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

Commit c2ff5cf5 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

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: default avatarAndrew Oakley <andrew@ado.is-a-geek.net>
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
parent ddffeb8c
Loading
Loading
Loading
Loading
+32 −7
Original line number Original line Diff line number Diff line
@@ -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)