diff options
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 29 |
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 | */ | ||
1028 | static 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", |