Merge branch 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile...
[pandora-kernel.git] / arch / x86 / kernel / apic / apic.c
index a0bf78a..b9338b8 100644 (file)
@@ -506,7 +506,7 @@ static void __cpuinit setup_APIC_timer(void)
 {
        struct clock_event_device *levt = &__get_cpu_var(lapic_events);
 
-       if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_ARAT)) {
+       if (this_cpu_has(X86_FEATURE_ARAT)) {
                lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP;
                /* Make LAPIC timer preferrable over percpu HPET */
                lapic_clockevent.rating = 150;
@@ -1238,6 +1238,17 @@ void __cpuinit setup_local_APIC(void)
        /* always use the value from LDR */
        early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
                logical_smp_processor_id();
+
+       /*
+        * Some NUMA implementations (NUMAQ) don't initialize apicid to
+        * node mapping during NUMA init.  Now that logical apicid is
+        * guaranteed to be known, give it another chance.  This is already
+        * a bit too late - percpu allocation has already happened without
+        * proper NUMA affinity.
+        */
+       if (apic->x86_32_numa_cpu_node)
+               set_apicid_to_node(early_per_cpu(x86_cpu_to_apicid, cpu),
+                                  apic->x86_32_numa_cpu_node(cpu));
 #endif
 
        /*
@@ -1451,7 +1462,6 @@ int __init enable_IR(void)
 void __init enable_IR_x2apic(void)
 {
        unsigned long flags;
-       struct IO_APIC_route_entry **ioapic_entries;
        int ret, x2apic_enabled = 0;
        int dmar_table_init_ret;
 
@@ -1459,13 +1469,7 @@ void __init enable_IR_x2apic(void)
        if (dmar_table_init_ret && !x2apic_supported())
                return;
 
-       ioapic_entries = alloc_ioapic_entries();
-       if (!ioapic_entries) {
-               pr_err("Allocate ioapic_entries failed\n");
-               goto out;
-       }
-
-       ret = save_IO_APIC_setup(ioapic_entries);
+       ret = save_ioapic_entries();
        if (ret) {
                pr_info("Saving IO-APIC state failed: %d\n", ret);
                goto out;
@@ -1473,7 +1477,7 @@ void __init enable_IR_x2apic(void)
 
        local_irq_save(flags);
        legacy_pic->mask_all();
-       mask_IO_APIC_setup(ioapic_entries);
+       mask_ioapic_entries();
 
        if (dmar_table_init_ret)
                ret = 0;
@@ -1504,14 +1508,11 @@ void __init enable_IR_x2apic(void)
 
 nox2apic:
        if (!ret) /* IR enabling failed */
-               restore_IO_APIC_setup(ioapic_entries);
+               restore_ioapic_entries();
        legacy_pic->restore_mask();
        local_irq_restore(flags);
 
 out:
-       if (ioapic_entries)
-               free_ioapic_entries(ioapic_entries);
-
        if (x2apic_enabled)
                return;
 
@@ -1813,30 +1814,41 @@ void smp_spurious_interrupt(struct pt_regs *regs)
  */
 void smp_error_interrupt(struct pt_regs *regs)
 {
-       u32 v, v1;
+       u32 v0, v1;
+       u32 i = 0;
+       static const char * const error_interrupt_reason[] = {
+               "Send CS error",                /* APIC Error Bit 0 */
+               "Receive CS error",             /* APIC Error Bit 1 */
+               "Send accept error",            /* APIC Error Bit 2 */
+               "Receive accept error",         /* APIC Error Bit 3 */
+               "Redirectable IPI",             /* APIC Error Bit 4 */
+               "Send illegal vector",          /* APIC Error Bit 5 */
+               "Received illegal vector",      /* APIC Error Bit 6 */
+               "Illegal register address",     /* APIC Error Bit 7 */
+       };
 
        exit_idle();
        irq_enter();
        /* First tickle the hardware, only then report what went on. -- REW */
-       v = apic_read(APIC_ESR);
+       v0 = apic_read(APIC_ESR);
        apic_write(APIC_ESR, 0);
        v1 = apic_read(APIC_ESR);
        ack_APIC_irq();
        atomic_inc(&irq_err_count);
 
-       /*
-        * Here is what the APIC error bits mean:
-        * 0: Send CS error
-        * 1: Receive CS error
-        * 2: Send accept error
-        * 3: Receive accept error
-        * 4: Reserved
-        * 5: Send illegal vector
-        * 6: Received illegal vector
-        * 7: Illegal register address
-        */
-       pr_debug("APIC error on CPU%d: %02x(%02x)\n",
-               smp_processor_id(), v , v1);
+       apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
+                   smp_processor_id(), v0 , v1);
+
+       v1 = v1 & 0xff;
+       while (v1) {
+               if (v1 & 0x1)
+                       apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
+               i++;
+               v1 >>= 1;
+       };
+
+       apic_printk(APIC_DEBUG, KERN_CONT "\n");
+
        irq_exit();
 }
 
@@ -2004,21 +2016,6 @@ void default_init_apic_ldr(void)
        apic_write(APIC_LDR, val);
 }
 
-#ifdef CONFIG_X86_32
-int default_x86_32_numa_cpu_node(int cpu)
-{
-#ifdef CONFIG_NUMA
-       int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
-
-       if (apicid != BAD_APICID)
-               return __apicid_to_node[apicid];
-       return NUMA_NO_NODE;
-#else
-       return 0;
-#endif
-}
-#endif
-
 /*
  * Power management
  */
@@ -2089,28 +2086,20 @@ static void lapic_resume(void)
 {
        unsigned int l, h;
        unsigned long flags;
-       int maxlvt, ret;
-       struct IO_APIC_route_entry **ioapic_entries = NULL;
+       int maxlvt;
 
        if (!apic_pm_state.active)
                return;
 
        local_irq_save(flags);
        if (intr_remapping_enabled) {
-               ioapic_entries = alloc_ioapic_entries();
-               if (!ioapic_entries) {
-                       WARN(1, "Alloc ioapic_entries in lapic resume failed.");
-                       goto restore;
-               }
-
-               ret = save_IO_APIC_setup(ioapic_entries);
-               if (ret) {
-                       WARN(1, "Saving IO-APIC state failed: %d\n", ret);
-                       free_ioapic_entries(ioapic_entries);
-                       goto restore;
-               }
-
-               mask_IO_APIC_setup(ioapic_entries);
+               /*
+                * IO-APIC and PIC have their own resume routines.
+                * We just mask them here to make sure the interrupt
+                * subsystem is completely quiet while we enable x2apic
+                * and interrupt-remapping.
+                */
+               mask_ioapic_entries();
                legacy_pic->mask_all();
        }
 
@@ -2153,13 +2142,9 @@ static void lapic_resume(void)
        apic_write(APIC_ESR, 0);
        apic_read(APIC_ESR);
 
-       if (intr_remapping_enabled) {
+       if (intr_remapping_enabled)
                reenable_intr_remapping(x2apic_mode);
-               legacy_pic->restore_mask();
-               restore_IO_APIC_setup(ioapic_entries);
-               free_ioapic_entries(ioapic_entries);
-       }
-restore:
+
        local_irq_restore(flags);
 }