Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae2c3d95 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 325a86b6 318fe782
Loading
Loading
Loading
Loading
+34 −0
Original line number Original line Diff line number Diff line
@@ -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
 * This function clues the initialization function for one IOMMU
 * together and also allocates the command buffer and programs the
 * 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);
			iommu->stored_l2[i] = iommu_read_l2(iommu, i);
	}
	}


	amd_iommu_erratum_746_workaround(iommu);

	return pci_enable_device(iommu->dev);
	return pci_enable_device(iommu->dev);
}
}