X-Git-Url: http://git.cascardo.info/?p=cascardo%2Flinux.git;a=blobdiff_plain;f=arch%2Fx86%2Fxen%2Fsetup.c;h=973d29441f965025be794e0f0650940be7422b58;hp=99ef82cc4edc3bd8c6e2b2674b0ce1c565998398;hb=9ddac5b724a9465e27f25a0aa943e92c8341a85b;hpb=e612b4a7db4ae1dd8c2bbe171e10c21723de95b2 diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 99ef82cc4edc..973d29441f96 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -596,6 +596,40 @@ bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size) return true; } +/* + * Find a free area in physical memory not yet reserved and compliant with + * E820 map. + * Used to relocate pre-allocated areas like initrd or p2m list which are in + * conflict with the to be used E820 map. + * In case no area is found, return 0. Otherwise return the physical address + * of the area which is already reserved for convenience. + */ +phys_addr_t __init xen_find_free_area(phys_addr_t size) +{ + unsigned mapcnt; + phys_addr_t addr, start; + struct e820entry *entry = xen_e820_map; + + for (mapcnt = 0; mapcnt < xen_e820_map_entries; mapcnt++, entry++) { + if (entry->type != E820_RAM || entry->size < size) + continue; + start = entry->addr; + for (addr = start; addr < start + size; addr += PAGE_SIZE) { + if (!memblock_is_reserved(addr)) + continue; + start = addr + PAGE_SIZE; + if (start + size > entry->addr + entry->size) + break; + } + if (addr >= start + size) { + memblock_reserve(start, size); + return start; + } + } + + return 0; +} + /* * Reserve Xen mfn_list. * See comment above "struct start_info" in