aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>2013-01-24 14:17:53 -0500
committerJoerg Roedel <joro@8bytes.org>2013-01-28 09:26:54 -0500
commit318fe782539c4150d1b8e4e6c9dc3a896512cb8a (patch)
tree781f37f1e4f8f4e7523b363d6e58194f831e381c /drivers
parent949db153b6466c6f7cad5a427ecea94985927311 (diff)
IOMMU, AMD Family15h Model10-1Fh erratum 746 Workaround
The IOMMU may stop processing page translations due to a perceived lack of credits for writing upstream peripheral page service request (PPR) or event logs. If the L2B miscellaneous clock gating feature is enabled the IOMMU does not properly register credits after the log request has completed, leading to a potential system hang. BIOSes are supposed to disable L2B micellaneous clock gating by setting L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b. This patch corrects that for those which do not enable this workaround. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Acked-by: Borislav Petkov <bp@suse.de> Cc: stable@vger.kernel.org Signed-off-by: Joerg Roedel <joro@8bytes.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/amd_iommu_init.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 81837b0710a9..faf10ba1ed9a 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -975,6 +975,38 @@ static void __init free_iommu_all(void)
975} 975}
976 976
977/* 977/*
978 * Family15h Model 10h-1fh erratum 746 (IOMMU Logging May Stall Translations)
979 * Workaround:
980 * BIOS should disable L2B micellaneous clock gating by setting
981 * L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b
982 */
983static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
984{
985 u32 value;
986
987 if ((boot_cpu_data.x86 != 0x15) ||
988 (boot_cpu_data.x86_model < 0x10) ||
989 (boot_cpu_data.x86_model > 0x1f))
990 return;
991
992 pci_write_config_dword(iommu->dev, 0xf0, 0x90);
993 pci_read_config_dword(iommu->dev, 0xf4, &value);
994
995 if (value & BIT(2))
996 return;
997
998 /* Select NB indirect register 0x90 and enable writing */
999 pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8));
1000
1001 pci_write_config_dword(iommu->dev, 0xf4, value | 0x4);
1002 pr_info("AMD-Vi: Applying erratum 746 workaround for IOMMU at %s\n",
1003 dev_name(&iommu->dev->dev));
1004
1005 /* Clear the enable writing bit */
1006 pci_write_config_dword(iommu->dev, 0xf0, 0x90);
1007}
1008
1009/*
978 * This function clues the initialization function for one IOMMU 1010 * This function clues the initialization function for one IOMMU
979 * together and also allocates the command buffer and programs the 1011 * together and also allocates the command buffer and programs the
980 * hardware. It does NOT enable the IOMMU. This is done afterwards. 1012 * hardware. It does NOT enable the IOMMU. This is done afterwards.
@@ -1172,6 +1204,8 @@ static int iommu_init_pci(struct amd_iommu *iommu)
1172 iommu->stored_l2[i] = iommu_read_l2(iommu, i); 1204 iommu->stored_l2[i] = iommu_read_l2(iommu, i);
1173 } 1205 }
1174 1206
1207 amd_iommu_erratum_746_workaround(iommu);
1208
1175 return pci_enable_device(iommu->dev); 1209 return pci_enable_device(iommu->dev);
1176} 1210}
1177 1211