]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
x2apic: fix reserved APIC register accesses in print_local_APIC()
authorYinghai Lu <yhlu.kernel@gmail.com>
Wed, 3 Sep 2008 23:58:31 +0000 (16:58 -0700)
committerIngo Molnar <mingo@elte.hu>
Thu, 16 Oct 2008 14:53:04 +0000 (16:53 +0200)
APIC_ARBPRI is a reserved register for XAPIC and beyond.
APIC_RRR is a reserved register except for 82489DX, APIC for Pentium processors.
APIC_EOI is a write only register.
APIC_DFR is reserved in x2apic mode.

Access to these registers in x2apic will result in #GP fault. Fix these
apic register accesses.

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/io_apic.c
include/asm-x86/apic.h

index d28128e0392c94c8bd0325fc4b9c4c239c0c81f6..93ceb19d1e90e39cac4dfcfb7d1592bfd5d7267e 100644 (file)
@@ -1751,21 +1751,30 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
        printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
 
        if (APIC_INTEGRATED(ver)) {                     /* !82489DX */
-               v = apic_read(APIC_ARBPRI);
-               printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
-                       v & APIC_ARBPRI_MASK);
+               if (!APIC_XAPIC(ver)) {
+                       v = apic_read(APIC_ARBPRI);
+                       printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
+                              v & APIC_ARBPRI_MASK);
+               }
                v = apic_read(APIC_PROCPRI);
                printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
        }
 
-       v = apic_read(APIC_EOI);
-       printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
-       v = apic_read(APIC_RRR);
-       printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
+       /*
+        * Remote read supported only in the 82489DX and local APIC for
+        * Pentium processors.
+        */
+       if (!APIC_INTEGRATED(ver) || maxlvt == 3) {
+               v = apic_read(APIC_RRR);
+               printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
+       }
+
        v = apic_read(APIC_LDR);
        printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
-       v = apic_read(APIC_DFR);
-       printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
+       if (!x2apic_enabled()) {
+               v = apic_read(APIC_DFR);
+               printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
+       }
        v = apic_read(APIC_SPIV);
        printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
 
index 2d970f6bc2a101f459b497d27d7ae7927614fc12..ef1d72dbdfe02b74d389c2067af12373db2cd3de 100644 (file)
@@ -98,6 +98,20 @@ extern void check_x2apic(void);
 extern void enable_x2apic(void);
 extern void enable_IR_x2apic(void);
 extern void x2apic_icr_write(u32 low, u32 id);
+static inline int x2apic_enabled(void)
+{
+       int msr, msr2;
+
+       if (!cpu_has_x2apic)
+               return 0;
+
+       rdmsr(MSR_IA32_APICBASE, msr, msr2);
+       if (msr & X2APIC_ENABLE)
+               return 1;
+       return 0;
+}
+#else
+#define x2apic_enabled()       0
 #endif
 
 struct apic_ops {