Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'iommu-fixes-v3.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull IOMMU fix from Joerg Roedel:
"One fix for the AMD IOMMU driver to work around broken BIOSes found in
the field. Some BIOSes forget to enable a workaround for a hardware
problem which might cause the IOMMU to stop working under high load
conditions. The fix makes sure this workaround is enabled."

* tag 'iommu-fixes-v3.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
IOMMU, AMD Family15h Model10-1Fh erratum 746 Workaround

+34
+34
drivers/iommu/amd_iommu_init.c
··· 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 + */ 983 + static 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 1010 * This function clues the initialization function for one IOMMU 979 1011 * together and also allocates the command buffer and programs the 980 1012 * hardware. It does NOT enable the IOMMU. This is done afterwards. ··· 1203 1171 for (i = 0; i < 0x83; i++) 1204 1172 iommu->stored_l2[i] = iommu_read_l2(iommu, i); 1205 1173 } 1174 + 1175 + amd_iommu_erratum_746_workaround(iommu); 1206 1176 1207 1177 return pci_enable_device(iommu->dev); 1208 1178 }