[PATCH] drivers: xen: unmap Enlighten page before jumping to Linux
Dmytro Firsov
Dmytro_Firsov at epam.com
Tue Jul 19 12:45:04 CEST 2022
On 19.07.22 12:50, Julien Grall wrote:
> Hi Dmytro,
>
> On 19/07/2022 09:52, Dmytro Firsov wrote:
>> This commit fixes issue with usage of Xen hypervisor shared info page.
>> Previously U-boot did not unmap it at the end of OS boot process. It
>> leads to repeated mapping during Enlighten initialization in Linux.
>> Xen did not prevent guest from this, so it works but causes weird
>> wierd issues - one memory page, that was returned by memalign in U-boot
>> for Enlighten mapping was not returned to allocator and contained
>> shared info values during Linux run.
>
> I can't quite parse this. Do you mean the page will be marked as
> reserved for Linux and therefore it will never reach Linux's page
> allocator?
>
No, U-boot memory allocator uses real RAM pages and one of them will be
used for shared_info. Previously U-boot did not unmap it when jumped to
Linux. So, during Linux run, one of the pages that is marked as RAM in
device-tree will contain shared_info values. I don't know how it worked
previously, but it definitely will cause weird issue when Linux will try
to use it as regular RAM page.
>> Also Linux mapped it to another
>> place in memory again. >
>> Now code, that restricts repeated mapping of Enlighten page, is about
>> to be merged to Xen:
>> https://urldefense.com/v3/__https://lore.kernel.org/xen-devel/20220716145658.4175730-2-olekstysh@gmail.com/__;!!GF_29dbcQIUBPA!2OWttkgakR7s6GUn6e60EweRQ44H-TyI-8wWzhX0vWzR33BJE_z-x_AZ0S5VBBnXwwQ73-eIQ-sNcGLf$
>> [lore[.]kernel[.]org]
>>
>> So, without unmapping in U-boot, Linux will fail to start.
>
> Hmmm... From a discussion with Oleksandr, I was under the impression
> that this patch would also be necessary without the Xen patch merged.
> This was in order to prevent a corruption of the shared page [1].
>
Yes, definitely, but with new patches this problem becomes critical and
it will block Linux boot. General problem is explained in previous
section. This patch is needed to U-boot even without new patches to Xen,
but problem became visible only after them.
>> As discussed
>> on the xen-devel mailing list, to fix this issue the code should:
>> 1) Unmap the page
>> 2) Populate the area with memory using XENMEM_populate_physmap
>>
>> This patch adds page unmapping via XENMEM_remove_from_physmap, fills
>> hole in address space where page was mapped via XENMEM_populate_physmap
>> and return this address to memory allocator for freeing.
>
> Is U-boot mapping other shared page from Xen (e.g. grant-table...)?
Yes, but only shared_info is mapped with XENMEM_add_to_physmap, so other
drivers are not affected.
>
>>
>> Signed-off-by: Dmytro Firsov <dmytro_firsov at epam.com>
>> ---
>> drivers/xen/hypervisor.c | 31 +++++++++++++++++++++++++++++++
>> 1 file changed, 31 insertions(+)
>>
>> diff --git a/drivers/xen/hypervisor.c b/drivers/xen/hypervisor.c
>> index 2560894832..9ac377b618 100644
>> --- a/drivers/xen/hypervisor.c
>> +++ b/drivers/xen/hypervisor.c
>> @@ -144,6 +144,36 @@ struct shared_info *map_shared_info(void *p)
>> return HYPERVISOR_shared_info;
>> }
>> +void unmap_shared_info(void)
>> +{
>> + xen_pfn_t shared_info_pfn = virt_to_pfn(HYPERVISOR_shared_info);
>
> Somewhat unrelated to this patch. Can U-boot be compiled with 16K/64K
> page granularity?
I am using it on Armv8 and U-boot have hardcoded PAGE_SHIFT==12, and
PAGE_SIZE==(1<<PAGE_SHIFT)==4K
So, 16K/64K is not possible in current implementation for Armv8.
>
>> + struct xen_remove_from_physmap xrfp;
>> + struct xen_memory_reservation reservation;
>
> AFAICT, there some paddings in the two structure. So I would suggest
> to zero the structure (including paddings).
I did not see any padding in these structs definition in U-boot, so all
fields are initialized. But I can add zeroing with memset in next
version to be sure in this if structures will change.
>
>> + xen_ulong_t nr_exts = 1;
>> +
>> + xrfp.domid = DOMID_SELF;
>> + xrfp.gpfn = shared_info_pfn;
>> + if (HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrfp) != 0)
>> + BUG();
>
> If I am not mistaken, U-boot provide a panic() helper. So I would
> suggest to use it as this would be useful to print with the error
> returned.
Agree, will be fixed in next version.
>
>> +
>> + /*
>> + * After remove from physmap there will be a hole in address
>> space on
>
> Typo: s/remove/removing/
Agree, will be fixed in next version.
>
>> + * HYPERVISOR_shared_info address, so to free memory allocated with
>> + * memalign and prevent exceptions during access to this page we
>> need to
>> + * fill this 4KB hole with XENMEM_populate_physmap before
>> jumping to Linux.
>> + */
>> + reservation.domid = DOMID_SELF;
>> + reservation.extent_order = 0;
>> + reservation.address_bits = 0;
>> + set_xen_guest_handle(reservation.extent_start, &shared_info_pfn);
>> + reservation.nr_extents = nr_exts;
>> + if (HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation)
>> != nr_exts)
>> + BUG();
>
> Same here regarding using panic() rather than BUG()
Agree, will be fixed in next version.
>
>> +
>> + /* Now we can return this to memory allocator */
>> + free(HYPERVISOR_shared_info);
>> +}
>> +
>> void do_hypervisor_callback(struct pt_regs *regs)
>> {
>> unsigned long l1, l2, l1i, l2i;
>> @@ -251,4 +281,5 @@ void xen_fini(void)
>> fini_gnttab();
>> fini_xenbus();
>> fini_events();
>> + unmap_shared_info();
>> }
>
> [1]
> https://urldefense.com/v3/__https://github.com/xen-troops/u-boot/commit/f759b151116af204a5ab02ace82c09300cd6233a*__;Iw!!GF_29dbcQIUBPA!2OWttkgakR7s6GUn6e60EweRQ44H-TyI-8wWzhX0vWzR33BJE_z-x_AZ0S5VBBnXwwQ73-eIQ_0Hh8nA$
> [github[.]com]
>
More information about the U-Boot
mailing list