[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 5/7] xen/ppc: Enable bootfdt and boot allocator
Hi Shawn, On 20/12/2023 13:23, Julien Grall wrote: Hi, On 15/12/2023 02:44, Shawn Anastasio wrote:Move PPC off the asm-generic setup.h and enable usage of bootfdt for populating the boot info struct from the firmware-provided device tree. Also enable the Xen boot page allocator. Includes minor changes to bootfdt.c's boot_fdt_info() to tolerate the scenario in which the FDT overlaps a reserved memory region, as is the case on PPC when booted directly from skiboot. Also includes a minor change to record Xen's correct position on PPC where Xen relocates itself to at the entrypoint. Signed-off-by: Shawn Anastasio <sanastasio@xxxxxxxxxxxxxxxxxxxxx> --- xen/arch/ppc/include/asm/Makefile | 1 - xen/arch/ppc/include/asm/setup.h | 123 +++++++++++++ xen/arch/ppc/setup.c | 289 +++++++++++++++++++++++++++++-I might be missing something. But isn't most of the code you add is the same as Arm? And if so, shouldn't this be consolidated? So I have create a new file and move the PPC functions I think should be the same. Then I replace with the Arm code. Below the diff. Looking through it, I can't see why the code cannot be shared in except part of populate_boot_allocator() (which could be split). I forsee that some of the code you remove will be necessary (e.g. BOOTMOD_RAMDISK, BOOTMOD_XSM). And some of the style change doesn't match what we do in Xen (messages are not split). If there are common bits with other architectures, then I would really like if they are shared rather than duplicated. I am more than happy to help finding a good split because it will reduce maintenance effort for everyone in the longer run. Cheers, diff --git a/xen/common/device-tree/setup.c b/xen/common/device-tree/setup.c index 3f79b97e9036..9c376527d11b 100644 --- a/xen/common/device-tree/setup.c +++ b/xen/common/device-tree/setup.c@@ -70,6 +70,10 @@ const char * __init boot_module_kind_as_string(bootmodule_kind kind) case BOOTMOD_XEN: return "Xen"; case BOOTMOD_FDT: return "Device Tree"; case BOOTMOD_KERNEL: return "Kernel"; + case BOOTMOD_RAMDISK: return "Ramdisk"; + case BOOTMOD_XSM: return "XSM"; + case BOOTMOD_GUEST_DTB: return "DTB"; + case BOOTMOD_UNKNOWN: return "Unknown"; default: BUG(); } }@@ -95,9 +99,8 @@ static bool __init bootmodules_overlap_check(struct bootmodules *bootmodules, continue; else { - printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with"- " mod[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n", region_start, - region_end, i, mod_start, mod_end);+ printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with mod[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n", + region_start, region_end, i, mod_start, mod_end); return true; } }@@ -126,9 +129,8 @@ static bool __init meminfo_overlap_check(struct meminfo *meminfo, continue; else { - printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with"- " bank[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n", region_start, - region_end, i, bank_start, bank_end);+ printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with bank[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n", + region_start, region_end, i, bank_start, bank_end); return true; } }@@ -155,6 +157,12 @@ bool __init check_reserved_regions_overlap(paddr_t region_start, region_start, region_size) ) return true; +#ifdef CONFIG_ACPI+ /* Check if input region is overlapping with ACPI EfiACPIReclaimMemory */ + if ( meminfo_overlap_check(&bootinfo.acpi, region_start, region_size) ) + return true; +#endif + return false; }@@ -196,12 +204,47 @@ static void __init dt_unreserved_regions(paddr_t s, paddr_t e, void (*cb)(paddr_t ps, paddr_t pe), unsigned int first) { - unsigned int i; + unsigned int i, nr; + int rc; + + rc = fdt_num_mem_rsv(device_tree_flattened); + if ( rc < 0 )+ panic("Unable to retrieve the number of reserved regions (rc=%d)\n", + rc); - for ( i = 0 ; i < bootinfo.reserved_mem.nr_banks; i++ ) + nr = rc; + + for ( i = first; i < nr ; i++ ) { - paddr_t r_s = bootinfo.reserved_mem.bank[i].start; - paddr_t r_e = r_s + bootinfo.reserved_mem.bank[i].size; + paddr_t r_s, r_e; ++ if ( fdt_get_mem_rsv_paddr(device_tree_flattened, i, &r_s, &r_e ) < 0 ) + /* If we can't read it, pretend it doesn't exist... */ + continue; + + r_e += r_s; /* fdt_get_mem_rsv_paddr returns length */ + + if ( s < r_e && r_s < e ) + { + dt_unreserved_regions(r_e, e, cb, i+1); + dt_unreserved_regions(s, r_s, cb, i+1); + return; + } + } + + /* + * i is the current bootmodule we are evaluating across all possible + * kinds. + * + * When retrieving the corresponding reserved-memory addresses + * below, we need to index the bootinfo.reserved_mem bank starting + * from 0, and only counting the reserved-memory modules. Hence, + * we need to use i - nr. + */ + for ( ; i - nr < bootinfo.reserved_mem.nr_banks; i++ ) + { + paddr_t r_s = bootinfo.reserved_mem.bank[i - nr].start; + paddr_t r_e = r_s + bootinfo.reserved_mem.bank[i - nr].size; if ( s < r_e && r_s < e ) {@@ -214,6 +257,16 @@ static void __init dt_unreserved_regions(paddr_t s, paddr_t e, cb(s, e); } +void __init fw_unreserved_regions(paddr_t s, paddr_t e, + void (*cb)(paddr_t ps, paddr_t pe), + unsigned int first) +{ + if ( acpi_disabled ) + dt_unreserved_regions(s, e, cb, first); + else + cb(s, e); +} + /* * boot_cmdline_find_by_kind can only be used to return Xen modules (e.g * XSM, DTB) or Dom0 modules. This is not suitable for looking up guest@@ -235,18 +288,47 @@ struct bootcmdline * __init boot_cmdline_find_by_kind(bootmodule_kind kind) } /* - * Populate the boot allocator. Based on arch/arm/setup.c's - * populate_boot_allocator. - * All RAM but the following regions will be added to the boot allocator: + * Populate the boot allocator. + * If a static heap was not provided by the admin, all the RAM but the + * following regions will be added: * - Modules (e.g., Xen, Kernel) * - Reserved regions + * - Xenheap (arm32 only) + * If a static heap was provided by the admin, populate the boot + * allocator with the corresponding regions only, but with Xenheap excluded + * on arm32. */ -static void __init populate_boot_allocator(void) +void __init populate_boot_allocator(void) { unsigned int i; const struct meminfo *banks = &bootinfo.mem; paddr_t s, e; + if ( bootinfo.static_heap ) + { + for ( i = 0 ; i < bootinfo.reserved_mem.nr_banks; i++ ) + {+ if ( bootinfo.reserved_mem.bank[i].type != MEMBANK_STATIC_HEAP ) + continue; + + s = bootinfo.reserved_mem.bank[i].start; + e = s + bootinfo.reserved_mem.bank[i].size; +#ifdef CONFIG_ARM_32+ /* Avoid the xenheap, note that the xenheap cannot across a bank */ + if ( s <= mfn_to_maddr(directmap_mfn_start) && + e >= mfn_to_maddr(directmap_mfn_end) ) + { + init_boot_pages(s, mfn_to_maddr(directmap_mfn_start)); + init_boot_pages(mfn_to_maddr(directmap_mfn_end), e); + } + else +#endif + init_boot_pages(s, e); + } + + return; + } + for ( i = 0; i < banks->nr_banks; i++ ) { const struct membank *bank = &banks->bank[i]; @@ -269,11 +351,18 @@ static void __init populate_boot_allocator(void) if ( e > bank_end ) e = bank_end; - dt_unreserved_regions(s, e, init_boot_pages, 0); - +#ifdef CONFIG_ARM_32 + /* Avoid the xenheap */ + if ( s < mfn_to_maddr(directmap_mfn_end) && + mfn_to_maddr(directmap_mfn_start) < e ) + { + e = mfn_to_maddr(directmap_mfn_start); + n = mfn_to_maddr(directmap_mfn_end); + } +#endif + + fw_unreserved_regions(s, e, init_boot_pages, 0); s = n; } } } - - I would also expect RISC-V to need the same. Cheers, -- Julien Grall
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |