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-64/mmcfg: relax base address restriction

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] x86-64/mmcfg: relax base address restriction
From: "Jan Beulich" <JBeulich@xxxxxxxxxx>
Date: Tue, 16 Aug 2011 12:49:49 +0100
Delivery-date: Tue, 16 Aug 2011 04:51:42 -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
Following what Linux did quite a while ago, don't generally disallow
MMCFG base addresses to live above the 4Gb boundary: New systems are
assumed to be fine, and SGI ones are, too.

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

--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -520,6 +520,76 @@ fail:              d++;
        return count;
 }
 
+/**
+ *     dmi_get_date - parse a DMI date
+ *     @field: data index (see enum dmi_field)
+ *     @yearp: optional out parameter for the year
+ *     @monthp: optional out parameter for the month
+ *     @dayp: optional out parameter for the day
+ *
+ *     The date field is assumed to be in the form resembling
+ *     [mm[/dd]]/yy[yy] and the result is stored in the out
+ *     parameters any or all of which can be omitted.
+ *
+ *     If the field doesn't exist, all out parameters are set to zero
+ *     and false is returned.  Otherwise, true is returned with any
+ *     invalid part of date set to zero.
+ *
+ *     On return, year, month and day are guaranteed to be in the
+ *     range of [0,9999], [0,12] and [0,31] respectively.
+ */
+bool_t __init dmi_get_date(int field, int *yearp, int *monthp, int *dayp)
+{
+       int year = 0, month = 0, day = 0;
+       bool_t exists;
+       const char *s, *e, *y;
+
+       s = field < DMI_STRING_MAX ? dmi_ident[field] : NULL;
+       exists = !!s;
+       if (!exists)
+               goto out;
+
+       /*
+        * Determine year first.  We assume the date string resembles
+        * mm/dd/yy[yy] but the original code extracted only the year
+        * from the end.  Keep the behavior in the spirit of no
+        * surprises.
+        */
+       y = strrchr(s, '/');
+       if (!y)
+               goto out;
+
+       y++;
+       year = simple_strtoul(y, &e, 10);
+       if (y != e && year < 100) {     /* 2-digit year */
+               year += 1900;
+               if (year < 1996)        /* no dates < spec 1.0 */
+                       year += 100;
+       }
+       if (year > 9999)                /* year should fit in %04d */
+               year = 0;
+
+       /* parse the mm and dd */
+       month = simple_strtoul(s, &e, 10);
+       if (s == e || *e != '/' || !month || month > 12) {
+               month = 0;
+               goto out;
+       }
+
+       s = e + 1;
+       day = simple_strtoul(s, &e, 10);
+       if (s == y || s == e || *e != '/' || day > 31)
+               day = 0;
+out:
+       if (yearp)
+               *yearp = year;
+       if (monthp)
+               *monthp = month;
+       if (dayp)
+               *dayp = day;
+       return exists;
+}
+
 void __init dmi_end_boot(void)
 {
     unsigned int i;
--- a/xen/arch/x86/x86_64/acpi_mmcfg.c
+++ b/xen/arch/x86/x86_64/acpi_mmcfg.c
@@ -48,6 +48,30 @@
 struct acpi_mcfg_allocation *pci_mmcfg_config;
 int pci_mmcfg_config_num;
 
+static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
+                                        struct acpi_mcfg_allocation *cfg)
+{
+    int year;
+
+    if (cfg->address < 0xFFFFFFFF)
+        return 0;
+
+    if (!strcmp(mcfg->header.oem_id, "SGI") ||
+        !strcmp(mcfg->header.oem_id, "SGI2"))
+        return 0;
+
+    if (mcfg->header.revision >= 1 &&
+        dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
+        year >= 2010)
+            return 0;
+
+    printk(KERN_ERR "MCFG region for %04x:%02x-%02x at %#"PRIx64
+                    " (above 4GB) ignored\n",
+           cfg->pci_segment, cfg->start_bus_number, cfg->end_bus_number,
+           cfg->address);
+    return -EINVAL;
+}
+
 int __init acpi_parse_mcfg(struct acpi_table_header *header)
 {
     struct acpi_table_mcfg *mcfg;
@@ -82,9 +106,7 @@ int __init acpi_parse_mcfg(struct acpi_t
            pci_mmcfg_config_num * sizeof(*pci_mmcfg_config));
 
     for (i = 0; i < pci_mmcfg_config_num; ++i) {
-        if (pci_mmcfg_config[i].address > 0xFFFFFFFF) {
-            printk(KERN_ERR PREFIX
-                   "MMCONFIG not in low 4GB of memory\n");
+        if (acpi_mcfg_check_entry(mcfg, &pci_mmcfg_config[i])) {
             xfree(pci_mmcfg_config);
             pci_mmcfg_config_num = 0;
             return -ENODEV;
--- a/xen/include/xen/dmi.h
+++ b/xen/include/xen/dmi.h
@@ -36,6 +36,7 @@ extern int dmi_check_system(struct dmi_s
 extern void dmi_scan_machine(void);
 extern int dmi_get_table(u32 *base, u32 *len);
 extern void dmi_efi_get_table(void *);
+bool_t dmi_get_date(int field, int *yearp, int *monthp, int *dayp);
 extern void dmi_end_boot(void);
 
 #endif /* __DMI_H__ */


Attachment: x86_64-mmcfg-64bit.patch
Description: Text document

_______________________________________________
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-64/mmcfg: relax base address restriction, Jan Beulich <=