|
@@ -1019,6 +1019,34 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
|
|
|
pci_write_config_dword(iommu->dev, 0xf0, 0x90);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Family15h Model 30h-3fh (IOMMU Mishandles ATS Write Permission)
|
|
|
+ * Workaround:
|
|
|
+ * BIOS should enable ATS write permission check by setting
|
|
|
+ * L2_DEBUG_3[AtsIgnoreIWDis](D0F2xF4_x47[0]) = 1b
|
|
|
+ */
|
|
|
+static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
|
|
|
+{
|
|
|
+ u32 value;
|
|
|
+
|
|
|
+ if ((boot_cpu_data.x86 != 0x15) ||
|
|
|
+ (boot_cpu_data.x86_model < 0x30) ||
|
|
|
+ (boot_cpu_data.x86_model > 0x3f))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* Test L2_DEBUG_3[AtsIgnoreIWDis] == 1 */
|
|
|
+ value = iommu_read_l2(iommu, 0x47);
|
|
|
+
|
|
|
+ if (value & BIT(0))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */
|
|
|
+ iommu_write_l2(iommu, 0x47, value | BIT(0));
|
|
|
+
|
|
|
+ pr_info("AMD-Vi: Applying ATS write check workaround for IOMMU at %s\n",
|
|
|
+ dev_name(&iommu->dev->dev));
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* This function clues the initialization function for one IOMMU
|
|
|
* together and also allocates the command buffer and programs the
|
|
@@ -1288,6 +1316,7 @@ static int iommu_init_pci(struct amd_iommu *iommu)
|
|
|
}
|
|
|
|
|
|
amd_iommu_erratum_746_workaround(iommu);
|
|
|
+ amd_iommu_ats_write_check_workaround(iommu);
|
|
|
|
|
|
iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu,
|
|
|
amd_iommu_groups, "ivhd%d",
|