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

[Xen-devel] [PATCH v2] pci: apply workaround for Intel errata HSE43 and BDF2



This errata affect the values read from the BAR registers, and could
render vPCI (and by extension PVH Dom0 unusable).

HSE43 is a Haswell erratum where a non-BAR register is implemented at
the position where the first BAR of the device should be found in a
Power Control Unit device. Note that there are no BARs on this device,
apart from the bogus CSR register positioned on top of the first BAR.

BDF2/BDX2 is a Broadwell erratum where BARs in the Home Agent device
will return bogus non-zero values.

In both cases the solution is to treat such devices as having no BARs
in the vPCI code.

Reported-by: Jan Beulich <jbeulich@xxxxxxxx>
Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Cc: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Cc: Julien Grall <julien.grall@xxxxxxx>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>
Cc: Tim Deegan <tim@xxxxxxx>
Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
---
Some testing would be nice has I don't seem to have any box ATM that
contains this errata.
---
Changes since v1:
 - Fix wording in the description and reference BDX2 erratum.
 - Use a tuple array to store the list of affected devices.
 - Return early from init_bars if BARs are ignored.
 - Move position of the ignore_bars field in the pci_dev struct.
---
 xen/drivers/passthrough/pci.c | 41 +++++++++++++++++++++++++++++++++++
 xen/drivers/vpci/header.c     |  3 +++
 xen/include/xen/pci.h         |  3 +++
 3 files changed, 47 insertions(+)

diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 7584ce2fbb..c24d5875b9 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -17,6 +17,7 @@
 #include <xen/sched.h>
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
+#include <xen/pci_ids.h>
 #include <xen/list.h>
 #include <xen/prefetch.h>
 #include <xen/iommu.h>
@@ -298,6 +299,45 @@ static void check_pdev(const struct pci_dev *pdev)
 #undef PCI_STATUS_CHECK
 }
 
+static void apply_quirks(struct pci_dev *pdev)
+{
+    uint16_t vendor = pci_conf_read16(pdev->seg, pdev->bus,
+                                      PCI_SLOT(pdev->devfn),
+                                      PCI_FUNC(pdev->devfn), PCI_VENDOR_ID);
+    uint16_t device = pci_conf_read16(pdev->seg, pdev->bus,
+                                      PCI_SLOT(pdev->devfn),
+                                      PCI_FUNC(pdev->devfn), PCI_DEVICE_ID);
+    const static struct {
+        uint16_t vendor, device;
+    } quirks[] = {
+        /*
+         * Device [8086:2fc0]
+         * Erratum HSE43
+         * CONFIG_TDP_NOMINAL CSR Implemented at Incorrect Offset
+         * 
http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v3-spec-update.html
+         */
+        { PCI_VENDOR_ID_INTEL, 0x2fc0 },
+        /*
+         * Devices [8086:6f60,6fa0,6fc0]
+         * Erratum BDF2
+         * PCI BARs in the Home Agent Will Return Non-Zero Values During 
Enumeration
+         * 
http://www.intel.com/content/www/us/en/processors/xeon/xeon-e5-v4-spec-update.html
+        */
+        { PCI_VENDOR_ID_INTEL, 0x6f60 },
+        { PCI_VENDOR_ID_INTEL, 0x6fa0 },
+        { PCI_VENDOR_ID_INTEL, 0x6fc0 },
+    };
+    unsigned int i;
+
+    for ( i = 0; i < ARRAY_SIZE(quirks); i++)
+        if ( vendor == quirks[i].vendor && device == quirks[i].device )
+            /*
+             * For both erratas force ignoring the BARs, this prevents vPCI
+             * from trying to size the BARs or add handlers to trap accesses.
+             */
+            pdev->ignore_bars = true;
+}
+
 static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn)
 {
     struct pci_dev *pdev;
@@ -397,6 +437,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 
bus, u8 devfn)
     }
 
     check_pdev(pdev);
+    apply_quirks(pdev);
 
     return pdev;
 }
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index 43cac3f7d3..106e8af8b2 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -486,6 +486,9 @@ static int init_bars(struct pci_dev *pdev)
     if ( rc )
         return rc;
 
+    if ( pdev->ignore_bars )
+        return 0;
+
     /* Disable memory decoding before sizing. */
     cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND);
     if ( cmd & PCI_COMMAND_MEMORY )
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 3c361cf0c0..a934662713 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -88,6 +88,9 @@ struct pci_dev {
 
     nodeid_t node; /* NUMA node */
 
+    /* Device with errata, ignore the BARs. */
+    bool ignore_bars;
+
     enum pdev_type {
         DEV_TYPE_PCI_UNKNOWN,
         DEV_TYPE_PCIe_ENDPOINT,
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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