commit 06d3104a1d029fe498dcb29fc71ef34c51116bf0 Author: Alex Williamson Date: Thu Aug 23 14:40:26 2012 -0600 intel-iommu: Add quirk for known broken devices Several devices have been found to break pci_find_upstream_pcie_bridge because they claim to be conventional PCI-to-PCI bridges, but are directly connected to upstream PCIe root ports. These are probably really PCIe-to-PCI bridges, but we don't know for certain and therefore don't know how to handle how they tag transactions from subordinate devices. Since we don't know that, disable VT-d support when these are found in the system. Signed-off-by: Alex Williamson diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 2297ec1..6ce9d9f 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4300,3 +4300,51 @@ static void __init check_tylersburg_isoch(void) printk(KERN_WARNING "DMAR: Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n", vtisochctrl); } + +static __devinit void quirk_bad_pcie_bridge(struct pci_dev *dev) +{ + struct acpi_table_header *header = NULL; + acpi_status status; + + if (no_iommu || dmar_disabled || !iommu_detected) + return; + + status = acpi_get_table(ACPI_SIG_DMAR, 0, &header); + if (!ACPI_SUCCESS(status)) + return; + + /* + * If we find a PCI-to-PCI bridge that's not on the root bus and + * connected upstream to a PCIe device that is not a PCIe-to-PCI + * bridge, it's probably actually a PCIe device. This will make + * pci_find_upstream_pcie_bridge() trigger a warning. We don't + * really know how to handle tagging on such devices, so we don't + * know how to program the IOMMU. Disable VT-d on systems with + * this broken hardware. See: + * + * https://bugzilla.kernel.org/show_bug.cgi?id=44881 + */ + if (!pci_is_pcie(dev) && dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && + !pci_is_root_bus(dev->bus) && pci_is_pcie(dev->bus->self) && + dev->bus->self->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { + + pr_info("Your hardware is broken, device %s claims to be a conventional PCI bridge device connected to an upstream PCIe device that is not a PCIe-to-PCI bridge. Disabling VT-d support on this system.\n", + pci_name(dev)); + dmar_disabled = 1; + + if (tboot_enabled()) + panic("tboot: VT-d cannot be enabled on this system\n"); + } +} + +/* + * The following devices are known to need this quirk: + * - ASMedia Technology Inc. Device 1080 (0x1b21, 0x1080) + * - Tundra Semiconductor Corp. Device 8113 (0x10e3, 0x8113) + * - Integrated Technology Express, Inc. Device 8892 (0x1283, 0x8892) + * + * We could probably call this on PCI_ANY_ID if we need to. + */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_bad_pcie_bridge); +DECLARE_PCI_FIXUP_HEADER(0x10e3, 0x8113, quirk_bad_pcie_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, 0x8892, quirk_bad_pcie_bridge);