[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 *)®_01 = io_apic_read(apic, 1);
if (reg_01.version >= 0x10)
*(int *)®_02 = io_apic_read(apic, 2);
+ if (reg_01.version >= 0x20)
+ *(int *)®_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 *)®_02 != *(int *)®_01) {
printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)®_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 *)®_03 != *(int *)®_02 &&
+ *(int *)®_03 != *(int *)®_01) {
+ printk(KERN_DEBUG ".... register #03: %08X\n", *(int *)®_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 *)®_01 = io_apic_read(apic, 1);
if (reg_01.version >= 0x10)
*(int *)®_02 = io_apic_read(apic, 2);
+ if (reg_01.version >= 0x20)
+ *(int *)®_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 *)®_02 != *(int *)®_01) {
printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)®_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 *)®_03 != *(int *)®_02 &&
+ *(int *)®_03 != *(int *)®_01) {
+ printk(KERN_DEBUG ".... register #03: %08X\n", *(int *)®_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