IOMMU fixes for Linux v3.8-rc5

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.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJRBpTXAAoJECvwRC2XARrjGDUQAKsNxpN2iD0BEvVUqCzTR7ha
 BTwxwKnMwxBr0vZZZzCCT9JnNXcPKKfJYLEWqW5QE7m/qlvYiBxS8Cg8uAfGVw0n
 y/y/SQPww7jeImyOCvAN9Axl+SZ8sHmKJTmS4343+CqpQ1e6PilC4WV5ogmOz/Gy
 nc9bj9rJGIMEP76bCYY7rMz7xVOaHmIOE+XcEA8TTj37AOk8t9PTUqLno+APTqWd
 X3jhgjRTQuisCiy+sTiGllXoa+CdH7+gmDOvd4S8CRzrhIznPDNI+x7UNfq8n5A0
 KBqwUEzeQ5fyqqopJQaSaK8+6eTZ8dUxcfpqjyD/sxe7dLY0V+1KBNcNZrOolz/w
 juLbV+dTfSJcaJHjjvh1NEqvN4ky/6zuNF50KexaL0DSqpUkPf62heXd+P60l5DE
 Tj+h3d8xX/mI1Ap2q14/4Bggvpdz3I+GPWnmyISOI7ZklxB0DlYeQiY+ZYDdO5Bl
 4aNvCRRRPEG6TsZzkJR60+iSjUnGEN7PSdrDkFymvmG0U0hH73xcy5Xc4Z3mRffx
 HNyK4uAnUNIgPzdZA2K9uctGLOj14Z1n/iREc2FhrGhPeyoaMhXMyWPbTVCQ0Fdx
 7cV6sBzuh/RzFD/S8r+VHP4umRg8uf2+22FaAVOaOD1wtO5ug9WAZQ+nqwcOTHNc
 YVO8wlC8XyybzM2+Xb7E
 =X83i
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2013-01-28 11:52:56 -08:00
commit ae2c3d95fa

View file

@ -974,6 +974,38 @@ static void __init free_iommu_all(void)
}
}
/*
* Family15h Model 10h-1fh erratum 746 (IOMMU Logging May Stall Translations)
* Workaround:
* BIOS should disable L2B micellaneous clock gating by setting
* L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b
*/
static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
{
u32 value;
if ((boot_cpu_data.x86 != 0x15) ||
(boot_cpu_data.x86_model < 0x10) ||
(boot_cpu_data.x86_model > 0x1f))
return;
pci_write_config_dword(iommu->dev, 0xf0, 0x90);
pci_read_config_dword(iommu->dev, 0xf4, &value);
if (value & BIT(2))
return;
/* Select NB indirect register 0x90 and enable writing */
pci_write_config_dword(iommu->dev, 0xf0, 0x90 | (1 << 8));
pci_write_config_dword(iommu->dev, 0xf4, value | 0x4);
pr_info("AMD-Vi: Applying erratum 746 workaround for IOMMU at %s\n",
dev_name(&iommu->dev->dev));
/* Clear the enable writing bit */
pci_write_config_dword(iommu->dev, 0xf0, 0x90);
}
/*
* This function clues the initialization function for one IOMMU
* together and also allocates the command buffer and programs the
@ -1172,6 +1204,8 @@ static int iommu_init_pci(struct amd_iommu *iommu)
iommu->stored_l2[i] = iommu_read_l2(iommu, i);
}
amd_iommu_erratum_746_workaround(iommu);
return pci_enable_device(iommu->dev);
}