[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Convert x86/32 Linux to use the new memory map hypercall.
# HG changeset patch # User Ian.Campbell@xxxxxxxxxxxxx # Node ID d61211a6c273de817af91944c666ffb6406c6798 # Parent 810ad61870e8c61a4e9ed096c4f73ab62048183b Convert x86/32 Linux to use the new memory map hypercall. This change removes several of the differences between the bare-metal and Xen versions. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx> --- linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c | 224 ++++------ linux-2.6-xen-sparse/arch/i386/mm/init-xen.c | 13 linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h | 28 + 3 files changed, 134 insertions(+), 131 deletions(-) diff -r 810ad61870e8 -r d61211a6c273 linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon May 22 09:22:18 2006 +0100 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon May 22 09:23:03 2006 +0100 @@ -70,9 +70,6 @@ /* Forward Declaration. */ void __init find_max_pfn(void); - -/* Allows setting of maximum possible memory size */ -static unsigned long xen_override_max_pfn; static int xen_panic_event(struct notifier_block *, unsigned long, void *); static struct notifier_block xen_panic_block = { @@ -462,6 +459,19 @@ static void __init limit_regions(unsigne } return; } +#ifdef CONFIG_XEN + if (i==e820.nr_map && current_addr < size) { + /* + * The e820 map finished before our requested size so + * extend the final entry to the requested address. + */ + --i; + if (e820.map[i].type == E820_RAM) + e820.map[i].size -= current_addr - size; + else + add_memory_region(current_addr, size - current_addr, E820_RAM); + } +#endif } #define E820_DEBUG 1 @@ -492,7 +502,6 @@ static void __init print_memory_map(char } } -#if 0 /* * Sanitize the BIOS e820 map. * @@ -680,9 +689,13 @@ static int __init sanitize_e820_map(stru */ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) { +#ifndef CONFIG_XEN /* Only one memory region (or negative)? Ignore it */ if (nr_map < 2) return -1; +#else + BUG_ON(nr_map < 1); +#endif do { unsigned long long start = biosmap->addr; @@ -694,6 +707,7 @@ static int __init copy_e820_map(struct e if (start > end) return -1; +#ifndef CONFIG_XEN /* * Some BIOSes claim RAM in the 640k - 1M region. * Not right. Fix it up. @@ -708,11 +722,11 @@ static int __init copy_e820_map(struct e size = end - start; } } +#endif add_memory_region(start, size, type); } while (biosmap++,--nr_map); return 0; } -#endif #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; @@ -785,13 +799,8 @@ static void __init parse_cmdline_early ( unsigned long long mem_size; mem_size = memparse(from+4, &from); -#if 0 limit_regions(mem_size); userdef=1; -#else - xen_override_max_pfn = - (unsigned long)(mem_size>>PAGE_SHIFT); -#endif } } @@ -984,7 +993,6 @@ static void __init parse_cmdline_early ( } } -#if 0 /* !XEN */ /* * Callback for efi_memory_walk. */ @@ -1036,21 +1044,6 @@ void __init find_max_pfn(void) memory_present(0, start, end); } } -#else -/* We don't use the fake e820 because we need to respond to user override. */ -void __init find_max_pfn(void) -{ - if (xen_override_max_pfn == 0) { - max_pfn = xen_start_info->nr_pages; - /* Default 8MB slack (to balance backend allocations). */ - max_pfn += 8 << (20 - PAGE_SHIFT); - } else if (xen_override_max_pfn > xen_start_info->nr_pages) { - max_pfn = xen_override_max_pfn; - } else { - max_pfn = xen_start_info->nr_pages; - } -} -#endif /* XEN */ /* * Determine low and high memory ranges: @@ -1158,6 +1151,15 @@ static void __init register_bootmem_low_ */ last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); +#ifdef CONFIG_XEN + /* + * Truncate to the number of actual pages currently + * present. + */ + if (last_pfn > xen_start_info->nr_pages) + last_pfn = xen_start_info->nr_pages; +#endif + if (last_pfn > max_low_pfn) last_pfn = max_low_pfn; @@ -1351,83 +1353,33 @@ void __init remapped_pgdat_init(void) * and also for regions reported as reserved by the e820. */ static void __init -legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource) +legacy_init_iomem_resources(struct e820entry *e820, int nr_map, + struct resource *code_resource, + struct resource *data_resource) { int i; -#ifdef CONFIG_XEN - dom0_op_t op; - struct dom0_memory_map_entry *map; - unsigned long gapstart, gapsize; - unsigned long long last; -#endif - -#ifdef CONFIG_XEN_PRIVILEGED_GUEST + +#if defined(CONFIG_XEN_PRIVILEGED_GUEST) || !defined(CONFIG_XEN) probe_roms(); #endif -#ifdef CONFIG_XEN - map = alloc_bootmem_low_pages(PAGE_SIZE); - op.cmd = DOM0_PHYSICAL_MEMORY_MAP; - set_xen_guest_handle(op.u.physical_memory_map.memory_map, map); - op.u.physical_memory_map.max_map_entries = - PAGE_SIZE / sizeof(struct dom0_memory_map_entry); - BUG_ON(HYPERVISOR_dom0_op(&op)); - - last = 0x100000000ULL; - gapstart = 0x10000000; - gapsize = 0x400000; - - for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) { + for (i = 0; i < nr_map; i++) { struct resource *res; - - if ((last > map[i].end) && ((last - map[i].end) > gapsize)) { - gapsize = last - map[i].end; - gapstart = map[i].end; - } - if (map[i].start < last) - last = map[i].start; - - if (map[i].end > 0x100000000ULL) + if (e820[i].addr + e820[i].size > 0x100000000ULL) continue; res = alloc_bootmem_low(sizeof(struct resource)); - res->name = map[i].is_ram ? "System RAM" : "reserved"; - res->start = map[i].start; - res->end = map[i].end - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - request_resource(&iomem_resource, res); - } - - free_bootmem(__pa(map), PAGE_SIZE); - - /* - * Start allocating dynamic PCI memory a bit into the gap, - * aligned up to the nearest megabyte. - * - * Question: should we try to pad it up a bit (do something - * like " + (gapsize >> 3)" in there too?). We now have the - * technology. - */ - pci_mem_start = (gapstart + 0xfffff) & ~0xfffff; - - printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", - pci_mem_start, gapstart, gapsize); -#else - for (i = 0; i < e820.nr_map; i++) { - struct resource *res; - if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) - continue; - res = alloc_bootmem_low(sizeof(struct resource)); - switch (e820.map[i].type) { + switch (e820[i].type) { case E820_RAM: res->name = "System RAM"; break; case E820_ACPI: res->name = "ACPI Tables"; break; case E820_NVS: res->name = "ACPI Non-volatile Storage"; break; default: res->name = "reserved"; } - res->start = e820.map[i].addr; - res->end = res->start + e820.map[i].size - 1; + res->start = e820[i].addr; + res->end = res->start + e820[i].size - 1; res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); - if (e820.map[i].type == E820_RAM) { +#ifndef CONFIG_XEN + if (e820[i].type == E820_RAM) { /* * We don't know which RAM region contains kernel data, * so we try it repeatedly and let the resource manager @@ -1439,38 +1391,21 @@ legacy_init_iomem_resources(struct resou request_resource(res, &crashk_res); #endif } - } -#endif -} - -/* - * Request address space for all standard resources - */ -static void __init register_memory(void) -{ -#ifndef CONFIG_XEN +#endif + } +} + +/* + * Locate a unused range of the physical address space below 4G which + * can be used for PCI mappings. + */ +static void __init +e820_setup_gap(struct e820entry *e820, int nr_map) +{ unsigned long gapstart, gapsize, round; unsigned long long last; -#endif - int i; - - /* Nothing to do if not running in dom0. */ - if (!(xen_start_info->flags & SIF_INITDOMAIN)) - return; - - if (efi_enabled) - efi_initialize_iomem_resources(&code_resource, &data_resource); - else - legacy_init_iomem_resources(&code_resource, &data_resource); - - /* EFI systems may still have VGA */ - request_resource(&iomem_resource, &video_ram_resource); - - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < STANDARD_IO_RESOURCES; i++) - request_resource(&ioport_resource, &standard_io_resources[i]); - -#ifndef CONFIG_XEN + int i; + /* * Search for the bigest gap in the low 32 bits of the e820 * memory space. @@ -1478,10 +1413,10 @@ static void __init register_memory(void) last = 0x100000000ull; gapstart = 0x10000000; gapsize = 0x400000; - i = e820.nr_map; + i = nr_map; while (--i >= 0) { - unsigned long long start = e820.map[i].addr; - unsigned long long end = start + e820.map[i].size; + unsigned long long start = e820[i].addr; + unsigned long long end = start + e820[i].size; /* * Since "last" is at most 4GB, we know we'll @@ -1511,6 +1446,53 @@ static void __init register_memory(void) printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", pci_mem_start, gapstart, gapsize); +} + +/* + * Request address space for all standard resources + */ +static void __init register_memory(void) +{ +#ifdef CONFIG_XEN + struct e820entry *machine_e820; + struct xen_memory_map memmap; +#endif + int i; + + /* Nothing to do if not running in dom0. */ + if (!(xen_start_info->flags & SIF_INITDOMAIN)) + return; + +#ifdef CONFIG_XEN + machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE); + + memmap.nr_entries = E820MAX; + set_xen_guest_handle(memmap.buffer, machine_e820); + + BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap)); + + legacy_init_iomem_resources(machine_e820, memmap.nr_entries, + &code_resource, &data_resource); +#else + if (efi_enabled) + efi_initialize_iomem_resources(&code_resource, &data_resource); + else + legacy_init_iomem_resources(e820.map, e820.nr_map, + &code_resource, &data_resource); +#endif + + /* EFI systems may still have VGA */ + request_resource(&iomem_resource, &video_ram_resource); + + /* request I/O space for devices used on all i[345]86 PCs */ + for (i = 0; i < STANDARD_IO_RESOURCES; i++) + request_resource(&ioport_resource, &standard_io_resources[i]); + +#ifdef CONFIG_XEN + e820_setup_gap(machine_e820, memmap.nr_entries); + free_bootmem(__pa(machine_e820), PAGE_SIZE); +#else + e820_setup_gap(e820.map, e820.nr_map); #endif } diff -r 810ad61870e8 -r d61211a6c273 linux-2.6-xen-sparse/arch/i386/mm/init-xen.c --- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Mon May 22 09:22:18 2006 +0100 +++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Mon May 22 09:23:03 2006 +0100 @@ -228,6 +228,12 @@ static inline int page_kills_ppro(unsign return 0; } +#else + +#define page_kills_ppro(p) 0 + +#endif + extern int is_available_memory(efi_memory_desc_t *); int page_is_ram(unsigned long pagenr) @@ -268,13 +274,6 @@ int page_is_ram(unsigned long pagenr) } return 0; } - -#else /* CONFIG_XEN */ - -#define page_kills_ppro(p) 0 -#define page_is_ram(p) 1 - -#endif #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; diff -r 810ad61870e8 -r d61211a6c273 linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon May 22 09:22:18 2006 +0100 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon May 22 09:23:03 2006 +0100 @@ -10,10 +10,32 @@ static char * __init machine_specific_memory_setup(void) { - unsigned long max_pfn = xen_start_info->nr_pages; + int rc; + struct xen_memory_map memmap; + /* + * This is rather large for a stack variable but this early in + * the boot process we know we have plenty slack space. + */ + struct e820entry map[E820MAX]; - e820.nr_map = 0; - add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM); + memmap.nr_entries = E820MAX; + set_xen_guest_handle(memmap.buffer, map); + + rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); + if ( rc == -ENOSYS ) { + memmap.nr_entries = 1; + map[0].addr = 0ULL; + map[0].size = xen_start_info->nr_pages << PAGE_SHIFT; + /* 8MB slack (to balance backend allocations). */ + map[0].size += 8 << 20; + map[0].type = E820_RAM; + rc = 0; + } + BUG_ON(rc); + + sanitize_e820_map(map, (char *)&memmap.nr_entries); + + BUG_ON(copy_e820_map(map, (char)memmap.nr_entries) < 0); return "Xen"; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |