mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] unexpected IO-APIC update
@ 2003-06-24 23:10 Randy.Dunlap
  2003-06-25  1:31 ` Linus Torvalds
  0 siblings, 1 reply; 6+ messages in thread
From: Randy.Dunlap @ 2003-06-24 23:10 UTC (permalink / raw)
  To: lkml; +Cc: torvalds, macro, akpm


Hi,

Recently there has been a rash of Unexpected IO APIC reports on
the linux-smp mailing list.  Most of the most recent ones are due
to some newer Intel chipsets (865, 875).

The IO APIC Version register doesn't indicate the differences in
these IO APICs.

I have an patch that addresses these chipsets.  It has been
tested by a few people with good results and has been blessed
by Maciej Rozycki.

Other than conditionally decoding IO APIC registers 2 and 3,
we could alternately ignore them since Linux doesn't use the values
for anything other than printing them.

This patch ignores IO APIC register 2 if it's the same value as IO APIC
register 1.  It also reads IO APIC register 3 if the IO APIC
version is >= 0x20, but some chipsets don't support this
register, so it is also ignored if its value if the same as IO APIC
register 1 or 2.

Another possible(?) alternative is to read the PID/VID of the
device to determine which registers it supports.  However,
PCI devices have not been scanned at this point in init, so it
would require scanning PCI config space directly and I don't
yet see the point of doing that.

Oh, and the UNEXPECTED_IO_APIC() function doesn't print anything
in 2.5.current and I didn't change that.

Patch for 2.5.73 is below.  Please apply.

--
~Randy
~ http://developer.osdl.org/rddunlap/ ~ http://www.xenotime.net/linux/ ~



patch_name:	ioapic_update_2573.patch
patch_version:	2003-06-24.15:43:44
author:		Randy.Dunlap <rddunlap@osdl.org>
description:	support newer Intel chipset IO APICs;
product:	Linux
product_versions: linux-2573
maintainer:	Maciej W. Rozycki <macro@ds2.pg.gda.pl>
diffstat:	=
 arch/i386/kernel/io_apic.c |   26 +++++++++++++++++++++++++-
 include/asm-i386/io_apic.h |    5 +++++
 2 files changed, 30 insertions(+), 1 deletion(-)


diff -Naur ./include/asm-i386/io_apic.h~ioap ./include/asm-i386/io_apic.h
--- ./include/asm-i386/io_apic.h~ioap	2003-06-14 12:18:25.000000000 -0700
+++ ./include/asm-i386/io_apic.h	2003-06-14 20:17:44.000000000 -0700
@@ -44,6 +44,11 @@
 		__reserved_1	:  4;
 } __attribute__ ((packed));
 
+struct IO_APIC_reg_03 {
+	__u32	boot_DT		:  1,
+		__reserved_1	: 31;
+} __attribute__ ((packed));
+
 /*
  * # of IO-APICs and # of IRQ routing registers
  */
diff -Naur ./arch/i386/kernel/io_apic.c~ioap ./arch/i386/kernel/io_apic.c
--- ./arch/i386/kernel/io_apic.c~ioap	2003-06-14 12:18:06.000000000 -0700
+++ ./arch/i386/kernel/io_apic.c	2003-06-14 20:43:19.000000000 -0700
@@ -1275,6 +1278,7 @@
 	struct IO_APIC_reg_00 reg_00;
 	struct IO_APIC_reg_01 reg_01;
 	struct IO_APIC_reg_02 reg_02;
+	struct IO_APIC_reg_03 reg_03;
 	unsigned long flags;
 
  	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
@@ -1295,6 +1299,8 @@
 	*(int *)&reg_01 = io_apic_read(apic, 1);
 	if (reg_01.version >= 0x10)
 		*(int *)&reg_02 = io_apic_read(apic, 2);
+	if (reg_01.version >= 0x20)
+		*(int *)&reg_03 = io_apic_read(apic, 3);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	printk("\n");
@@ -1332,13 +1336,31 @@
 	if (reg_01.__reserved_1 || reg_01.__reserved_2)
 		UNEXPECTED_IO_APIC();
 
-	if (reg_01.version >= 0x10) {
+	/*
+	 * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
+	 * but the value of reg_02 is read as the previous read register
+	 * value, so ignore it if reg_02 == reg_01.
+	 */
+	if (reg_01.version >= 0x10 && *(int *)&reg_02 != *(int *)&reg_01) {
 		printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)&reg_02);
 		printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.arbitration);
 		if (reg_02.__reserved_1 || reg_02.__reserved_2)
 			UNEXPECTED_IO_APIC();
 	}
 
+	/*
+	 * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
+	 * or reg_03, but the value of reg_0[23] is read as the previous read
+	 * register value, so ignore it if reg_03 == reg_0[12].
+	 */
+	if (reg_01.version >= 0x20 && *(int *)&reg_03 != *(int *)&reg_02 &&
+	    *(int *)&reg_03 != *(int *)&reg_01) {
+		printk(KERN_DEBUG ".... register #03: %08X\n", *(int *)&reg_03);
+		printk(KERN_DEBUG ".......     : Boot DT    : %X\n", reg_03.boot_DT);
+		if (reg_03.__reserved_1)
+			UNEXPECTED_IO_APIC();
+	}
+
 	printk(KERN_DEBUG ".... IRQ redirection table:\n");
 
 	printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2003-06-26 13:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-24 23:10 [PATCH] unexpected IO-APIC update Randy.Dunlap
2003-06-25  1:31 ` Linus Torvalds
2003-06-25 15:57   ` Randy.Dunlap
2003-06-25 16:11     ` Maciej W. Rozycki
2003-06-25 18:23       ` [PATCH] IO-APIC unions Randy.Dunlap
2003-06-26 13:47         ` Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®