All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xen/arm: bootfdt: Always sort memory banks
@ 2021-06-14 19:34 Oleksandr Tyshchenko
  2021-06-30  0:49 ` Stefano Stabellini
  2021-06-30  8:56 ` Julien Grall
  0 siblings, 2 replies; 4+ messages in thread
From: Oleksandr Tyshchenko @ 2021-06-14 19:34 UTC (permalink / raw)
  To: xen-devel
  Cc: Oleksandr Tyshchenko, Stefano Stabellini, Julien Grall,
	Volodymyr Babchuk

From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>

At the moment, Xen expects the memory banks to be ordered.
Unfortunately, there may be a case when updated by firmware
device tree contains unordered banks. This means Xen will panic
when setting xenheap mappings for the subsequent bank with start
address being less than xenheap_mfn_start (start address of
the first bank).

As there is no clear requirment regarding ordering in the device
tree, update code to be able to deal with by sorting memory
banks if we have more than one.

Suggested-by: Julien Grall <jgrall@amazon.com>
Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
---

The proposed commit fixes the booting Xen on R-Car M3-W+ SoC:

Starting kernel ...
- UART enabled -
- Boot CPU booting -
- Current EL 00000008 -
- Initialize CPU -
- Turning on paging -
- Zero BSS -
- Ready -
(XEN) Checking for initrd in /chosen
(XEN) Initrd 0000000084000040-0000000085dbc32a
(XEN) RAM: 0000000480000000 - 00000004ffffffff
(XEN) RAM: 0000000048000000 - 00000000bfffffff
(XEN) RAM: 0000000600000000 - 00000006ffffffff

...

(XEN) ****************************************
(XEN) Panic on CPU 0:
(XEN) cannot add xenheap mapping at 48000 below heap start 480000
(XEN) ****************************************
(XEN) 
(XEN) Reboot in five seconds...
---
 xen/arch/arm/bootfdt.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index dcff512..3ef63b3 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -13,6 +13,7 @@
 #include <xen/init.h>
 #include <xen/device_tree.h>
 #include <xen/libfdt/libfdt.h>
+#include <xen/sort.h>
 #include <xsm/xsm.h>
 #include <asm/setup.h>
 
@@ -395,6 +396,21 @@ static void __init early_print_info(void)
     printk("\n");
 }
 
+/* This function assumes that memory regions are not overlapped */
+static int __init cmp_memory_node(const void *key, const void *elem)
+{
+    const struct membank *handler0 = key;
+    const struct membank *handler1 = elem;
+
+    if ( handler0->start < handler1->start )
+        return -1;
+
+    if ( handler0->start >= (handler1->start + handler1->size) )
+        return 1;
+
+    return 0;
+}
+
 /**
  * boot_fdt_info - initialize bootinfo from a DTB
  * @fdt: flattened device tree binary
@@ -412,6 +428,12 @@ size_t __init boot_fdt_info(const void *fdt, paddr_t paddr)
     add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), false);
 
     device_tree_for_each_node((void *)fdt, 0, early_scan_node, NULL);
+    if ( bootinfo.mem.nr_banks > 1 )
+    {
+        /* Some DT may describe unordered banks, sort them in ascending order */
+        sort(bootinfo.mem.bank, bootinfo.mem.nr_banks, sizeof(struct membank),
+             cmp_memory_node, NULL);
+    }
     early_print_info();
 
     return fdt_totalsize(fdt);
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] xen/arm: bootfdt: Always sort memory banks
  2021-06-14 19:34 [PATCH] xen/arm: bootfdt: Always sort memory banks Oleksandr Tyshchenko
@ 2021-06-30  0:49 ` Stefano Stabellini
  2021-06-30  8:56 ` Julien Grall
  1 sibling, 0 replies; 4+ messages in thread
From: Stefano Stabellini @ 2021-06-30  0:49 UTC (permalink / raw)
  To: Oleksandr Tyshchenko
  Cc: xen-devel, Oleksandr Tyshchenko, Stefano Stabellini,
	Julien Grall, Volodymyr Babchuk

On Mon, 14 Jun 2021, Oleksandr Tyshchenko wrote:
> From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
> 
> At the moment, Xen expects the memory banks to be ordered.
> Unfortunately, there may be a case when updated by firmware
> device tree contains unordered banks. This means Xen will panic
> when setting xenheap mappings for the subsequent bank with start
> address being less than xenheap_mfn_start (start address of
> the first bank).
> 
> As there is no clear requirment regarding ordering in the device
> tree, update code to be able to deal with by sorting memory
> banks if we have more than one.
> 
> Suggested-by: Julien Grall <jgrall@amazon.com>
> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>


> ---
> 
> The proposed commit fixes the booting Xen on R-Car M3-W+ SoC:
> 
> Starting kernel ...
> - UART enabled -
> - Boot CPU booting -
> - Current EL 00000008 -
> - Initialize CPU -
> - Turning on paging -
> - Zero BSS -
> - Ready -
> (XEN) Checking for initrd in /chosen
> (XEN) Initrd 0000000084000040-0000000085dbc32a
> (XEN) RAM: 0000000480000000 - 00000004ffffffff
> (XEN) RAM: 0000000048000000 - 00000000bfffffff
> (XEN) RAM: 0000000600000000 - 00000006ffffffff
> 
> ...
> 
> (XEN) ****************************************
> (XEN) Panic on CPU 0:
> (XEN) cannot add xenheap mapping at 48000 below heap start 480000
> (XEN) ****************************************
> (XEN) 
> (XEN) Reboot in five seconds...
> ---
>  xen/arch/arm/bootfdt.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
> index dcff512..3ef63b3 100644
> --- a/xen/arch/arm/bootfdt.c
> +++ b/xen/arch/arm/bootfdt.c
> @@ -13,6 +13,7 @@
>  #include <xen/init.h>
>  #include <xen/device_tree.h>
>  #include <xen/libfdt/libfdt.h>
> +#include <xen/sort.h>
>  #include <xsm/xsm.h>
>  #include <asm/setup.h>
>  
> @@ -395,6 +396,21 @@ static void __init early_print_info(void)
>      printk("\n");
>  }
>  
> +/* This function assumes that memory regions are not overlapped */
> +static int __init cmp_memory_node(const void *key, const void *elem)
> +{
> +    const struct membank *handler0 = key;
> +    const struct membank *handler1 = elem;
> +
> +    if ( handler0->start < handler1->start )
> +        return -1;
> +
> +    if ( handler0->start >= (handler1->start + handler1->size) )
> +        return 1;
> +
> +    return 0;
> +}
> +
>  /**
>   * boot_fdt_info - initialize bootinfo from a DTB
>   * @fdt: flattened device tree binary
> @@ -412,6 +428,12 @@ size_t __init boot_fdt_info(const void *fdt, paddr_t paddr)
>      add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), false);
>  
>      device_tree_for_each_node((void *)fdt, 0, early_scan_node, NULL);
> +    if ( bootinfo.mem.nr_banks > 1 )
> +    {
> +        /* Some DT may describe unordered banks, sort them in ascending order */
> +        sort(bootinfo.mem.bank, bootinfo.mem.nr_banks, sizeof(struct membank),
> +             cmp_memory_node, NULL);
> +    }
>      early_print_info();
>  
>      return fdt_totalsize(fdt);
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] xen/arm: bootfdt: Always sort memory banks
  2021-06-14 19:34 [PATCH] xen/arm: bootfdt: Always sort memory banks Oleksandr Tyshchenko
  2021-06-30  0:49 ` Stefano Stabellini
@ 2021-06-30  8:56 ` Julien Grall
  2021-07-05 17:26   ` Oleksandr
  1 sibling, 1 reply; 4+ messages in thread
From: Julien Grall @ 2021-06-30  8:56 UTC (permalink / raw)
  To: Oleksandr Tyshchenko, xen-devel
  Cc: Oleksandr Tyshchenko, Stefano Stabellini, Volodymyr Babchuk

Hi Oleksandr,

On 14/06/2021 20:34, Oleksandr Tyshchenko wrote:
> From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
> 
> At the moment, Xen expects the memory banks to be ordered.
> Unfortunately, there may be a case when updated by firmware
> device tree contains unordered banks. This means Xen will panic
> when setting xenheap mappings for the subsequent bank with start
> address being less than xenheap_mfn_start (start address of
> the first bank).

Please clarify in the commit message that the behavior you are 
describing is for arm64. For arm32, there is only one heap region.

That said, I think the sorting is fine to be done in common code.

> 
> As there is no clear requirment regarding ordering in the device

s/requirment/requirement/

> tree, update code to be able to deal with by sorting memory
> banks if we have more than one.
> 
> Suggested-by: Julien Grall <jgrall@amazon.com>
> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
> ---
> 
> The proposed commit fixes the booting Xen on R-Car M3-W+ SoC:
> 
> Starting kernel ...
> - UART enabled -
> - Boot CPU booting -
> - Current EL 00000008 -
> - Initialize CPU -
> - Turning on paging -
> - Zero BSS -
> - Ready -
> (XEN) Checking for initrd in /chosen
> (XEN) Initrd 0000000084000040-0000000085dbc32a
> (XEN) RAM: 0000000480000000 - 00000004ffffffff
> (XEN) RAM: 0000000048000000 - 00000000bfffffff
> (XEN) RAM: 0000000600000000 - 00000006ffffffff
> 
> ...
> 
> (XEN) ****************************************
> (XEN) Panic on CPU 0:
> (XEN) cannot add xenheap mapping at 48000 below heap start 480000
> (XEN) ****************************************
> (XEN)
> (XEN) Reboot in five seconds...
> ---
>   xen/arch/arm/bootfdt.c | 22 ++++++++++++++++++++++
>   1 file changed, 22 insertions(+)
> 
> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
> index dcff512..3ef63b3 100644
> --- a/xen/arch/arm/bootfdt.c
> +++ b/xen/arch/arm/bootfdt.c
> @@ -13,6 +13,7 @@
>   #include <xen/init.h>
>   #include <xen/device_tree.h>
>   #include <xen/libfdt/libfdt.h>
> +#include <xen/sort.h>
>   #include <xsm/xsm.h>
>   #include <asm/setup.h>
>   
> @@ -395,6 +396,21 @@ static void __init early_print_info(void)
>       printk("\n");
>   }
>   
> +/* This function assumes that memory regions are not overlapped */
> +static int __init cmp_memory_node(const void *key, const void *elem)
> +{
> +    const struct membank *handler0 = key;
> +    const struct membank *handler1 = elem;
> +
> +    if ( handler0->start < handler1->start )
> +        return -1;
> +
> +    if ( handler0->start >= (handler1->start + handler1->size) )
> +        return 1;
> +
> +    return 0;
> +}
> +
>   /**
>    * boot_fdt_info - initialize bootinfo from a DTB
>    * @fdt: flattened device tree binary
> @@ -412,6 +428,12 @@ size_t __init boot_fdt_info(const void *fdt, paddr_t paddr)
>       add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), false);
>   
>       device_tree_for_each_node((void *)fdt, 0, early_scan_node, NULL);
> +    if ( bootinfo.mem.nr_banks > 1 )

NIT: sort() is already be able to deal with one element array. So this 
checks looks a bit pointless.

> +    {
> +        /* Some DT may describe unordered banks, sort them in ascending order */

It would be good to explain in the comment *why* this is necessary. Some 
along the line:

On Arm64, setup_xenheap_pages() expects to be called with the lowest 
bank in memory first. There is no requirement that the DT will provide 
the banks sorted in ascending order. So sort them through.

> +        sort(bootinfo.mem.bank, bootinfo.mem.nr_banks, sizeof(struct membank),
> +             cmp_memory_node, NULL);
> +    }
>       early_print_info();
>   
>       return fdt_totalsize(fdt);
> 

Cheers,

-- 
Julien Grall


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] xen/arm: bootfdt: Always sort memory banks
  2021-06-30  8:56 ` Julien Grall
@ 2021-07-05 17:26   ` Oleksandr
  0 siblings, 0 replies; 4+ messages in thread
From: Oleksandr @ 2021-07-05 17:26 UTC (permalink / raw)
  To: Julien Grall, xen-devel
  Cc: Oleksandr Tyshchenko, Stefano Stabellini, Volodymyr Babchuk


On 30.06.21 11:56, Julien Grall wrote:
> Hi Oleksandr,

Hi Julien


Sorry for the late response.


>
> On 14/06/2021 20:34, Oleksandr Tyshchenko wrote:
>> From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
>>
>> At the moment, Xen expects the memory banks to be ordered.
>> Unfortunately, there may be a case when updated by firmware
>> device tree contains unordered banks. This means Xen will panic
>> when setting xenheap mappings for the subsequent bank with start
>> address being less than xenheap_mfn_start (start address of
>> the first bank).
>
> Please clarify in the commit message that the behavior you are 
> describing is for arm64. For arm32, there is only one heap region.
>
> That said, I think the sorting is fine to be done in common code.

ok


>
>
>>
>> As there is no clear requirment regarding ordering in the device
>
> s/requirment/requirement/

ok


>
>> tree, update code to be able to deal with by sorting memory
>> banks if we have more than one.
>>
>> Suggested-by: Julien Grall <jgrall@amazon.com>
>> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
>> ---
>>
>> The proposed commit fixes the booting Xen on R-Car M3-W+ SoC:
>>
>> Starting kernel ...
>> - UART enabled -
>> - Boot CPU booting -
>> - Current EL 00000008 -
>> - Initialize CPU -
>> - Turning on paging -
>> - Zero BSS -
>> - Ready -
>> (XEN) Checking for initrd in /chosen
>> (XEN) Initrd 0000000084000040-0000000085dbc32a
>> (XEN) RAM: 0000000480000000 - 00000004ffffffff
>> (XEN) RAM: 0000000048000000 - 00000000bfffffff
>> (XEN) RAM: 0000000600000000 - 00000006ffffffff
>>
>> ...
>>
>> (XEN) ****************************************
>> (XEN) Panic on CPU 0:
>> (XEN) cannot add xenheap mapping at 48000 below heap start 480000
>> (XEN) ****************************************
>> (XEN)
>> (XEN) Reboot in five seconds...
>> ---
>>   xen/arch/arm/bootfdt.c | 22 ++++++++++++++++++++++
>>   1 file changed, 22 insertions(+)
>>
>> diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
>> index dcff512..3ef63b3 100644
>> --- a/xen/arch/arm/bootfdt.c
>> +++ b/xen/arch/arm/bootfdt.c
>> @@ -13,6 +13,7 @@
>>   #include <xen/init.h>
>>   #include <xen/device_tree.h>
>>   #include <xen/libfdt/libfdt.h>
>> +#include <xen/sort.h>
>>   #include <xsm/xsm.h>
>>   #include <asm/setup.h>
>>   @@ -395,6 +396,21 @@ static void __init early_print_info(void)
>>       printk("\n");
>>   }
>>   +/* This function assumes that memory regions are not overlapped */
>> +static int __init cmp_memory_node(const void *key, const void *elem)
>> +{
>> +    const struct membank *handler0 = key;
>> +    const struct membank *handler1 = elem;
>> +
>> +    if ( handler0->start < handler1->start )
>> +        return -1;
>> +
>> +    if ( handler0->start >= (handler1->start + handler1->size) )
>> +        return 1;
>> +
>> +    return 0;
>> +}
>> +
>>   /**
>>    * boot_fdt_info - initialize bootinfo from a DTB
>>    * @fdt: flattened device tree binary
>> @@ -412,6 +428,12 @@ size_t __init boot_fdt_info(const void *fdt, 
>> paddr_t paddr)
>>       add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), false);
>>         device_tree_for_each_node((void *)fdt, 0, early_scan_node, 
>> NULL);
>> +    if ( bootinfo.mem.nr_banks > 1 )
>
> NIT: sort() is already be able to deal with one element array. So this 
> checks looks a bit pointless.

Agree, will drop.


>
>
>> +    {
>> +        /* Some DT may describe unordered banks, sort them in 
>> ascending order */
>
> It would be good to explain in the comment *why* this is necessary. 
> Some along the line:
>
> On Arm64, setup_xenheap_pages() expects to be called with the lowest 
> bank in memory first. There is no requirement that the DT will provide 
> the banks sorted in ascending order. So sort them through.

ok


>
>
>> +        sort(bootinfo.mem.bank, bootinfo.mem.nr_banks, sizeof(struct 
>> membank),
>> +             cmp_memory_node, NULL);
>> +    }
>>       early_print_info();
>>         return fdt_totalsize(fdt);
>>
>
> Cheers,
>
-- 
Regards,

Oleksandr Tyshchenko



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-07-05 17:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-14 19:34 [PATCH] xen/arm: bootfdt: Always sort memory banks Oleksandr Tyshchenko
2021-06-30  0:49 ` Stefano Stabellini
2021-06-30  8:56 ` Julien Grall
2021-07-05 17:26   ` Oleksandr

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.