iommu/amd: Work around wrong IOAPIC device-id in IVRS table
On some systems the BIOS puts the wrong device-id for the IO-APIC into the IVRS table. The result is that interrupt remapping is not working for the IO-APIC irqs. This usually means a kernel panic at boot because the timer is not working. Fix this kernel panic by disabling interrupt remapping if this problem is discovered in the IVRS table. Reported-by: Andrew Oakley <andrew@ado.is-a-geek.net> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
ddffeb8c4d
commit
c2ff5cf529
|
@ -1599,21 +1599,46 @@ static void __init free_on_init_error(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SB IOAPIC is always on this device in AMD systems */
|
||||||
|
#define IOAPIC_SB_DEVID ((0x00 << 8) | PCI_DEVFN(0x14, 0))
|
||||||
|
|
||||||
static bool __init check_ioapic_information(void)
|
static bool __init check_ioapic_information(void)
|
||||||
{
|
{
|
||||||
|
bool ret, has_sb_ioapic;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
|
has_sb_ioapic = false;
|
||||||
|
ret = false;
|
||||||
|
|
||||||
for (idx = 0; idx < nr_ioapics; idx++) {
|
for (idx = 0; idx < nr_ioapics; idx++) {
|
||||||
int id = mpc_ioapic_id(idx);
|
int devid, id = mpc_ioapic_id(idx);
|
||||||
|
|
||||||
if (get_ioapic_devid(id) < 0) {
|
devid = get_ioapic_devid(id);
|
||||||
pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id);
|
if (devid < 0) {
|
||||||
pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n");
|
pr_err(FW_BUG "AMD-Vi: IOAPIC[%d] not in IVRS table\n", id);
|
||||||
return false;
|
ret = false;
|
||||||
|
} else if (devid == IOAPIC_SB_DEVID) {
|
||||||
|
has_sb_ioapic = true;
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
if (!has_sb_ioapic) {
|
||||||
|
/*
|
||||||
|
* We expect the SB IOAPIC to be listed in the IVRS
|
||||||
|
* table. The system timer is connected to the SB IOAPIC
|
||||||
|
* and if we don't have it in the list the system will
|
||||||
|
* panic at boot time. This situation usually happens
|
||||||
|
* when the BIOS is buggy and provides us the wrong
|
||||||
|
* device id for the IOAPIC in the system.
|
||||||
|
*/
|
||||||
|
pr_err(FW_BUG "AMD-Vi: No southbridge IOAPIC found in IVRS table\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug(s)\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init free_dma_resources(void)
|
static void __init free_dma_resources(void)
|
||||||
|
|
Loading…
Reference in a new issue