[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |