@@ -508,7 +508,8 @@ EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
{
- if (isa_irq < NR_IRQS_LEGACY) {
+ if (isa_irq < NR_IRQS_LEGACY &&
+ isa_irq_to_gsi[isa_irq] != ACPI_INVALID_GSI) {
*gsi = isa_irq_to_gsi[isa_irq];
return 0;
}
@@ -913,6 +914,13 @@ static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
mp_save_irq(&mp_irq);
+ /*
+ * Reset default identity mapping if gsi is also an legacy IRQ,
+ * otherwise there will be more than one entry with the same GSI
+ * and acpi_isa_irq_to_gsi() may give wrong result.
+ */
+ if (gsi < NR_IRQS_LEGACY && isa_irq_to_gsi[gsi] == gsi)
+ isa_irq_to_gsi[gsi] = ACPI_INVALID_GSI;
isa_irq_to_gsi[bus_irq] = gsi;
}
A default identity mapping between GSI and IRQ is built for legacy IRQs. So when overriding the default identity mapping for legacy IRQs, we should also invalidate isa_irq_to_gsi[gsi] when setting isa_irq_to_gsi[irq] = gsi. Otherwise there may be two entries with the same GSI in the isa_irq_to_gsi array, and acpi_isa_irq_to_gsi() may give wrong result. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> --- arch/x86/kernel/acpi/boot.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)