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

[Xen-changelog] [xen-unstable] VT-d: improve RMRR validity checking



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1264065121 0
# Node ID 961acb357740507248fb5f6e502625c39e923177
# Parent  acd7d3f06d9aea147dcd7ea3830574cb64bce41b
VT-d: improve RMRR validity checking

Currently, Xen checks RMRR range and disables VT-d if RMRR range is
set incorrectly in BIOS rigorously. But, actually we can ignore the
RMRR if the device under its scope are not pci discoverable, because
the RMRR won't be used by non-existed or disabled devices.

This patch ignores the RMRR if the device under its scope are not pci
discoverable, and only checks the validity of RMRRs that are actually
used. In order to avoid duplicate pci device detection code, this
patch defines a function pci_device_detect for it.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/drivers/passthrough/pci.c      |   21 ++++++++++---
 xen/drivers/passthrough/vtd/dmar.c |   56 +++++++++++++++++++++++++++++--------
 xen/include/xen/pci.h              |    1 
 3 files changed, 61 insertions(+), 17 deletions(-)

diff -r acd7d3f06d9a -r 961acb357740 xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Thu Jan 21 09:11:06 2010 +0000
+++ b/xen/drivers/passthrough/pci.c     Thu Jan 21 09:12:01 2010 +0000
@@ -362,6 +362,21 @@ out:
 }
 
 /*
+ * detect pci device, return 0 if it exists, or return 0
+ */
+int pci_device_detect(u8 bus, u8 dev, u8 func)
+{
+    u32 vendor;
+
+    vendor = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID);
+    /* some broken boards return 0 or ~0 if a slot is empty: */
+    if ( (vendor == 0xffffffff) || (vendor == 0x00000000) ||
+         (vendor == 0x0000ffff) || (vendor == 0xffff0000) )
+        return 0;
+    return 1;
+}
+
+/*
  * scan pci devices to add all existed PCI devices to alldevs_list,
  * and setup pci hierarchy in array bus2bridge. This function is only
  * called in VT-d hardware setup
@@ -372,7 +387,6 @@ int __init scan_pci_devices(void)
     int bus, dev, func;
     u8 sec_bus, sub_bus;
     int type;
-    u32 l;
 
     spin_lock(&pcidevs_lock);
     for ( bus = 0; bus < 256; bus++ )
@@ -381,10 +395,7 @@ int __init scan_pci_devices(void)
         {
             for ( func = 0; func < 8; func++ )
             {
-                l = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID);
-                /* some broken boards return 0 or ~0 if a slot is empty: */
-                if ( (l == 0xffffffff) || (l == 0x00000000) ||
-                     (l == 0x0000ffff) || (l == 0xffff0000) )
+                if ( pci_device_detect(bus, dev, func) == 0 )
                     continue;
 
                 pdev = alloc_pdev(bus, PCI_DEVFN(dev, func));
diff -r acd7d3f06d9a -r 961acb357740 xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c        Thu Jan 21 09:11:06 2010 +0000
+++ b/xen/drivers/passthrough/vtd/dmar.c        Thu Jan 21 09:12:01 2010 +0000
@@ -410,14 +410,6 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
     u64 base_addr = rmrr->base_address, end_addr = rmrr->end_address;
     int ret = 0;
 
-    if ( base_addr >= end_addr )
-    {
-        dprintk(XENLOG_ERR VTDPREFIX,
-                "RMRR error: base_addr %"PRIx64" end_address %"PRIx64"\n",
-                base_addr, end_addr);
-        return -EFAULT;
-    }
-
 #ifdef CONFIG_X86
     /* This check is here simply to detect when RMRR values are
      * not properly represented in the system memory map and
@@ -441,9 +433,6 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
 
     rmrru->base_address = base_addr;
     rmrru->end_address = end_addr;
-    dprintk(XENLOG_INFO VTDPREFIX,
-            "  RMRR region: base_addr %"PRIx64" end_address %"PRIx64"\n",
-            rmrru->base_address, rmrru->end_address);
 
     dev_scope_start = (void *)(rmrr + 1);
     dev_scope_end   = ((void *)rmrr) + header->length;
@@ -453,7 +442,50 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
     if ( ret || (rmrru->scope.devices_cnt == 0) )
         xfree(rmrru);
     else
-        acpi_register_rmrr_unit(rmrru);
+    {
+        u8 b, d, f;
+        int i, ignore = 0;
+
+        for ( i = 0; i < rmrru->scope.devices_cnt; i++ )
+        {
+            b = PCI_BUS(rmrru->scope.devices[i]);
+            d = PCI_SLOT(rmrru->scope.devices[i]);
+            f = PCI_FUNC(rmrru->scope.devices[i]);
+
+            if ( pci_device_detect(b, d, f) == 0 )
+                ignore = 1;
+            else
+            {
+                ignore = 0;
+                break;
+            }
+        }
+
+        if ( ignore )
+        {
+            dprintk(XENLOG_WARNING VTDPREFIX,
+                "  Ignore the RMRR (%"PRIx64", %"PRIx64") due to "
+                "devices under its scope are not PCI discoverable!\n",
+                rmrru->base_address, rmrru->end_address);
+            xfree(rmrru);
+        }
+        else if ( base_addr > end_addr )
+        {
+            dprintk(XENLOG_WARNING VTDPREFIX,
+                "  The RMRR (%"PRIx64", %"PRIx64") is incorrect!\n",
+                rmrru->base_address, rmrru->end_address);
+            xfree(rmrru);
+            ret = -EFAULT;
+        }
+        else
+        {
+            dprintk(XENLOG_INFO VTDPREFIX,
+                "  RMRR region: base_addr %"PRIx64" end_address %"PRIx64"\n",
+                rmrru->base_address, rmrru->end_address);
+            acpi_register_rmrr_unit(rmrru);
+        }
+    }
+
     return ret;
 }
 
diff -r acd7d3f06d9a -r 961acb357740 xen/include/xen/pci.h
--- a/xen/include/xen/pci.h     Thu Jan 21 09:11:06 2010 +0000
+++ b/xen/include/xen/pci.h     Thu Jan 21 09:12:01 2010 +0000
@@ -74,6 +74,7 @@ enum {
     DEV_TYPE_PCI,
 };
 
+int pci_device_detect(u8 bus, u8 dev, u8 func);
 int scan_pci_devices(void);
 int pdev_type(u8 bus, u8 devfn);
 int find_upstream_bridge(u8 *bus, u8 *devfn, u8 *secbus);

_______________________________________________
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®.