|
@@ -509,6 +509,26 @@ static void set_dev_entry_bit(u16 devid, u8 bit)
|
|
|
amd_iommu_dev_table[devid].data[i] |= (1 << _bit);
|
|
|
}
|
|
|
|
|
|
+static int get_dev_entry_bit(u16 devid, u8 bit)
|
|
|
+{
|
|
|
+ int i = (bit >> 5) & 0x07;
|
|
|
+ int _bit = bit & 0x1f;
|
|
|
+
|
|
|
+ return (amd_iommu_dev_table[devid].data[i] & (1 << _bit)) >> _bit;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void amd_iommu_apply_erratum_63(u16 devid)
|
|
|
+{
|
|
|
+ int sysmgt;
|
|
|
+
|
|
|
+ sysmgt = get_dev_entry_bit(devid, DEV_ENTRY_SYSMGT1) |
|
|
|
+ (get_dev_entry_bit(devid, DEV_ENTRY_SYSMGT2) << 1);
|
|
|
+
|
|
|
+ if (sysmgt == 0x01)
|
|
|
+ set_dev_entry_bit(devid, DEV_ENTRY_IW);
|
|
|
+}
|
|
|
+
|
|
|
/* Writes the specific IOMMU for a device into the rlookup table */
|
|
|
static void __init set_iommu_for_device(struct amd_iommu *iommu, u16 devid)
|
|
|
{
|
|
@@ -537,6 +557,8 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
|
|
|
if (flags & ACPI_DEVFLAG_LINT1)
|
|
|
set_dev_entry_bit(devid, DEV_ENTRY_LINT1_PASS);
|
|
|
|
|
|
+ amd_iommu_apply_erratum_63(devid);
|
|
|
+
|
|
|
set_iommu_for_device(iommu, devid);
|
|
|
}
|
|
|
|