aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/intel-iommu.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2010-07-23 18:47:56 -0400
committerDan Williams <dan.j.williams@intel.com>2010-08-04 17:18:17 -0400
commit556ab45f9a775bfa4762bacc0a4afb5b44b067bc (patch)
tree6caf3f7c72617d50d78c4197b872fd0a22b18c99 /drivers/pci/intel-iommu.c
parent128f904ac87cb6e63921e80f378fdf9ba532c0f6 (diff)
ioat2: catch and recover from broken vtd configurations v6
On some platforms (MacPro3,1) the BIOS assigns the ioatdma device to the incorrect iommu causing faults when the driver initializes. Add a quirk to catch this misconfiguration and try falling back to untranslated operation (which works in the MacPro3,1 case). Assuming there are other platforms with misconfigured iommus teach the ioatdma driver to treat initialization failures as non-fatal (just fail the driver load and emit a warning instead of triggering a BUG_ON). This can be classified as a boot regression since 2.6.32 on affected platforms since the ioatdma module did not autoload prior to that kernel. Cc: <stable@kernel.org> Acked-by: David Woodhouse <David.Woodhouse@intel.com> Reported-by: Chris Li <lkml@chrisli.org> Tested-by: Chris Li <lkml@chrisli.org> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r--drivers/pci/intel-iommu.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 796828fce34c..90938c7a74c1 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -3029,6 +3029,34 @@ static void __init iommu_exit_mempool(void)
3029 3029
3030} 3030}
3031 3031
3032static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3033{
3034 struct dmar_drhd_unit *drhd;
3035 u32 vtbar;
3036 int rc;
3037
3038 /* We know that this device on this chipset has its own IOMMU.
3039 * If we find it under a different IOMMU, then the BIOS is lying
3040 * to us. Hope that the IOMMU for this device is actually
3041 * disabled, and it needs no translation...
3042 */
3043 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3044 if (rc) {
3045 /* "can't" happen */
3046 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3047 return;
3048 }
3049 vtbar &= 0xffff0000;
3050
3051 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3052 drhd = dmar_find_matched_drhd_unit(pdev);
3053 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3054 TAINT_FIRMWARE_WORKAROUND,
3055 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3056 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3057}
3058DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3059
3032static void __init init_no_remapping_devices(void) 3060static void __init init_no_remapping_devices(void)
3033{ 3061{
3034 struct dmar_drhd_unit *drhd; 3062 struct dmar_drhd_unit *drhd;