# 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
|