xen/535a34eb-VT-d-suppress-UR-signaling-for-server-chipsets.patch
Charles Arnold 3c2f525a91 - fate#316613: Implement pvscsi in xl/libxl
libxl.pvscsi.patch

- bnc#875668 - VUL-0: CVE-2014-3124: xen: XSA-92:
  HVMOP_set_mem_type allows invalid P2M entries to be created
  535fa503-x86-HVM-restrict-HVMOP_set_mem_type.patch (replaces xsa92.patch)
- bnc#826717 - VUL-0: CVE-2013-3495: XSA-59: xen: Intel VT-d
  Interrupt Remapping engines can be evaded by native NMI interrupts
  535a34eb-VT-d-suppress-UR-signaling-for-server-chipsets.patch
  535a3516-VT-d-suppress-UR-signaling-for-desktop-chipsets.patch
- Upstream patches from Jan
  535a354b-passthrough-allow-to-suppress-SERR-and-PERR-signaling.patch
  535e31bc-x86-HVM-correct-the-SMEP-logic-for-HVM_CR0_GUEST_RESERVED_BITS.patch
  53636978-hvm_set_ioreq_page-releases-wrong-page-in-error-path.patch
  53636ebf-x86-fix-guest-CPUID-handling.patch

- Fix pygrub to handle VM with no grub/menu.lst file.
- Don't use /var/run/xend/boot for temporary boot directory
  pygrub-boot-legacy-sles.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=314
2014-05-13 17:13:17 +00:00

216 lines
7.9 KiB
Diff

References: bnc#826717 CVE-2013-3495 XSA-59
# Commit d061d200eb92bcb1d86f9b55c6de73e35ce63fdf
# Date 2014-04-25 12:11:55 +0200
# Author Jan Beulich <jbeulich@suse.com>
# Committer Jan Beulich <jbeulich@suse.com>
VT-d: suppress UR signaling for server chipsets
Unsupported Requests can be signaled for malformed writes to the MSI
address region, e.g. due to buggy or malicious DMA set up to that
region. These should normally result in IOMMU faults, but don't on
the server chipsets dealt with here.
IDs 0xe00, 0xe01, and 0xe04 ... 0xe0b (Ivytown) aren't needed here -
Intel confirmed the issue to be fixed in hardware there.
This is CVE-2013-3495 / XSA-59.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Don Dugger <donald.d.dugger@intel.com>
Acked-by: Tim Deegan <tim@xen.org>
Acked-by: Xiantao Zhang <xiantao.zhang@intel.com>
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -27,6 +27,7 @@
#include <xen/softirq.h>
#include <xen/time.h>
#include <xen/pci.h>
+#include <xen/pci_ids.h>
#include <xen/pci_regs.h>
#include <xen/keyhandler.h>
#include <asm/msi.h>
@@ -390,12 +391,68 @@ void __init pci_vtd_quirk(struct pci_dev
int bus = pdev->bus;
int dev = PCI_SLOT(pdev->devfn);
int func = PCI_FUNC(pdev->devfn);
- int id, val;
+ int pos;
+ u32 val;
- id = pci_conf_read32(seg, bus, dev, func, 0);
- if ( id == 0x342e8086 || id == 0x3c288086 )
+ if ( pci_conf_read16(seg, bus, dev, func, PCI_VENDOR_ID) !=
+ PCI_VENDOR_ID_INTEL )
+ return;
+
+ switch ( pci_conf_read16(seg, bus, dev, func, PCI_DEVICE_ID) )
{
+ case 0x342e: /* Tylersburg chipset (Nehalem / Westmere systems) */
+ case 0x3c28: /* Sandybridge */
val = pci_conf_read32(seg, bus, dev, func, 0x1AC);
pci_conf_write32(seg, bus, dev, func, 0x1AC, val | (1 << 31));
+ break;
+
+ /* Tylersburg (EP)/Boxboro (MP) chipsets (NHM-EP/EX, WSM-EP/EX) */
+ case 0x3400 ... 0x3407: /* host bridges */
+ case 0x3408 ... 0x3411: case 0x3420 ... 0x3421: /* root ports */
+ /* JasperForest (Intel Xeon Processor C5500/C3500 */
+ case 0x3700 ... 0x370f: /* host bridges */
+ case 0x3720 ... 0x3724: /* root ports */
+ /* Sandybridge-EP (Romley) */
+ case 0x3c00: /* host bridge */
+ case 0x3c01 ... 0x3c0b: /* root ports */
+ pos = pci_find_ext_capability(seg, bus, pdev->devfn,
+ PCI_EXT_CAP_ID_ERR);
+ if ( !pos )
+ {
+ pos = pci_find_ext_capability(seg, bus, pdev->devfn,
+ PCI_EXT_CAP_ID_VNDR);
+ while ( pos )
+ {
+ val = pci_conf_read32(seg, bus, dev, func, pos + PCI_VNDR_HEADER);
+ if ( PCI_VNDR_HEADER_ID(val) == 4 && PCI_VNDR_HEADER_REV(val) == 1 )
+ {
+ pos += PCI_VNDR_HEADER;
+ break;
+ }
+ pos = pci_find_next_ext_capability(seg, bus, pdev->devfn, pos,
+ PCI_EXT_CAP_ID_VNDR);
+ }
+ }
+ if ( !pos )
+ {
+ printk(XENLOG_WARNING "%04x:%02x:%02x.%u without AER capability?\n",
+ seg, bus, dev, func);
+ break;
+ }
+
+ val = pci_conf_read32(seg, bus, dev, func, pos + PCI_ERR_UNCOR_MASK);
+ pci_conf_write32(seg, bus, dev, func, pos + PCI_ERR_UNCOR_MASK,
+ val | PCI_ERR_UNC_UNSUP);
+ val = pci_conf_read32(seg, bus, dev, func, pos + PCI_ERR_COR_MASK);
+ pci_conf_write32(seg, bus, dev, func, pos + PCI_ERR_COR_MASK,
+ val | PCI_ERR_COR_ADV_NFAT);
+
+ /* XPUNCERRMSK Send Completion with Unsupported Request */
+ val = pci_conf_read32(seg, bus, dev, func, 0x20c);
+ pci_conf_write32(seg, bus, dev, func, 0x20c, val | (1 << 4));
+
+ printk(XENLOG_INFO "Masked UR signaling on %04x:%02x:%02x.%u\n",
+ seg, bus, dev, func);
+ break;
}
}
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -66,23 +66,33 @@ int pci_find_next_cap(u16 seg, u8 bus, u
/**
* pci_find_ext_capability - Find an extended capability
- * @dev: PCI device to query
+ * @seg/@bus/@devfn: PCI device to query
* @cap: capability code
*
* Returns the address of the requested extended capability structure
* within the device's PCI configuration space or 0 if the device does
- * not support it. Possible values for @cap:
- *
- * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
- * %PCI_EXT_CAP_ID_VC Virtual Channel
- * %PCI_EXT_CAP_ID_DSN Device Serial Number
- * %PCI_EXT_CAP_ID_PWR Power Budgeting
+ * not support it.
*/
int pci_find_ext_capability(int seg, int bus, int devfn, int cap)
{
+ return pci_find_next_ext_capability(seg, bus, devfn, 0, cap);
+}
+
+/**
+ * pci_find_next_ext_capability - Find another extended capability
+ * @seg/@bus/@devfn: PCI device to query
+ * @pos: starting position
+ * @cap: capability code
+ *
+ * Returns the address of the requested extended capability structure
+ * within the device's PCI configuration space or 0 if the device does
+ * not support it.
+ */
+int pci_find_next_ext_capability(int seg, int bus, int devfn, int start, int cap)
+{
u32 header;
int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
- int pos = 0x100;
+ int pos = max(start, 0x100);
header = pci_conf_read32(seg, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
@@ -92,9 +102,10 @@ int pci_find_ext_capability(int seg, int
*/
if ( (header == 0) || (header == -1) )
return 0;
+ ASSERT(start != pos || PCI_EXT_CAP_ID(header) == cap);
while ( ttl-- > 0 ) {
- if ( PCI_EXT_CAP_ID(header) == cap )
+ if ( PCI_EXT_CAP_ID(header) == cap && pos != start )
return pos;
pos = PCI_EXT_CAP_NEXT(header);
if ( pos < 0x100 )
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -140,6 +140,7 @@ int pci_mmcfg_write(unsigned int seg, un
int pci_find_cap_offset(u16 seg, u8 bus, u8 dev, u8 func, u8 cap);
int pci_find_next_cap(u16 seg, u8 bus, unsigned int devfn, u8 pos, int cap);
int pci_find_ext_capability(int seg, int bus, int devfn, int cap);
+int pci_find_next_ext_capability(int seg, int bus, int devfn, int pos, int cap);
const char *parse_pci(const char *, unsigned int *seg, unsigned int *bus,
unsigned int *dev, unsigned int *func);
--- /dev/null
+++ b/xen/include/xen/pci_ids.h
@@ -0,0 +1,9 @@
+#define PCI_VENDOR_ID_AMD 0x1022
+
+#define PCI_VENDOR_ID_NVIDIA 0x10de
+
+#define PCI_VENDOR_ID_OXSEMI 0x1415
+
+#define PCI_VENDOR_ID_BROADCOM 0x14e4
+
+#define PCI_VENDOR_ID_INTEL 0x8086
--- a/xen/include/xen/pci_regs.h
+++ b/xen/include/xen/pci_regs.h
@@ -431,6 +431,7 @@
#define PCI_EXT_CAP_ID_VC 2
#define PCI_EXT_CAP_ID_DSN 3
#define PCI_EXT_CAP_ID_PWR 4
+#define PCI_EXT_CAP_ID_VNDR 11
#define PCI_EXT_CAP_ID_ACS 13
#define PCI_EXT_CAP_ID_ARI 14
#define PCI_EXT_CAP_ID_ATS 15
@@ -459,6 +460,7 @@
#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
+#define PCI_ERR_COR_ADV_NFAT 0x00002000 /* Advisory Non-Fatal */
#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
/* Same bits as above */
#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */
@@ -510,6 +512,12 @@
#define PCI_PWR_CAP 12 /* Capability */
#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
+/* Vendor-Specific (VSEC, PCI_EXT_CAP_ID_VNDR) */
+#define PCI_VNDR_HEADER 4 /* Vendor-Specific Header */
+#define PCI_VNDR_HEADER_ID(x) ((x) & 0xffff)
+#define PCI_VNDR_HEADER_REV(x) (((x) >> 16) & 0xf)
+#define PCI_VNDR_HEADER_LEN(x) (((x) >> 20) & 0xfff)
+
/*
* Hypertransport sub capability types
*