[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN][POWERPC] memory clean up (phase 3)
# HG changeset patch # User Hollis Blanchard <hollisb@xxxxxxxxxx> # Node ID 9b3b420ec064ba6933998f82f0e07e0c816bef35 # Parent af7c87d42bc6d85441a7ff0a03f8bbbc67195f8e [XEN][POWERPC] memory clean up (phase 3) The following changes are included: Open Firmware: - use all args for of_claim() - handle broken claim methods as best we can - describe where the Dom0 image is comming from - stop copying the Dom0 image Heaps: - make sure we do not overwrite the oftree - release as much memory as possible to xenheap - release Dom0 image after we are done with it - Lots of checks and simplifications Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> --- xen/arch/powerpc/boot_of.c | 127 +++++++++++++++++++++++---------------------- xen/arch/powerpc/setup.c | 105 ++++++++++++++++++++++++------------- 2 files changed, 135 insertions(+), 97 deletions(-) diff -r af7c87d42bc6 -r 9b3b420ec064 xen/arch/powerpc/boot_of.c --- a/xen/arch/powerpc/boot_of.c Thu Aug 17 07:10:57 2006 -0400 +++ b/xen/arch/powerpc/boot_of.c Tue Aug 29 13:20:31 2006 -0500 @@ -26,6 +26,7 @@ #include <xen/spinlock.h> #include <xen/serial.h> #include <xen/time.h> +#include <xen/sched.h> #include <asm/page.h> #include <asm/io.h> #include "exceptions.h" @@ -322,17 +323,18 @@ static void __init of_test(const char *o } } -static int __init of_claim(void * virt, u32 size) +static int __init of_claim(u32 virt, u32 size, u32 align) { int rets[1] = { OF_FAILURE }; - of_call("claim", 3, 1, rets, virt, size, 0/*align*/); + of_call("claim", 3, 1, rets, virt, size, align); if (rets[0] == OF_FAILURE) { - DBG("%s 0x%p 0x%08x -> FAIL\n", __func__, virt, size); - return OF_FAILURE; - } - - DBG("%s 0x%p 0x%08x -> 0x%x\n", __func__, virt, size, rets[0]); + DBG("%s 0x%08x 0x%08x 0x%08x -> FAIL\n", __func__, virt, size, align); + return OF_FAILURE; + } + + DBG("%s 0x%08x 0x%08x 0x%08x -> 0x%08x\n", __func__, virt, size, align, + rets[0]); return rets[0]; } @@ -683,32 +685,47 @@ static int boot_of_fixup_chosen(void *me } static ulong space_base; -static ulong find_space(u32 size, ulong align, multiboot_info_t *mbi) +static int broken_claim; + +/* + * The following function is necessary because we cannot depend on all + * FW to actually allocate us any space, so we look for it _hoping_ + * that at least is will fail if we try to claim something that + * belongs to FW. This hope does not seem to be true on some version + * of PIBS. + */ +static ulong find_space(u32 size, u32 align, multiboot_info_t *mbi) { memory_map_t *map = (memory_map_t *)((ulong)mbi->mmap_addr); ulong eomem = ((u64)map->length_high << 32) | (u64)map->length_low; ulong base; - of_printf("%s base=0x%016lx eomem=0x%016lx size=0x%08x align=0x%lx\n", + if (size == 0) return base; + + if (align == 0) + of_panic("cannot call %s() with align of 0\n", __func__); + + if (!broken_claim) { + /* just try and claim it to the FW chosen address */ + base = of_claim(0, size, align); + if (base != OF_FAILURE) + return base; + of_printf("%s: Firmware does not allocate memory for you\n", __func__); + broken_claim = 1; + } + + of_printf("%s base=0x%016lx eomem=0x%016lx size=0x%08x align=0x%x\n", __func__, space_base, eomem, size, align); base = ALIGN_UP(space_base, PAGE_SIZE); - if ((base + size) >= 0x4000000) return 0; - if (base + size > eomem) of_panic("not enough RAM\n"); - - if (size == 0) return base; - if (of_claim((void*)base, size) != OF_FAILURE) { - space_base = base + size; - return base; - } else { - for(base += 0x100000; (base+size) < 0x4000000; base += 0x100000) { - of_printf("Trying 0x%016lx\n", base); - if (of_claim((void*)base, size) != OF_FAILURE) { - space_base = base + size; - return base; - } - } - return 0; - } + + while ((base + size) < rma_size(cpu_rma_order())) { + if (of_claim(base, size, 0) != OF_FAILURE) { + space_base = base + size; + return base; + } + base += (PAGE_SIZE > align) ? PAGE_SIZE : align; + } + of_panic("Cannot find memory in the RMA\n"); } /* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges @@ -834,9 +851,8 @@ static void boot_of_module(ulong r3, ulo static module_t mods[3]; void *oftree; ulong oftree_sz = 48 * PAGE_SIZE; - char *mod0_start; + ulong mod0_start; ulong mod0_size; - ulong mod0; static const char sepr[] = " -- "; extern char dom0_start[] __attribute__ ((weak)); extern char dom0_size[] __attribute__ ((weak)); @@ -844,59 +860,48 @@ static void boot_of_module(ulong r3, ulo if ((r3 > 0) && (r4 > 0)) { /* was it handed to us in registers ? */ - mod0_start = (void *)r3; + mod0_start = r3; mod0_size = r4; + of_printf("%s: Dom0 was loaded and found using r3/r4:" + "0x%lx[size 0x%lx]\n", + __func__, mod0_start, mod0_size); } else { /* see if it is in the boot params */ p = strstr((char *)((ulong)mbi->cmdline), "dom0_start="); if ( p != NULL) { p += 11; - mod0_start = (char *)simple_strtoul(p, NULL, 0); + mod0_start = simple_strtoul(p, NULL, 0); p = strstr((char *)((ulong)mbi->cmdline), "dom0_size="); p += 10; mod0_size = simple_strtoul(p, NULL, 0); - - of_printf("mod0: %o %c %c %c\n", - mod0_start[0], - mod0_start[1], - mod0_start[2], - mod0_start[3]); - + of_printf("%s: Dom0 was loaded and found using cmdline:" + "0x%lx[size 0x%lx]\n", + __func__, mod0_start, mod0_size); } else if ( ((ulong)dom0_start != 0) && ((ulong)dom0_size != 0) ) { /* was it linked in ? */ - mod0_start = dom0_start; + mod0_start = (ulong)dom0_start; mod0_size = (ulong)dom0_size; - of_printf("%s: linked in module copied after _end " - "(start 0x%p size 0x%lx)\n", + of_printf("%s: Dom0 is linked in: 0x%lx[size 0x%lx]\n", __func__, mod0_start, mod0_size); } else { - mod0_start = _end; + mod0_start = (ulong)_end; mod0_size = 0; - } + of_printf("%s: FYI Dom0 is unknown, will be caught later\n", + __func__); + } + } + + if (mod0_size > 0) { + const char *c = (const char *)mod0_start; + + of_printf("mod0: %o %c %c %c\n", c[0], c[1], c[2], c[3]); } space_base = (ulong)_end; - mod0 = find_space(mod0_size, PAGE_SIZE, mbi); - - /* three cases - * 1) mod0_size is not 0 and the image can be copied - * 2) mod0_size is not 0 and the image cannot be copied - * 3) mod0_size is 0 - */ - if (mod0_size > 0) { - if (mod0 != 0) { - memcpy((void *)mod0, mod0_start, mod0_size); - mods[0].mod_start = mod0; - mods[0].mod_end = mod0 + mod0_size; - } else { - of_panic("No space to copy mod0\n"); - } - } else { - mods[0].mod_start = mod0; - mods[0].mod_end = mod0; - } + mods[0].mod_start = mod0_start; + mods[0].mod_end = mod0_start + mod0_size; of_printf("%s: mod[0] @ 0x%016x[0x%x]\n", __func__, mods[0].mod_start, mods[0].mod_end); diff -r af7c87d42bc6 -r 9b3b420ec064 xen/arch/powerpc/setup.c --- a/xen/arch/powerpc/setup.c Thu Aug 17 07:10:57 2006 -0400 +++ b/xen/arch/powerpc/setup.c Tue Aug 29 13:20:31 2006 -0500 @@ -61,6 +61,7 @@ unsigned long wait_init_idle; unsigned long wait_init_idle; ulong oftree; ulong oftree_len; +ulong oftree_end; cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; cpumask_t cpu_online_map; /* missing ifdef in schedule.c */ @@ -193,17 +194,37 @@ void startup_cpu_idle_loop(void) reset_stack_and_jump(idle_loop); } +static ulong free_xenheap(ulong start, ulong end) +{ + start = ALIGN_UP(start, PAGE_SIZE); + end = ALIGN_DOWN(end, PAGE_SIZE); + + printk("%s: 0x%lx - 0x%lx\n", __func__, start, end); + + if (oftree <= end && oftree >= start) { + printk("%s: Go around the devtree: 0x%lx - 0x%lx\n", + __func__, oftree, oftree_end); + init_xenheap_pages(start, ALIGN_DOWN(oftree, PAGE_SIZE)); + init_xenheap_pages(ALIGN_UP(oftree_end, PAGE_SIZE), end); + } else { + init_xenheap_pages(start, end); + } + return ALIGN_UP(end, PAGE_SIZE); +} + static void __init __start_xen(multiboot_info_t *mbi) { char *cmdline; module_t *mod = (module_t *)((ulong)mbi->mods_addr); ulong heap_start; - ulong modules_start, modules_size; ulong eomem = 0; ulong heap_size = 0; ulong bytes = 0; - ulong freemem = (ulong)_end; - ulong oftree_end; + ulong freemem; + ulong dom0_start, dom0_len; + ulong initrd_start, initrd_len; + + int i; memcpy(0, exception_vectors, exception_vectors_end - exception_vectors); synchronize_caches(0, exception_vectors_end - exception_vectors); @@ -234,10 +255,6 @@ static void __init __start_xen(multiboot if (!(mbi->flags & MBI_MEMMAP)) { panic("FATAL ERROR: Bootloader provided no memory information.\n"); } - - /* mark the begining of images */ - modules_start = mod[0].mod_start; - modules_size = mod[mbi->mods_count-1].mod_end - mod[0].mod_start; /* OF dev tree is the last module */ oftree = mod[mbi->mods_count-1].mod_start; @@ -283,7 +300,15 @@ static void __init __start_xen(multiboot /* Architecturally the first 4 pages are exception hendlers, we * will also be copying down some code there */ - heap_start = init_boot_allocator(4 << PAGE_SHIFT); + heap_start = 4 << PAGE_SHIFT; + if (oftree < (ulong)_start) + heap_start = ALIGN_UP(oftree_end, PAGE_SIZE); + + heap_start = init_boot_allocator(heap_start); + if (heap_start > (ulong)_start) { + panic("space below _start (%p) is not enough memory " + "for heap (0x%lx)\n", _start, heap_start); + } /* we give the first RMA to the hypervisor */ xenheap_phys_end = rma_size(cpu_rma_order()); @@ -295,24 +320,28 @@ static void __init __start_xen(multiboot /* Add memory between the beginning of the heap and the beginning * of out text */ - init_xenheap_pages(heap_start, (ulong)_start); - - /* move the modules to just after _end */ - if (modules_start) { - printk("modules at: %016lx - %016lx\n", modules_start, - modules_start + modules_size); - freemem = ALIGN_UP(freemem, PAGE_SIZE); - memmove((void *)freemem, (void *)modules_start, modules_size); - - oftree -= modules_start - freemem; - modules_start = freemem; - freemem += modules_size; - printk(" moved to: %016lx - %016lx\n", modules_start, - modules_start + modules_size); + free_xenheap(heap_start, (ulong)_start); + freemem = ALIGN_UP((ulong)_end, PAGE_SIZE); + + for (i = 0; i < mbi->mods_count; i++) { + u32 s; + + s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE); + + if (mod[i].mod_start > (ulong)_start && + mod[i].mod_start < (ulong)_end) { + /* mod was linked in */ + continue; + } + + if (s < freemem) + panic("module addresses must assend\n"); + + freemem = free_xenheap(freemem, s); } /* the rest of the xenheap, starting at the end of modules */ - init_xenheap_pages(freemem, xenheap_phys_end); + free_xenheap(freemem, xenheap_phys_end); #ifdef OF_DEBUG @@ -353,22 +382,26 @@ static void __init __start_xen(multiboot /* Scrub RAM that is still free and so may go to an unprivileged domain. */ scrub_heap_pages(); - /* - * We're going to setup domain0 using the module(s) that we - * stashed safely above our heap. The second module, if present, - * is an initrd ramdisk. The last module is the OF devtree. - */ - if (construct_dom0(dom0, - modules_start, - mod[0].mod_end-mod[0].mod_start, - (mbi->mods_count == 1) ? 0 : - modules_start + - (mod[1].mod_start-mod[0].mod_start), - (mbi->mods_count == 1) ? 0 : - mod[mbi->mods_count-1].mod_end - mod[1].mod_start, + dom0_start = mod[0].mod_start; + dom0_len = mod[0].mod_end - mod[0].mod_start; + if (mbi->mods_count > 1) { + initrd_start = mod[1].mod_start; + initrd_len = mod[1].mod_end - mod[1].mod_start; + } else { + initrd_start = 0; + initrd_len = 0; + } + if (construct_dom0(dom0, dom0_start, dom0_len, + initrd_start, initrd_len, cmdline) != 0) { panic("Could not set up DOM0 guest OS\n"); } + + free_xenheap(ALIGN_UP(dom0_start, PAGE_SIZE), + ALIGN_DOWN(dom0_start + dom0_len, PAGE_SIZE)); + if (initrd_start) + free_xenheap(ALIGN_UP(initrd_start, PAGE_SIZE), + ALIGN_DOWN(initrd_start + initrd_len, PAGE_SIZE)); init_trace_bufs(); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |