aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/apic/apic.c')
-rw-r--r--arch/x86/kernel/apic/apic.c117
1 files changed, 51 insertions, 66 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index fabf01eff771..b961af86bfea 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -505,7 +505,7 @@ static void __cpuinit setup_APIC_timer(void)
505{ 505{
506 struct clock_event_device *levt = &__get_cpu_var(lapic_events); 506 struct clock_event_device *levt = &__get_cpu_var(lapic_events);
507 507
508 if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_ARAT)) { 508 if (this_cpu_has(X86_FEATURE_ARAT)) {
509 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP; 509 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP;
510 /* Make LAPIC timer preferrable over percpu HPET */ 510 /* Make LAPIC timer preferrable over percpu HPET */
511 lapic_clockevent.rating = 150; 511 lapic_clockevent.rating = 150;
@@ -1237,6 +1237,17 @@ void __cpuinit setup_local_APIC(void)
1237 /* always use the value from LDR */ 1237 /* always use the value from LDR */
1238 early_per_cpu(x86_cpu_to_logical_apicid, cpu) = 1238 early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
1239 logical_smp_processor_id(); 1239 logical_smp_processor_id();
1240
1241 /*
1242 * Some NUMA implementations (NUMAQ) don't initialize apicid to
1243 * node mapping during NUMA init. Now that logical apicid is
1244 * guaranteed to be known, give it another chance. This is already
1245 * a bit too late - percpu allocation has already happened without
1246 * proper NUMA affinity.
1247 */
1248 if (apic->x86_32_numa_cpu_node)
1249 set_apicid_to_node(early_per_cpu(x86_cpu_to_apicid, cpu),
1250 apic->x86_32_numa_cpu_node(cpu));
1240#endif 1251#endif
1241 1252
1242 /* 1253 /*
@@ -1450,7 +1461,6 @@ int __init enable_IR(void)
1450void __init enable_IR_x2apic(void) 1461void __init enable_IR_x2apic(void)
1451{ 1462{
1452 unsigned long flags; 1463 unsigned long flags;
1453 struct IO_APIC_route_entry **ioapic_entries;
1454 int ret, x2apic_enabled = 0; 1464 int ret, x2apic_enabled = 0;
1455 int dmar_table_init_ret; 1465 int dmar_table_init_ret;
1456 1466
@@ -1458,13 +1468,7 @@ void __init enable_IR_x2apic(void)
1458 if (dmar_table_init_ret && !x2apic_supported()) 1468 if (dmar_table_init_ret && !x2apic_supported())
1459 return; 1469 return;
1460 1470
1461 ioapic_entries = alloc_ioapic_entries(); 1471 ret = save_ioapic_entries();
1462 if (!ioapic_entries) {
1463 pr_err("Allocate ioapic_entries failed\n");
1464 goto out;
1465 }
1466
1467 ret = save_IO_APIC_setup(ioapic_entries);
1468 if (ret) { 1472 if (ret) {
1469 pr_info("Saving IO-APIC state failed: %d\n", ret); 1473 pr_info("Saving IO-APIC state failed: %d\n", ret);
1470 goto out; 1474 goto out;
@@ -1472,7 +1476,7 @@ void __init enable_IR_x2apic(void)
1472 1476
1473 local_irq_save(flags); 1477 local_irq_save(flags);
1474 legacy_pic->mask_all(); 1478 legacy_pic->mask_all();
1475 mask_IO_APIC_setup(ioapic_entries); 1479 mask_ioapic_entries();
1476 1480
1477 if (dmar_table_init_ret) 1481 if (dmar_table_init_ret)
1478 ret = 0; 1482 ret = 0;
@@ -1503,14 +1507,11 @@ void __init enable_IR_x2apic(void)
1503 1507
1504nox2apic: 1508nox2apic:
1505 if (!ret) /* IR enabling failed */ 1509 if (!ret) /* IR enabling failed */
1506 restore_IO_APIC_setup(ioapic_entries); 1510 restore_ioapic_entries();
1507 legacy_pic->restore_mask(); 1511 legacy_pic->restore_mask();
1508 local_irq_restore(flags); 1512 local_irq_restore(flags);
1509 1513
1510out: 1514out:
1511 if (ioapic_entries)
1512 free_ioapic_entries(ioapic_entries);
1513
1514 if (x2apic_enabled) 1515 if (x2apic_enabled)
1515 return; 1516 return;
1516 1517
@@ -1812,30 +1813,41 @@ void smp_spurious_interrupt(struct pt_regs *regs)
1812 */ 1813 */
1813void smp_error_interrupt(struct pt_regs *regs) 1814void smp_error_interrupt(struct pt_regs *regs)
1814{ 1815{
1815 u32 v, v1; 1816 u32 v0, v1;
1817 u32 i = 0;
1818 static const char * const error_interrupt_reason[] = {
1819 "Send CS error", /* APIC Error Bit 0 */
1820 "Receive CS error", /* APIC Error Bit 1 */
1821 "Send accept error", /* APIC Error Bit 2 */
1822 "Receive accept error", /* APIC Error Bit 3 */
1823 "Redirectable IPI", /* APIC Error Bit 4 */
1824 "Send illegal vector", /* APIC Error Bit 5 */
1825 "Received illegal vector", /* APIC Error Bit 6 */
1826 "Illegal register address", /* APIC Error Bit 7 */
1827 };
1816 1828
1817 exit_idle(); 1829 exit_idle();
1818 irq_enter(); 1830 irq_enter();
1819 /* First tickle the hardware, only then report what went on. -- REW */ 1831 /* First tickle the hardware, only then report what went on. -- REW */
1820 v = apic_read(APIC_ESR); 1832 v0 = apic_read(APIC_ESR);
1821 apic_write(APIC_ESR, 0); 1833 apic_write(APIC_ESR, 0);
1822 v1 = apic_read(APIC_ESR); 1834 v1 = apic_read(APIC_ESR);
1823 ack_APIC_irq(); 1835 ack_APIC_irq();
1824 atomic_inc(&irq_err_count); 1836 atomic_inc(&irq_err_count);
1825 1837
1826 /* 1838 apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
1827 * Here is what the APIC error bits mean: 1839 smp_processor_id(), v0 , v1);
1828 * 0: Send CS error 1840
1829 * 1: Receive CS error 1841 v1 = v1 & 0xff;
1830 * 2: Send accept error 1842 while (v1) {
1831 * 3: Receive accept error 1843 if (v1 & 0x1)
1832 * 4: Reserved 1844 apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
1833 * 5: Send illegal vector 1845 i++;
1834 * 6: Received illegal vector 1846 v1 >>= 1;
1835 * 7: Illegal register address 1847 };
1836 */ 1848
1837 pr_debug("APIC error on CPU%d: %02x(%02x)\n", 1849 apic_printk(APIC_DEBUG, KERN_CONT "\n");
1838 smp_processor_id(), v , v1); 1850
1839 irq_exit(); 1851 irq_exit();
1840} 1852}
1841 1853
@@ -2003,21 +2015,6 @@ void default_init_apic_ldr(void)
2003 apic_write(APIC_LDR, val); 2015 apic_write(APIC_LDR, val);
2004} 2016}
2005 2017
2006#ifdef CONFIG_X86_32
2007int default_x86_32_numa_cpu_node(int cpu)
2008{
2009#ifdef CONFIG_NUMA
2010 int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
2011
2012 if (apicid != BAD_APICID)
2013 return __apicid_to_node[apicid];
2014 return NUMA_NO_NODE;
2015#else
2016 return 0;
2017#endif
2018}
2019#endif
2020
2021/* 2018/*
2022 * Power management 2019 * Power management
2023 */ 2020 */
@@ -2088,28 +2085,20 @@ static void lapic_resume(void)
2088{ 2085{
2089 unsigned int l, h; 2086 unsigned int l, h;
2090 unsigned long flags; 2087 unsigned long flags;
2091 int maxlvt, ret; 2088 int maxlvt;
2092 struct IO_APIC_route_entry **ioapic_entries = NULL;
2093 2089
2094 if (!apic_pm_state.active) 2090 if (!apic_pm_state.active)
2095 return; 2091 return;
2096 2092
2097 local_irq_save(flags); 2093 local_irq_save(flags);
2098 if (intr_remapping_enabled) { 2094 if (intr_remapping_enabled) {
2099 ioapic_entries = alloc_ioapic_entries(); 2095 /*
2100 if (!ioapic_entries) { 2096 * IO-APIC and PIC have their own resume routines.
2101 WARN(1, "Alloc ioapic_entries in lapic resume failed."); 2097 * We just mask them here to make sure the interrupt
2102 goto restore; 2098 * subsystem is completely quiet while we enable x2apic
2103 } 2099 * and interrupt-remapping.
2104 2100 */
2105 ret = save_IO_APIC_setup(ioapic_entries); 2101 mask_ioapic_entries();
2106 if (ret) {
2107 WARN(1, "Saving IO-APIC state failed: %d\n", ret);
2108 free_ioapic_entries(ioapic_entries);
2109 goto restore;
2110 }
2111
2112 mask_IO_APIC_setup(ioapic_entries);
2113 legacy_pic->mask_all(); 2102 legacy_pic->mask_all();
2114 } 2103 }
2115 2104
@@ -2152,13 +2141,9 @@ static void lapic_resume(void)
2152 apic_write(APIC_ESR, 0); 2141 apic_write(APIC_ESR, 0);
2153 apic_read(APIC_ESR); 2142 apic_read(APIC_ESR);
2154 2143
2155 if (intr_remapping_enabled) { 2144 if (intr_remapping_enabled)
2156 reenable_intr_remapping(x2apic_mode); 2145 reenable_intr_remapping(x2apic_mode);
2157 legacy_pic->restore_mask(); 2146
2158 restore_IO_APIC_setup(ioapic_entries);
2159 free_ioapic_entries(ioapic_entries);
2160 }
2161restore:
2162 local_irq_restore(flags); 2147 local_irq_restore(flags);
2163} 2148}
2164 2149