[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86/mmcfg: misc adjustments



- fix the mapping range (end_bus_number is inclusive)
- fix the mapping base address (shifting segment by 22 was set for
  overlapping mappings; assuming the goal was to reduce the virtual
  space used when less than 256 busses are present on all segments,
  adding logic to determine the smallest possible shift value)
- fix PCI_MCFG_VIRT_END, and actually use it to avoid creating mappings
  outside the designated range
- fix address calculations (segment numbers must be converted to long
  to avoid truncation)
- add a way (command line option) to suppress the use of mmconfig as
  well as to actually use the AMD Fam10 special code
- correct __init annotations
- use xmalloc()/xmalloc_array() in favor of xmalloc_bytes()
- eliminate dead code and data

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

--- 2009-08-18.orig/xen/arch/x86/x86_64/acpi_mmcfg.c    2009-09-04 
14:23:19.000000000 +0200
+++ 2009-08-18/xen/arch/x86/x86_64/acpi_mmcfg.c 2009-09-04 12:38:10.000000000 
+0200
@@ -48,13 +48,10 @@
 struct acpi_mcfg_allocation *pci_mmcfg_config;
 int pci_mmcfg_config_num;
 
-static int acpi_mcfg_64bit_base_addr __initdata = FALSE;
-
-int acpi_parse_mcfg(struct acpi_table_header *header)
+int __init acpi_parse_mcfg(struct acpi_table_header *header)
 {
     struct acpi_table_mcfg *mcfg;
     unsigned long i;
-    int config_size;
 
     if (!header)
         return -EINVAL;
@@ -73,19 +70,19 @@ int acpi_parse_mcfg(struct acpi_table_he
         return -ENODEV;
     }
 
-    config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
-    pci_mmcfg_config = xmalloc_bytes(config_size);
+    pci_mmcfg_config = xmalloc_array(struct acpi_mcfg_allocation,
+                                     pci_mmcfg_config_num);
     if (!pci_mmcfg_config) {
         printk(KERN_WARNING PREFIX
                "No memory for MCFG config tables\n");
         return -ENOMEM;
     }
 
-    memcpy(pci_mmcfg_config, &mcfg[1], config_size);
+    memcpy(pci_mmcfg_config, &mcfg[1],
+           pci_mmcfg_config_num * sizeof(*pci_mmcfg_config));
 
     for (i = 0; i < pci_mmcfg_config_num; ++i) {
-        if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) &&
-            !acpi_mcfg_64bit_base_addr) {
+        if (pci_mmcfg_config[i].address > 0xFFFFFFFF) {
             printk(KERN_ERR PREFIX
                    "MMCONFIG not in low 4GB of memory\n");
             xfree(pci_mmcfg_config);
--- 2009-08-18.orig/xen/arch/x86/x86_64/mmconfig.h      2009-09-04 
12:32:49.000000000 +0200
+++ 2009-08-18/xen/arch/x86/x86_64/mmconfig.h   2009-09-04 12:38:10.000000000 
+0200
@@ -81,7 +81,7 @@ static inline void mmio_config_writel(vo
 extern int pci_mmcfg_config_num;
 extern struct acpi_mcfg_allocation *pci_mmcfg_config;
 
-/* fucntion prototypes */
-int __init acpi_parse_mcfg(struct acpi_table_header *header);
-int __init pci_mmcfg_arch_init(void);
-void __init pci_mmcfg_arch_free(void);
+/* function prototypes */
+int acpi_parse_mcfg(struct acpi_table_header *header);
+int pci_mmcfg_arch_init(void);
+void pci_mmcfg_arch_free(void);
--- 2009-08-18.orig/xen/arch/x86/x86_64/mmconfig-shared.c       2009-09-04 
12:30:42.000000000 +0200
+++ 2009-08-18/xen/arch/x86/x86_64/mmconfig-shared.c    2009-09-04 
13:35:07.000000000 +0200
@@ -24,7 +24,27 @@
 #include "mmconfig.h"
 
 static int __initdata known_bridge;
-unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_MMCONF;
+static unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_MMCONF;
+
+static void __init parse_mmcfg(char *s)
+{
+    char *ss;
+
+    do {
+        ss = strchr(s, ',');
+        if ( ss )
+            *ss = '\0';
+
+        if ( !strcmp(s, "off") || !strcmp(s, "no") || !strcmp(s, "false") ||
+             !strcmp(s, "0") || !strcmp(s, "disable") )
+            pci_probe &= ~PCI_PROBE_MMCONF;
+        else if ( !strcmp(s, "amd_fam10") || !strcmp(s, "amd-fam10") )
+            pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF;
+
+        s = ss + 1;
+    } while ( ss );
+}
+custom_param("mmcfg", parse_mmcfg);
 
 static const char __init *pci_mmcfg_e7520(void)
 {
@@ -36,7 +56,7 @@ static const char __init *pci_mmcfg_e752
         pci_mmcfg_config_num = 0;
     else {
         pci_mmcfg_config_num = 1;
-        pci_mmcfg_config = xmalloc_bytes(sizeof(pci_mmcfg_config[0]));
+        pci_mmcfg_config = xmalloc(struct acpi_mcfg_allocation);
         if (!pci_mmcfg_config)
             return NULL;
         memset(pci_mmcfg_config, 0, sizeof(pci_mmcfg_config[0]));
@@ -90,7 +110,7 @@ static const char __init *pci_mmcfg_inte
         pci_mmcfg_config_num = 0;
 
     if (pci_mmcfg_config_num) {
-        pci_mmcfg_config = xmalloc_bytes(sizeof(pci_mmcfg_config[0]));
+        pci_mmcfg_config = xmalloc(struct acpi_mcfg_allocation);
         if (!pci_mmcfg_config)
             return NULL;
         memset(pci_mmcfg_config, 0, sizeof(pci_mmcfg_config[0]));
@@ -143,13 +163,13 @@ static const char __init *pci_mmcfg_amd_
     }
 
     pci_mmcfg_config_num = (1 << segnbits);
-    pci_mmcfg_config = xmalloc_bytes(sizeof(pci_mmcfg_config[0]) *
+    pci_mmcfg_config = xmalloc_array(struct acpi_mcfg_allocation,
                                      pci_mmcfg_config_num);
     if (!pci_mmcfg_config)
         return NULL;
 
     for (i = 0; i < (1 << segnbits); i++) {
-        pci_mmcfg_config[i].address = base + (1<<28) * i;
+        pci_mmcfg_config[i].address = base + ((unsigned long)i << 28);
         pci_mmcfg_config[i].pci_segment = i;
         pci_mmcfg_config[i].start_bus_number = 0;
         pci_mmcfg_config[i].end_bus_number = (1 << busnbits) - 1;
@@ -334,7 +354,7 @@ static int __init is_mmconf_reserved(
     return valid;
 }
 
-static void __init pci_mmcfg_reject_broken(int early)
+static void __init pci_mmcfg_reject_broken(void)
 {
     typeof(pci_mmcfg_config[0]) *cfg;
     int i;
@@ -347,7 +367,6 @@ static void __init pci_mmcfg_reject_brok
     cfg = &pci_mmcfg_config[0];
 
     for (i = 0; i < pci_mmcfg_config_num; i++) {
-        int valid = 0;
         u64 addr, size;
 
         cfg = &pci_mmcfg_config[i];
@@ -362,17 +381,7 @@ static void __init pci_mmcfg_reject_brok
                (unsigned int)cfg->start_bus_number,
                (unsigned int)cfg->end_bus_number);
 
-        if (valid)
-            continue;
-
-        if (!early)
-            printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %lx is not"
-                   " reserved in ACPI motherboard resources\n",
-                   cfg->address);
-
-        valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1);
-
-        if (!valid)
+        if (!is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1))
             goto reject;
     }
 
@@ -386,28 +395,26 @@ reject:
     pci_mmcfg_config_num = 0;
 }
 
-void __init __pci_mmcfg_init(int early)
+void __init acpi_mmcfg_init(void)
 {
     /* MMCONFIG disabled */
     if ((pci_probe & PCI_PROBE_MMCONF) == 0)
         return;
 
     /* MMCONFIG already enabled */
-    if (!early && !(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF))
+    if (!(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF))
         return;
 
     /* for late to exit */
     if (known_bridge)
         return;
 
-    if (early) {
-        if (pci_mmcfg_check_hostbridge())
-            known_bridge = 1;
-    }
+    if (pci_mmcfg_check_hostbridge())
+        known_bridge = 1;
 
     if (!known_bridge) {
         acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
-        pci_mmcfg_reject_broken(early);
+        pci_mmcfg_reject_broken();
     }
 
     if ((pci_mmcfg_config_num == 0) ||
@@ -420,11 +427,6 @@ void __init __pci_mmcfg_init(int early)
     }
 }
 
-void acpi_mmcfg_init(void)
-{
-    __pci_mmcfg_init(1);
-}
-
 /**
  * pci_find_ext_capability - Find an extended capability
  * @dev: PCI device to query
--- 2009-08-18.orig/xen/arch/x86/x86_64/mmconfig_64.c   2009-09-04 
14:23:19.000000000 +0200
+++ 2009-08-18/xen/arch/x86/x86_64/mmconfig_64.c        2009-09-04 
14:30:10.000000000 +0200
@@ -21,6 +21,7 @@ struct mmcfg_virt {
     char __iomem *virt;
 };
 static struct mmcfg_virt *pci_mmcfg_virt;
+static int __initdata mmcfg_pci_segment_shift;
 
 static char __iomem *get_virt(unsigned int seg, unsigned bus)
 {
@@ -109,27 +110,26 @@ int pci_mmcfg_write(unsigned int seg, un
 
 static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
 {
-    void __iomem *addr;
-    unsigned long virt;
-    unsigned long mfn;
-    unsigned long size, nr_mfn;
-
-    virt = PCI_MCFG_VIRT_START + (cfg->pci_segment * (1 << 22)) +
-               (cfg->start_bus_number * (1 << 20));
-    mfn = cfg->address >> PAGE_SHIFT;
-        size = (cfg->end_bus_number - cfg->start_bus_number) << 20;
-        nr_mfn = size >> PAGE_SHIFT;
+    unsigned long virt, size;
 
-    map_pages_to_xen(virt, mfn, nr_mfn, PAGE_HYPERVISOR_NOCACHE);
-    addr = (void __iomem *) virt;
+    virt = PCI_MCFG_VIRT_START +
+           ((unsigned long)cfg->pci_segment << mmcfg_pci_segment_shift) +
+           (cfg->start_bus_number << 20);
+    size = (cfg->end_bus_number - cfg->start_bus_number + 1) << 20;
+    if (virt + size < virt || virt + size > PCI_MCFG_VIRT_END)
+        return NULL;
+
+    map_pages_to_xen(virt, cfg->address >> PAGE_SHIFT,
+                     size >> PAGE_SHIFT, PAGE_HYPERVISOR_NOCACHE);
 
-    return addr;
+    return (void __iomem *) virt;
 }
 
 int __init pci_mmcfg_arch_init(void)
 {
     int i;
-    pci_mmcfg_virt = xmalloc_bytes(sizeof(*pci_mmcfg_virt) * 
pci_mmcfg_config_num);
+
+    pci_mmcfg_virt = xmalloc_array(struct mmcfg_virt, pci_mmcfg_config_num);
     if (pci_mmcfg_virt == NULL) {
         printk(KERN_ERR "PCI: Can not allocate memory for mmconfig 
structures\n");
         return 0;
@@ -138,6 +138,11 @@ int __init pci_mmcfg_arch_init(void)
 
     for (i = 0; i < pci_mmcfg_config_num; ++i) {
         pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
+        while (pci_mmcfg_config[i].end_bus_number >> mmcfg_pci_segment_shift)
+            ++mmcfg_pci_segment_shift;
+    }
+    mmcfg_pci_segment_shift += 20;
+    for (i = 0; i < pci_mmcfg_config_num; ++i) {
         pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]);
         if (!pci_mmcfg_virt[i].virt) {
             printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
--- 2009-08-18.orig/xen/include/asm-x86/config.h        2009-09-04 
14:01:23.000000000 +0200
+++ 2009-08-18/xen/include/asm-x86/config.h     2009-09-04 14:15:36.000000000 
+0200
@@ -194,7 +194,7 @@ extern unsigned int video_mode, video_fl
  *     - since PML4 slot has 39 bits, we limit segments to 2048 (11-bits)
  */
 #define PCI_MCFG_VIRT_START     (PML4_ADDR(257))
-#define PCI_MCFG_VIRT_END       (RDWR_MPT_VIRT_START + PML4_ENTRY_BYTES)
+#define PCI_MCFG_VIRT_END       (PCI_MCFG_VIRT_START + PML4_ENTRY_BYTES)
 /* Slot 258: linear page table (guest table). */
 #define LINEAR_PT_VIRT_START    (PML4_ADDR(258))
 #define LINEAR_PT_VIRT_END      (LINEAR_PT_VIRT_START + PML4_ENTRY_BYTES)



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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