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 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 | ||
3032 | static 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 | } | ||
3058 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); | ||
3059 | |||
3032 | static void __init init_no_remapping_devices(void) | 3060 | static void __init init_no_remapping_devices(void) |
3033 | { | 3061 | { |
3034 | struct dmar_drhd_unit *drhd; | 3062 | struct dmar_drhd_unit *drhd; |