aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iommu/amd_iommu_init.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index d06a6d9edbca..bf4959f4225b 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -1020,6 +1020,34 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
1020} 1020}
1021 1021
1022/* 1022/*
1023 * Family15h Model 30h-3fh (IOMMU Mishandles ATS Write Permission)
1024 * Workaround:
1025 * BIOS should enable ATS write permission check by setting
1026 * L2_DEBUG_3[AtsIgnoreIWDis](D0F2xF4_x47[0]) = 1b
1027 */
1028static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
1029{
1030 u32 value;
1031
1032 if ((boot_cpu_data.x86 != 0x15) ||
1033 (boot_cpu_data.x86_model < 0x30) ||
1034 (boot_cpu_data.x86_model > 0x3f))
1035 return;
1036
1037 /* Test L2_DEBUG_3[AtsIgnoreIWDis] == 1 */
1038 value = iommu_read_l2(iommu, 0x47);
1039
1040 if (value & BIT(0))
1041 return;
1042
1043 /* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */
1044 iommu_write_l2(iommu, 0x47, value | BIT(0));
1045
1046 pr_info("AMD-Vi: Applying ATS write check workaround for IOMMU at %s\n",
1047 dev_name(&iommu->dev->dev));
1048}
1049
1050/*
1023 * This function clues the initialization function for one IOMMU 1051 * This function clues the initialization function for one IOMMU
1024 * together and also allocates the command buffer and programs the 1052 * together and also allocates the command buffer and programs the
1025 * hardware. It does NOT enable the IOMMU. This is done afterwards. 1053 * hardware. It does NOT enable the IOMMU. This is done afterwards.
@@ -1288,6 +1316,7 @@ static int iommu_init_pci(struct amd_iommu *iommu)
1288 } 1316 }
1289 1317
1290 amd_iommu_erratum_746_workaround(iommu); 1318 amd_iommu_erratum_746_workaround(iommu);
1319 amd_iommu_ats_write_check_workaround(iommu);
1291 1320
1292 iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu, 1321 iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu,
1293 amd_iommu_groups, "ivhd%d", 1322 amd_iommu_groups, "ivhd%d",