mirror of
https://abf.rosa.ru/djam/kernel-xen.git
synced 2025-02-23 07:42:46 +00:00
173 lines
5.5 KiB
Diff
173 lines
5.5 KiB
Diff
![]() |
From: Eric W. Biederman <ebiederm@xmission.com>
|
||
|
Subject: x86: Fix out of order of gsi
|
||
|
References: bnc#569050
|
||
|
Patch-Mainline: yes (x86-tip)
|
||
|
Commit-ID: fad539956c9e69749a03f7817d22d1bab87657bf
|
||
|
|
||
|
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||
|
|
||
|
Iranna D Ankad reported that IBM x3950 systems have boot
|
||
|
problems after this commit:
|
||
|
|
||
|
|
|
||
|
| commit b9c61b70075c87a8612624736faf4a2de5b1ed30
|
||
|
|
|
||
|
| x86/pci: update pirq_enable_irq() to setup io apic routing
|
||
|
|
|
||
|
|
||
|
The problem is that with the patch, the machine freezes when
|
||
|
console=ttyS0,... kernel serial parameter is passed.
|
||
|
|
||
|
It seem to freeze at DVD initialization and the whole problem
|
||
|
seem to be DVD/pata related, but somehow exposed through the
|
||
|
serial parameter.
|
||
|
|
||
|
Such apic problems can expose really weird behavior:
|
||
|
|
||
|
ACPI: IOAPIC (id[0x10] address[0xfecff000] gsi_base[0])
|
||
|
IOAPIC[0]: apic_id 16, version 0, address 0xfecff000, GSI 0-2
|
||
|
ACPI: IOAPIC (id[0x0f] address[0xfec00000] gsi_base[3])
|
||
|
IOAPIC[1]: apic_id 15, version 0, address 0xfec00000, GSI 3-38
|
||
|
ACPI: IOAPIC (id[0x0e] address[0xfec01000] gsi_base[39])
|
||
|
IOAPIC[2]: apic_id 14, version 0, address 0xfec01000, GSI 39-74
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 1 global_irq 4 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 5 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 3 global_irq 6 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 4 global_irq 7 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 6 global_irq 9 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 7 global_irq 10 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 8 global_irq 11 low edge)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 12 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 12 global_irq 15 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 13 global_irq 16 dfl dfl)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 14 global_irq 17 low edge)
|
||
|
ACPI: INT_SRC_OVR (bus 0 bus_irq 15 global_irq 18 dfl dfl)
|
||
|
|
||
|
It turns out that the system has three io apic controllers, but
|
||
|
boot ioapic routing is in the second one, and that gsi_base is
|
||
|
not 0 - it is using a bunch of INT_SRC_OVR...
|
||
|
|
||
|
So these recent changes:
|
||
|
|
||
|
1. one set routing for first io apic controller
|
||
|
2. assume irq = gsi
|
||
|
|
||
|
... will break that system.
|
||
|
|
||
|
So try to remap those gsis, need to seperate boot_ioapic_idx
|
||
|
detection out of enable_IO_APIC() and call them early.
|
||
|
|
||
|
So introduce boot_ioapic_idx, and remap_ioapic_gsi()...
|
||
|
|
||
|
-v2: shift gsi with delta instead of gsi_base of boot_ioapic_idx
|
||
|
|
||
|
-v3: double check with find_isa_irq_apic(0, mp_INT) to get right
|
||
|
boot_ioapic_idx
|
||
|
|
||
|
-v4: nr_legacy_irqs
|
||
|
|
||
|
-v5: add print out for boot_ioapic_idx, and also make it could be
|
||
|
applied for current kernel and previous kernel
|
||
|
|
||
|
-v6: add bus_irq, in acpi_sci_ioapic_setup, so can get overwride
|
||
|
for sci right mapping...
|
||
|
|
||
|
-v7: looks like pnpacpi get irq instead of gsi, so need to revert
|
||
|
them back...
|
||
|
|
||
|
-v8: split into two patches
|
||
|
|
||
|
-v9: according to Eric, use fixed 16 for shifting instead of remap
|
||
|
|
||
|
-v10: still need to touch rsparser.c
|
||
|
|
||
|
-v11: just revert back to way Eric suggest...
|
||
|
anyway the ioapic in first ioapic is blocked by second...
|
||
|
|
||
|
-v12: two patches, this one will add more loop but check apic_id and irq > 16
|
||
|
|
||
|
Reported-by: Iranna D Ankad <iranna.ankad@in.ibm.com>
|
||
|
Bisected-by: Iranna D Ankad <iranna.ankad@in.ibm.com>
|
||
|
Tested-by: Gary Hade <garyhade@us.ibm.com>
|
||
|
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
|
||
|
Cc: Eric W. Biederman <ebiederm@xmission.com>
|
||
|
Cc: Thomas Renninger <trenn@suse.de>
|
||
|
Cc: Eric W. Biederman <ebiederm@xmission.com>
|
||
|
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
|
||
|
Cc: len.brown@intel.com
|
||
|
LKML-Reference: <4B8A321A.1000008@kernel.org>
|
||
|
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||
|
|
||
|
Automatically created from "patches.fixes/x86_ioapic_fix_out_of_order_gsi.patch" by xen-port-patches.py
|
||
|
|
||
|
--- sle11sp1-2010-03-22.orig/arch/x86/kernel/apic/io_apic-xen.c 2010-03-22 12:47:01.000000000 +0100
|
||
|
+++ sle11sp1-2010-03-22/arch/x86/kernel/apic/io_apic-xen.c 2010-03-22 12:52:03.000000000 +0100
|
||
|
@@ -1556,7 +1556,7 @@ static struct {
|
||
|
|
||
|
static void __init setup_IO_APIC_irqs(void)
|
||
|
{
|
||
|
- int apic_id = 0, pin, idx, irq;
|
||
|
+ int apic_id, pin, idx, irq;
|
||
|
int notcon = 0;
|
||
|
struct irq_desc *desc;
|
||
|
struct irq_cfg *cfg;
|
||
|
@@ -1564,14 +1564,7 @@ static void __init setup_IO_APIC_irqs(vo
|
||
|
|
||
|
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
|
||
|
|
||
|
-#ifdef CONFIG_ACPI
|
||
|
- if (!acpi_disabled && acpi_ioapic) {
|
||
|
- apic_id = mp_find_ioapic(0);
|
||
|
- if (apic_id < 0)
|
||
|
- apic_id = 0;
|
||
|
- }
|
||
|
-#endif
|
||
|
-
|
||
|
+ for (apic_id = 0; apic_id < nr_ioapics; apic_id++)
|
||
|
for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
|
||
|
idx = find_irq_entry(apic_id, pin, mp_INT);
|
||
|
if (idx == -1) {
|
||
|
@@ -1593,6 +1586,9 @@ static void __init setup_IO_APIC_irqs(vo
|
||
|
|
||
|
irq = pin_2_irq(idx, apic_id, pin);
|
||
|
|
||
|
+ if ((apic_id > 0) && (irq > 16))
|
||
|
+ continue;
|
||
|
+
|
||
|
#ifdef CONFIG_XEN
|
||
|
if (irq < PIRQ_BASE || irq >= PIRQ_BASE + nr_pirqs)
|
||
|
continue;
|
||
|
@@ -4210,27 +4206,23 @@ int acpi_get_override_irq(int bus_irq, i
|
||
|
#ifdef CONFIG_SMP
|
||
|
void __init setup_ioapic_dest(void)
|
||
|
{
|
||
|
- int pin, ioapic = 0, irq, irq_entry;
|
||
|
+ int pin, ioapic, irq, irq_entry;
|
||
|
struct irq_desc *desc;
|
||
|
const struct cpumask *mask;
|
||
|
|
||
|
if (skip_ioapic_setup == 1)
|
||
|
return;
|
||
|
|
||
|
-#ifdef CONFIG_ACPI
|
||
|
- if (!acpi_disabled && acpi_ioapic) {
|
||
|
- ioapic = mp_find_ioapic(0);
|
||
|
- if (ioapic < 0)
|
||
|
- ioapic = 0;
|
||
|
- }
|
||
|
-#endif
|
||
|
-
|
||
|
+ for (ioapic = 0; ioapic < nr_ioapics; ioapic++)
|
||
|
for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
|
||
|
irq_entry = find_irq_entry(ioapic, pin, mp_INT);
|
||
|
if (irq_entry == -1)
|
||
|
continue;
|
||
|
irq = pin_2_irq(irq_entry, ioapic, pin);
|
||
|
|
||
|
+ if ((ioapic > 0) && (irq > 16))
|
||
|
+ continue;
|
||
|
+
|
||
|
desc = irq_to_desc(irq);
|
||
|
|
||
|
/*
|