[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-smp
Subject:    [PATCH] unexpected IO-APIC test]
From:       "Randy.Dunlap" <rddunlap () osdl ! org>
Date:       2003-06-15 4:22:48
[Download RAW message or body]

Hi,

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

I have an experimental patch that addresses these chipsets.
Other than conditionally decoding them, we could alternately ignore
IO APIC registers 2 and 3 since Linux doesn't use the values for
anything other then 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 it's value if the same as IO APIC
register 1 or 2.

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

Comments?

Thanks,
~Randy

Patches for 2.4.21 and for 2.5.71 are attached.



["ioapic_update_2421.patch" (application/octet-stream)]

patch_name:	ioapic_update_2421.patch
patch_version:	2003-06-13.15:35:48
author:		Randy.Dunlap <rddunlap@osdl.org>
description:	support newer Intel chipset IO APICs;
product:	Linux
product_versions: linux-2421
maintainer:	Maciej W. Rozycki <macro@ds2.pg.gda.pl>
diffstat:	=
 arch/i386/kernel/io_apic.c |   23 ++++++++++++++++++++++-
 include/asm-i386/io_apic.h |    5 +++++
 2 files changed, 27 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-13 09:11:32.000000000 -0700
+++ ./include/asm-i386/io_apic.h	2003-06-13 14:45:37.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-13 07:51:29.000000000 -0700
+++ ./arch/i386/kernel/io_apic.c	2003-06-13 15:34:33.000000000 -0700
@@ -750,6 +750,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);
@@ -770,6 +771,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");
@@ -807,13 +810,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"

["ioapic_update_2571.patch" (application/octet-stream)]

patch_name:	ioapic_update_2571.patch
patch_version:	2003-06-14.20:53:04
author:		Randy.Dunlap <rddunlap@osdl.org>
description:	support newer Intel chipset IO APICs;
product:	Linux
product_versions: linux-2571
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
@@ -45,6 +45,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
@@ -1265,6 +1265,9 @@
 
 static inline void UNEXPECTED_IO_APIC(void)
 {
+	printk(KERN_WARNING 
+		"An unexpected IO-APIC was found. If this kernel release is less than\n"
+		"three months old, please report this at http://bugzilla.kernel.org\n");
 }
 
 void __init print_IO_APIC(void)
@@ -1273,6 +1276,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);
@@ -1293,6 +1297,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");
@@ -1328,13 +1334,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"

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

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic