diff options
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 6a5af18faf68..b0de57947189 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -3030,6 +3030,34 @@ static void __init iommu_exit_mempool(void) | |||
3030 | 3030 | ||
3031 | } | 3031 | } |
3032 | 3032 | ||
3033 | static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev) | ||
3034 | { | ||
3035 | struct dmar_drhd_unit *drhd; | ||
3036 | u32 vtbar; | ||
3037 | int rc; | ||
3038 | |||
3039 | /* We know that this device on this chipset has its own IOMMU. | ||
3040 | * If we find it under a different IOMMU, then the BIOS is lying | ||
3041 | * to us. Hope that the IOMMU for this device is actually | ||
3042 | * disabled, and it needs no translation... | ||
3043 | */ | ||
3044 | rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar); | ||
3045 | if (rc) { | ||
3046 | /* "can't" happen */ | ||
3047 | dev_info(&pdev->dev, "failed to run vt-d quirk\n"); | ||
3048 | return; | ||
3049 | } | ||
3050 | vtbar &= 0xffff0000; | ||
3051 | |||
3052 | /* we know that the this iommu should be at offset 0xa000 from vtbar */ | ||
3053 | drhd = dmar_find_matched_drhd_unit(pdev); | ||
3054 | if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000, | ||
3055 | TAINT_FIRMWARE_WORKAROUND, | ||
3056 | "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n")) | ||
3057 | pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; | ||
3058 | } | ||
3059 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); | ||
3060 | |||
3033 | static void __init init_no_remapping_devices(void) | 3061 | static void __init init_no_remapping_devices(void) |
3034 | { | 3062 | { |
3035 | struct dmar_drhd_unit *drhd; | 3063 | struct dmar_drhd_unit *drhd; |