+ x86-x86_64-avoid-irq0-ioapic-pin-collision.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     x86/x86_64: avoid IRQ0 ioapic pin collision

has been added to the -mm tree.  Its filename is

     x86-x86_64-avoid-irq0-ioapic-pin-collision.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this


From: Kimball Murray <kimball.murray@xxxxxxxxx>

I'm working on an x86_64 platfrom, where I've hit a problem that appears to
be caused by a patch that went into 2.6.13 some time ago.  (git details are
below).  Basically, that patch introduced a work-around for a VIA chipset
limitation (only 4 bits to store a PCI interrupt).  And that work-around
causes an unfortunate pin collision on our ioapic.

Our system uses an ACPI Interrupt Source Override to inform the OS that the
8254 timer (IRQ0) is on pin 1 of the ioapic.  On that same ioapic, pin 0
handles an interrupt from a PCI device.  The work-around for the VIA
chipset now causes pin 0 to get IRQ0 on our platform, which the timer also
claims.  The sad result is both pins 0 and 1 drive IRQ0, but pins 0 and 1
have in an IRQ0 interrupt storm.

I brought this up with Natalie, who provided the VIA patch.  What we came
up with is a means of keeping the VIA work-around, but at the same time,
avoiding the IRQ0 collision.  What I'm doing here is creating a flag in
io_apic.c (timer_uses_ioapic_pin_0), which is checked in mpparse.c.  If the
timer is not using pin 0, and we find a PCI-type interrupt for gsi 0, then
I bump the gsi up to the current value of pci_irq.  Otherwise, it behaves
as before.

Cc: Andi Kleen <ak@xxxxxx>
Cc: "Brown, Len" <len.brown@xxxxxxxxx>
Cc: "Protasevich, Natalie" <Natalie.Protasevich@xxxxxxxxxx>
Acked-by: Rohit Seth <rohitseth@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 arch/i386/kernel/io_apic.c   |    5 +++++
 arch/i386/kernel/mpparse.c   |   12 +++++++++++-
 arch/x86_64/kernel/io_apic.c |    5 +++++
 arch/x86_64/kernel/mpparse.c |   12 +++++++++++-
 include/asm-i386/io_apic.h   |    1 +
 include/asm-x86_64/io_apic.h |    1 +
 6 files changed, 34 insertions(+), 2 deletions(-)

diff -puN arch/i386/kernel/io_apic.c~x86-x86_64-avoid-irq0-ioapic-pin-collision arch/i386/kernel/io_apic.c
--- 25/arch/i386/kernel/io_apic.c~x86-x86_64-avoid-irq0-ioapic-pin-collision	Wed Apr 26 14:21:09 2006
+++ 25-akpm/arch/i386/kernel/io_apic.c	Wed Apr 26 14:21:59 2006
@@ -2239,6 +2239,8 @@ static inline void unlock_ExtINT_logic(v
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
+int timer_uses_ioapic_pin_0;
+
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
  * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
@@ -2275,6 +2277,9 @@ static inline void check_timer(void)
 	pin2  = ioapic_i8259.pin;
 	apic2 = ioapic_i8259.apic;
 
+	if (pin1 == 0)
+		timer_uses_ioapic_pin_0 = 1;
+
 	printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
 		vector, apic1, pin1, apic2, pin2);
 
diff -puN arch/i386/kernel/mpparse.c~x86-x86_64-avoid-irq0-ioapic-pin-collision arch/i386/kernel/mpparse.c
--- 25/arch/i386/kernel/mpparse.c~x86-x86_64-avoid-irq0-ioapic-pin-collision	Wed Apr 26 14:21:09 2006
+++ 25-akpm/arch/i386/kernel/mpparse.c	Wed Apr 26 14:21:20 2006
@@ -1131,7 +1131,17 @@ int mp_register_gsi (u32 gsi, int trigge
 		 */
 		int irq = gsi;
 		if (gsi < MAX_GSI_NUM) {
-			if (gsi > 15)
+			/*
+			 * Retain the VIA chipset work-around (gsi > 15), but
+			 * avoid a problem where the 8254 timer (IRQ0) is setup
+			 * via an override (so it's not on pin 0 of the ioapic),
+			 * and at the same time, the pin 0 interrupt is a PCI
+			 * type.  The gsi > 15 test could cause these two pins
+			 * to be shared as IRQ0, and they are not shareable.
+			 * So test for this condition, and if necessary, avoid
+			 * the pin collision.
+			 */
+			if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
 				gsi = pci_irq++;
 			/*
 			 * Don't assign IRQ used by ACPI SCI
diff -puN arch/x86_64/kernel/io_apic.c~x86-x86_64-avoid-irq0-ioapic-pin-collision arch/x86_64/kernel/io_apic.c
--- 25/arch/x86_64/kernel/io_apic.c~x86-x86_64-avoid-irq0-ioapic-pin-collision	Wed Apr 26 14:21:09 2006
+++ 25-akpm/arch/x86_64/kernel/io_apic.c	Wed Apr 26 14:21:59 2006
@@ -1777,6 +1777,8 @@ static inline void unlock_ExtINT_logic(v
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
+int timer_uses_ioapic_pin_0;
+
 /*
  * This code may look a bit paranoid, but it's supposed to cooperate with
  * a wide range of boards and BIOS bugs.  Fortunately only the timer IRQ
@@ -1814,6 +1816,9 @@ static inline void check_timer(void)
 	pin2  = ioapic_i8259.pin;
 	apic2 = ioapic_i8259.apic;
 
+	if (pin1 == 0)
+		timer_uses_ioapic_pin_0 = 1;
+
 	apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
 		vector, apic1, pin1, apic2, pin2);
 
diff -puN arch/x86_64/kernel/mpparse.c~x86-x86_64-avoid-irq0-ioapic-pin-collision arch/x86_64/kernel/mpparse.c
--- 25/arch/x86_64/kernel/mpparse.c~x86-x86_64-avoid-irq0-ioapic-pin-collision	Wed Apr 26 14:21:09 2006
+++ 25-akpm/arch/x86_64/kernel/mpparse.c	Wed Apr 26 14:21:22 2006
@@ -968,7 +968,17 @@ int mp_register_gsi(u32 gsi, int trigger
 		 */
 		int irq = gsi;
 		if (gsi < MAX_GSI_NUM) {
-			if (gsi > 15)
+			/*
+			 * Retain the VIA chipset work-around (gsi > 15), but
+			 * avoid a problem where the 8254 timer (IRQ0) is setup
+			 * via an override (so it's not on pin 0 of the ioapic),
+			 * and at the same time, the pin 0 interrupt is a PCI
+			 * type.  The gsi > 15 test could cause these two pins
+			 * to be shared as IRQ0, and they are not shareable.
+			 * So test for this condition, and if necessary, avoid
+			 * the pin collision.
+			 */
+			if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0))
 				gsi = pci_irq++;
 			/*
 			 * Don't assign IRQ used by ACPI SCI
diff -puN include/asm-i386/io_apic.h~x86-x86_64-avoid-irq0-ioapic-pin-collision include/asm-i386/io_apic.h
--- 25/include/asm-i386/io_apic.h~x86-x86_64-avoid-irq0-ioapic-pin-collision	Wed Apr 26 14:21:09 2006
+++ 25-akpm/include/asm-i386/io_apic.h	Wed Apr 26 14:21:09 2006
@@ -200,6 +200,7 @@ extern int io_apic_get_unique_id (int io
 extern int io_apic_get_version (int ioapic);
 extern int io_apic_get_redir_entries (int ioapic);
 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low);
+extern int timer_uses_ioapic_pin_0;
 #endif /* CONFIG_ACPI */
 
 extern int (*ioapic_renumber_irq)(int ioapic, int irq);
diff -puN include/asm-x86_64/io_apic.h~x86-x86_64-avoid-irq0-ioapic-pin-collision include/asm-x86_64/io_apic.h
--- 25/include/asm-x86_64/io_apic.h~x86-x86_64-avoid-irq0-ioapic-pin-collision	Wed Apr 26 14:21:09 2006
+++ 25-akpm/include/asm-x86_64/io_apic.h	Wed Apr 26 14:21:09 2006
@@ -205,6 +205,7 @@ extern int skip_ioapic_setup;
 extern int io_apic_get_version (int ioapic);
 extern int io_apic_get_redir_entries (int ioapic);
 extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int);
+extern int timer_uses_ioapic_pin_0;
 #endif
 
 extern int sis_apic_bug; /* dummy */ 
_

Patches currently in -mm which might be from kimball.murray@xxxxxxxxx are

x86-x86_64-avoid-irq0-ioapic-pin-collision.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux