3c2f525a91
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
216 lines
7.9 KiB
Diff
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
|
|
*
|