diff options
-rw-r--r-- | xen/drivers/passthrough/vtd/iommu.c | 5 | ||||
-rw-r--r-- | xen/drivers/passthrough/vtd/quirks.c | 27 |
2 files changed, 32 insertions, 0 deletions
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index ef8bc95b72..0fc10de15b 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -2125,6 +2125,11 @@ int __init intel_vtd_setup(void) } platform_quirks_init(); + if ( !iommu_enable ) + { + ret = -ENODEV; + goto error; + } /* We enable the following features only if they are supported by all VT-d * engines: Snoop Control, DMA passthrough, Queued Invalidation and diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c index d79a155b28..6d839c08bf 100644 --- a/xen/drivers/passthrough/vtd/quirks.c +++ b/xen/drivers/passthrough/vtd/quirks.c @@ -244,6 +244,29 @@ void vtd_ops_postamble_quirk(struct iommu* iommu) } } +/* 5500/5520/X58 Chipset Interrupt remapping errata, for stepping B-3. + * Fixed in stepping C-2. */ +static void __init tylersburg_intremap_quirk(void) +{ + uint32_t bus, device; + uint8_t rev; + + for ( bus = 0; bus < 0x100; bus++ ) + { + /* Match on System Management Registers on Device 20 Function 0 */ + device = pci_conf_read32(0, bus, 20, 0, PCI_VENDOR_ID); + rev = pci_conf_read8(0, bus, 20, 0, PCI_REVISION_ID); + + if ( rev == 0x13 && device == 0x342e8086 ) + { + printk(XENLOG_WARNING VTDPREFIX + "Disabling IOMMU due to Intel 5500/5520/X58 Chipset errata #47, #53\n"); + iommu_enable = 0; + break; + } + } +} + /* initialize platform identification flags */ void __init platform_quirks_init(void) { @@ -264,6 +287,10 @@ void __init platform_quirks_init(void) /* ioremap IGD MMIO+0x2000 page */ map_igd_reg(); + + /* Tylersburg interrupt remap quirk */ + if ( iommu_intremap ) + tylersburg_intremap_quirk(); } /* |