[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Improve boot loader data moving logic in start_kernel()
# HG changeset patch # User Alex Williamson <alex.williamson@xxxxxx> # Date 1200596743 25200 # Node ID 4fbde3a39909aae668a6a785ae6a0bafeb26786b # Parent bba0419a05f165099e74b7705bc44f345cfb0cea [IA64] Improve boot loader data moving logic in start_kernel() Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> --- xen/arch/ia64/xen/xensetup.c | 80 +++++++++++++++++++++++++------------------ 1 files changed, 47 insertions(+), 33 deletions(-) diff -r bba0419a05f1 -r 4fbde3a39909 xen/arch/ia64/xen/xensetup.c --- a/xen/arch/ia64/xen/xensetup.c Thu Jan 17 12:05:43 2008 -0700 +++ b/xen/arch/ia64/xen/xensetup.c Thu Jan 17 12:05:43 2008 -0700 @@ -77,7 +77,7 @@ void *xen_pickle_offset __read_mostly; static void __init parse_xenheap_megabytes(char *s) { - unsigned long megabytes = parse_size_and_unit(s, NULL); + unsigned long megabytes = simple_strtoll(s, NULL, 0); #define XENHEAP_MEGABYTES_MIN 16 if (megabytes < XENHEAP_MEGABYTES_MIN) @@ -241,12 +241,21 @@ is_xenheap_usable_memory(efi_memory_desc } static inline int __init -md_overlaps(efi_memory_desc_t *md, unsigned long phys_addr) +md_overlaps(const efi_memory_desc_t *md, unsigned long phys_addr) { return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)); } +static inline int __init +md_overlap_with_boot_param(const efi_memory_desc_t *md) +{ + return md_overlaps(md, __pa(ia64_boot_param)) || + md_overlaps(md, ia64_boot_param->efi_memmap) || + md_overlaps(md, ia64_boot_param->command_line); +} + #define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT) +#define MD_END(md) ((md)->phys_addr + ((md)->num_pages << EFI_PAGE_SHIFT)) extern char __init_begin[], __init_end[]; static void noinline init_done(void) @@ -366,27 +375,34 @@ void __init start_kernel(void) while (relo_start + relo_size >= md_end) { md = efi_get_md(md_end); - BUG_ON(!md); - BUG_ON(!is_xenheap_usable_memory(md)); - - md_end = md->phys_addr + MD_SIZE(md); + if (md == NULL) { + printk("no room to move loader data. skip moving loader data\n"); + goto skip_move; + } + + md_end = MD_END(md); + if (relo_start < md->phys_addr) + relo_start = md->phys_addr; + + if (!is_xenheap_usable_memory(md)) + continue; + /* * The dom0 kernel or initrd could overlap, reserve space * at the end to relocate them later. */ if (md->type == EFI_LOADER_DATA) { /* Test for ranges we're not prepared to move */ - BUG_ON(md_overlaps(md, __pa(ia64_boot_param)) || - md_overlaps(md, ia64_boot_param->efi_memmap) || - md_overlaps(md, ia64_boot_param->command_line)); - - relo_size += MD_SIZE(md); + if (!md_overlap_with_boot_param(md)) + relo_size += MD_SIZE(md); + /* If range overlaps the end, push out the relocation start */ if (md_end > relo_start) relo_start = md_end; } } last_md = md; + relo_start = md_end - relo_size; relo_end = relo_start + relo_size; md_end = __pa(ia64_imva(&_end)); @@ -397,9 +413,9 @@ void __init start_kernel(void) * and set to zero pages. */ for (md = efi_get_md(md_end) ;; md = efi_get_md(md_end)) { - md_end = md->phys_addr + MD_SIZE(md); - - if (md->type == EFI_LOADER_DATA) { + md_end = MD_END(md); + + if (md->type == EFI_LOADER_DATA && !md_overlap_with_boot_param(md)) { unsigned long relo_offset; if (md_overlaps(md, ia64_boot_param->domain_start)) { @@ -421,27 +437,14 @@ void __init start_kernel(void) relo_start += MD_SIZE(md); } - if (md == kern_md) - continue; if (md == last_md) break; - - md->phys_addr = relo_end; - md->num_pages = 0; } /* Trim the last entry */ - md->phys_addr = relo_end; - md->num_pages = (md_end - relo_end) >> EFI_PAGE_SHIFT; - - /* - * Expand the new kernel/xenheap (and maybe dom0/initrd) out to - * the full size. This range will already be type EFI_LOADER_DATA, - * therefore the xenheap area is now protected being allocated for - * use by find_memmap_space() in efi.c - */ - kern_md->num_pages = (relo_end - kern_md->phys_addr) >> EFI_PAGE_SHIFT; - + md->num_pages -= (relo_size >> EFI_PAGE_SHIFT); + +skip_move: reserve_memory(); /* first find highest page frame number */ @@ -485,10 +488,21 @@ void __init start_kernel(void) if (vmx_enabled) xen_heap_start = vmx_init_env(xen_heap_start, xenheap_phys_end); - init_xenheap_pages(__pa(xen_heap_start), xenheap_phys_end); + md_end = __pa(xen_heap_start); + for (md = efi_get_md(md_end); + md != NULL && md->phys_addr < xenheap_phys_end; + md = efi_get_md(md_end)) { + md_end = MD_END(md); + + if (md == kern_md || + (md->type == EFI_LOADER_DATA && !md_overlap_with_boot_param(md)) || + (md->attribute & EFI_MEMORY_WB)) + init_xenheap_pages(max(__pa(xen_heap_start), md->phys_addr), + min(md_end, xenheap_phys_end)); + } printk("Xen heap: %luMB (%lukB)\n", - (xenheap_phys_end-__pa(xen_heap_start)) >> 20, - (xenheap_phys_end-__pa(xen_heap_start)) >> 10); + (xenheap_phys_end-__pa(xen_heap_start)) >> 20, + (xenheap_phys_end-__pa(xen_heap_start)) >> 10); end_boot_allocator(); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |