[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging] xen/arm: bootfdt: Always sort memory banks

commit 4473f3601098a2c3cf5ab89d5a29504772985e3a
Author:     Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>
AuthorDate: Mon Jul 5 20:48:51 2021 +0300
Commit:     Julien Grall <jgrall@xxxxxxxxxx>
CommitDate: Tue Jul 6 09:55:53 2021 +0100

    xen/arm: bootfdt: Always sort memory banks
    At the moment, Xen on Arm64 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 requirement regarding ordering in the device
    tree, update code to be able to deal with by sorting memory
    banks. There is only one heap region on Arm32, so the sorting
    is fine to be done in the common code.
    Suggested-by: Julien Grall <jgrall@xxxxxxxxxx>
    Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
    Acked-by: Julien Grall <jgrall@xxxxxxxxxx>
 xen/arch/arm/bootfdt.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index dcff512648..476e32e0f5 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)
+/* 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,15 @@ 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);
+    /*
+     * On Arm64 setup_xenheap_mappings() 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);
     return fdt_totalsize(fdt);
generated by git-patchbot for /home/xen/git/xen.git#staging



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.