WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] x86/mmcfg: misc adjustments
From: "Jan Beulich" <JBeulich@xxxxxxxxxx>
Date: Fri, 04 Sep 2009 14:11:32 +0100
Delivery-date: Fri, 04 Sep 2009 06:13:59 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
- 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] x86/mmcfg: misc adjustments, Jan Beulich <=