[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.