mirror of
https://github.com/genesi/linux-legacy.git
synced 2026-09-23 15:14:12 +00:00
x86/amd-iommu: Workaround for erratum 63
commit c5cca146aa03e1f60fb179df65f0dbaf17bc64ed upstream. There is an erratum for IOMMU hardware which documents undefined behavior when forwarding SMI requests from peripherals and the DTE of that peripheral has a sysmgt value of 01b. This problem caused weird IO_PAGE_FAULTS in my case. This patch implements the suggested workaround for that erratum into the AMD IOMMU driver. The erratum is documented with number 63. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
c385d8d439
commit
6a3f97dfa2
@@ -30,6 +30,7 @@ extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
|
||||
extern void amd_iommu_flush_all_domains(void);
|
||||
extern void amd_iommu_flush_all_devices(void);
|
||||
extern void amd_iommu_shutdown(void);
|
||||
extern void amd_iommu_apply_erratum_63(u16 devid);
|
||||
#else
|
||||
static inline int amd_iommu_init(void) { return -ENODEV; }
|
||||
static inline void amd_iommu_detect(void) { }
|
||||
|
||||
@@ -1112,6 +1112,8 @@ static void __detach_device(struct protection_domain *domain, u16 devid)
|
||||
amd_iommu_dev_table[devid].data[1] = 0;
|
||||
amd_iommu_dev_table[devid].data[2] = 0;
|
||||
|
||||
amd_iommu_apply_erratum_63(devid);
|
||||
|
||||
/* decrease reference counter */
|
||||
domain->dev_cnt -= 1;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user