[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix PCI iomem resource fixup.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID d105692072a417a67f034b012a13af5c62b37432 # Parent 22599cd6aae053fc196ba630fc9d0a253e03b90b Fix PCI iomem resource fixup. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 22599cd6aae0 -r d105692072a4 linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Mon Sep 5 19:43:04 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Mon Sep 5 19:53:44 2005 @@ -1235,10 +1235,64 @@ legacy_init_iomem_resources(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 probe_roms(); #endif + +#ifdef CONFIG_XEN + map = alloc_bootmem_low_pages(PAGE_SIZE); + op.cmd = DOM0_PHYSICAL_MEMORY_MAP; + 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--) { + 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) + 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) @@ -1264,6 +1318,7 @@ request_resource(res, data_resource); } } +#endif } /* @@ -1271,23 +1326,29 @@ */ static void __init register_memory(void) { +#ifndef CONFIG_XEN unsigned long gapstart, gapsize; 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); - if (xen_start_info->flags & SIF_INITDOMAIN) - /* EFI systems may still have VGA */ - request_resource(&iomem_resource, &video_ram_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 /* * Search for the bigest gap in the low 32 bits of the e820 * memory space. @@ -1328,6 +1389,7 @@ printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", pci_mem_start, gapstart, gapsize); +#endif } /* Use inline assembly to define this because the nops are defined diff -r 22599cd6aae0 -r d105692072a4 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c Mon Sep 5 19:43:04 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c Mon Sep 5 19:53:44 2005 @@ -517,11 +517,10 @@ } #else /* CONFIX_XEN */ + extern unsigned long xen_override_max_pfn; extern union xen_start_info_union xen_start_info_union; -/* - * Guest physical starts from 0. - */ + unsigned long __init e820_end_of_ram(void) { unsigned long max_end_pfn = xen_start_info->nr_pages; @@ -532,64 +531,53 @@ return xen_override_max_pfn; } - - void __init e820_reserve_resources(void) { - return; /* Xen won't have reserved entries */ -} - -#endif - -void __init parse_memopt(char *p, char **from) -{ - end_user_pfn = memparse(p, from); - end_user_pfn >>= PAGE_SHIFT; - xen_override_max_pfn = (unsigned long) end_user_pfn; -} - -unsigned long pci_mem_start = 0xaeedbabe; - -/* - * Search for the biggest gap in the low 32 bits of the e820 - * memory space. We pass this space to PCI to assign MMIO resources - * for hotplug or unconfigured devices in. - * Hopefully the BIOS let enough space left. - */ -__init void e820_setup_gap(void) -{ - unsigned long gapstart, gapsize; - unsigned long last; - int i; - int found = 0; - - last = 0x100000000ull; + dom0_op_t op; + struct dom0_memory_map_entry *map; + unsigned long gapstart, gapsize, last; + int i, found = 0; + + if (!(xen_start_info->flags & SIF_INITDOMAIN)) + return; + + map = alloc_bootmem_low_pages(PAGE_SIZE); + op.cmd = DOM0_PHYSICAL_MEMORY_MAP; + 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; - i = e820.nr_map; - while (--i >= 0) { - unsigned long long start = e820.map[i].addr; - unsigned long long end = start + e820.map[i].size; - - /* - * Since "last" is at most 4GB, we know we'll - * fit in 32 bits if this condition is true - */ - if (last > end) { - unsigned long gap = last - end; - - if (gap > gapsize) { - gapsize = gap; - gapstart = end; - found = 1; - } - } - if (start < last) - last = start; - } + + for (i = op.u.physical_memory_map.nr_map_entries - 1; i >= 0; i--) { + struct resource *res; + + if ((last > map[i].end) && ((last - map[i].end) > gapsize)) { + gapsize = last - map[i].end; + gapstart = map[i].end; + found = 1; + } + if (map[i].start < last) + last = map[i].start; + + if (map[i].end > 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); if (!found) { - gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024; + HYPERVISOR_memory_op(XENMEM_maximum_ram_page, &gapstart); + gapstart = (gapstart << PAGE_SHIFT) + 1024*1024; printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n" KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n"); } @@ -607,3 +595,74 @@ printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", pci_mem_start, gapstart, gapsize); } + +#endif + +void __init parse_memopt(char *p, char **from) +{ + end_user_pfn = memparse(p, from); + end_user_pfn >>= PAGE_SHIFT; + xen_override_max_pfn = (unsigned long) end_user_pfn; +} + +unsigned long pci_mem_start = 0xaeedbabe; + +/* + * Search for the biggest gap in the low 32 bits of the e820 + * memory space. We pass this space to PCI to assign MMIO resources + * for hotplug or unconfigured devices in. + * Hopefully the BIOS let enough space left. + */ +__init void e820_setup_gap(void) +{ +#ifndef CONFIG_XEN + unsigned long gapstart, gapsize; + unsigned long last; + int i; + int found = 0; + + last = 0x100000000ull; + gapstart = 0x10000000; + gapsize = 0x400000; + i = e820.nr_map; + while (--i >= 0) { + unsigned long long start = e820.map[i].addr; + unsigned long long end = start + e820.map[i].size; + + /* + * Since "last" is at most 4GB, we know we'll + * fit in 32 bits if this condition is true + */ + if (last > end) { + unsigned long gap = last - end; + + if (gap > gapsize) { + gapsize = gap; + gapstart = end; + found = 1; + } + } + if (start < last) + last = start; + } + + if (!found) { + gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024; + printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n" + KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n"); + } + + /* + * 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(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", + pci_mem_start, gapstart, gapsize); +#endif +} diff -r 22599cd6aae0 -r d105692072a4 xen/arch/x86/dom0_ops.c --- a/xen/arch/x86/dom0_ops.c Mon Sep 5 19:43:04 2005 +++ b/xen/arch/x86/dom0_ops.c Mon Sep 5 19:53:44 2005 @@ -389,9 +389,31 @@ } break; + case DOM0_PHYSICAL_MEMORY_MAP: + { + struct dom0_memory_map_entry entry; + int i; + + for ( i = 0; i < e820.nr_map; i++ ) + { + if ( i >= op->u.physical_memory_map.max_map_entries ) + break; + entry.start = e820.map[i].addr; + entry.end = e820.map[i].addr + e820.map[i].size; + entry.is_ram = (e820.map[i].type == E820_RAM); + (void)copy_to_user( + &op->u.physical_memory_map.memory_map[i], + &entry, sizeof(entry)); + } + + op->u.physical_memory_map.nr_map_entries = i; + (void)copy_to_user(u_dom0_op, op, sizeof(*op)); + } + break; + default: ret = -ENOSYS; - + break; } return ret; diff -r 22599cd6aae0 -r d105692072a4 xen/common/domain.c --- a/xen/common/domain.c Mon Sep 5 19:43:04 2005 +++ b/xen/common/domain.c Mon Sep 5 19:53:44 2005 @@ -176,10 +176,7 @@ void domain_shutdown(u8 reason) { struct domain *d = current->domain; - struct vcpu *v; - - if(reason == SHUTDOWN_crash) - printk("Domain %d crash detected.\n", d->domain_id); + struct vcpu *v; if ( d->domain_id == 0 ) { diff -r 22599cd6aae0 -r d105692072a4 xen/common/memory.c --- a/xen/common/memory.c Mon Sep 5 19:43:04 2005 +++ b/xen/common/memory.c Mon Sep 5 19:53:44 2005 @@ -190,7 +190,7 @@ case XENMEM_maximum_ram_page: if ( put_user(max_page, (unsigned long *)arg) ) return -EFAULT; - rc = -ENOSYS; + rc = 0; break; default: diff -r 22599cd6aae0 -r d105692072a4 xen/include/public/dom0_ops.h --- a/xen/include/public/dom0_ops.h Mon Sep 5 19:43:04 2005 +++ b/xen/include/public/dom0_ops.h Mon Sep 5 19:53:44 2005 @@ -373,6 +373,18 @@ /* IN variables. */ int quirk_id; } dom0_platform_quirk_t; + +#define DOM0_PHYSICAL_MEMORY_MAP 40 +typedef struct { + /* IN variables. */ + int max_map_entries; + /* OUT variables. */ + int nr_map_entries; + struct dom0_memory_map_entry { + u64 start, end; + int is_ram; + } *memory_map; +} dom0_physical_memory_map_t; typedef struct { u32 cmd; @@ -408,6 +420,7 @@ dom0_getvcpucontext_t getvcpucontext; dom0_getdomaininfolist_t getdomaininfolist; dom0_platform_quirk_t platform_quirk; + dom0_physical_memory_map_t physical_memory_map; } u; } dom0_op_t; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |