aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-12-18 05:55:06 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-18 05:55:12 -0500
commit9a3d8f735eee90bb5b1351983e946bc637041c01 (patch)
treebdbe6d9f986e9715f8d9b45499f969fa7b51c6a3 /arch
parentb9974dc6bddd41fbdc2583f196a34fbcebd8b089 (diff)
parenta98f8fd24fb24fcb9a359553e64dd6aac5cf4279 (diff)
Merge branch 'x86/apic' into cpus4096
This done for conflict prevention: we merge it into the cpus4096 tree because upcoming cpumask changes will touch apic.c that would collide with x86/apic otherwise.
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/apic.c121
-rw-r--r--arch/x86/kernel/nmi.c43
2 files changed, 90 insertions, 74 deletions
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index edda4c00e3d2..93cf2d13f335 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -441,6 +441,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
441 v = apic_read(APIC_LVTT); 441 v = apic_read(APIC_LVTT);
442 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); 442 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
443 apic_write(APIC_LVTT, v); 443 apic_write(APIC_LVTT, v);
444 apic_write(APIC_TMICT, 0xffffffff);
444 break; 445 break;
445 case CLOCK_EVT_MODE_RESUME: 446 case CLOCK_EVT_MODE_RESUME:
446 /* Nothing to do here */ 447 /* Nothing to do here */
@@ -559,13 +560,13 @@ static int __init calibrate_by_pmtimer(long deltapm, long *delta)
559 } else { 560 } else {
560 res = (((u64)deltapm) * mult) >> 22; 561 res = (((u64)deltapm) * mult) >> 22;
561 do_div(res, 1000000); 562 do_div(res, 1000000);
562 printk(KERN_WARNING "APIC calibration not consistent " 563 pr_warning("APIC calibration not consistent "
563 "with PM Timer: %ldms instead of 100ms\n", 564 "with PM Timer: %ldms instead of 100ms\n",
564 (long)res); 565 (long)res);
565 /* Correct the lapic counter value */ 566 /* Correct the lapic counter value */
566 res = (((u64)(*delta)) * pm_100ms); 567 res = (((u64)(*delta)) * pm_100ms);
567 do_div(res, deltapm); 568 do_div(res, deltapm);
568 printk(KERN_INFO "APIC delta adjusted to PM-Timer: " 569 pr_info("APIC delta adjusted to PM-Timer: "
569 "%lu (%ld)\n", (unsigned long)res, *delta); 570 "%lu (%ld)\n", (unsigned long)res, *delta);
570 *delta = (long)res; 571 *delta = (long)res;
571 } 572 }
@@ -645,8 +646,7 @@ static int __init calibrate_APIC_clock(void)
645 */ 646 */
646 if (calibration_result < (1000000 / HZ)) { 647 if (calibration_result < (1000000 / HZ)) {
647 local_irq_enable(); 648 local_irq_enable();
648 printk(KERN_WARNING 649 pr_warning("APIC frequency too slow, disabling apic timer\n");
649 "APIC frequency too slow, disabling apic timer\n");
650 return -1; 650 return -1;
651 } 651 }
652 652
@@ -672,13 +672,9 @@ static int __init calibrate_APIC_clock(void)
672 while (lapic_cal_loops <= LAPIC_CAL_LOOPS) 672 while (lapic_cal_loops <= LAPIC_CAL_LOOPS)
673 cpu_relax(); 673 cpu_relax();
674 674
675 local_irq_disable();
676
677 /* Stop the lapic timer */ 675 /* Stop the lapic timer */
678 lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); 676 lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);
679 677
680 local_irq_enable();
681
682 /* Jiffies delta */ 678 /* Jiffies delta */
683 deltaj = lapic_cal_j2 - lapic_cal_j1; 679 deltaj = lapic_cal_j2 - lapic_cal_j1;
684 apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); 680 apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj);
@@ -692,8 +688,7 @@ static int __init calibrate_APIC_clock(void)
692 local_irq_enable(); 688 local_irq_enable();
693 689
694 if (levt->features & CLOCK_EVT_FEAT_DUMMY) { 690 if (levt->features & CLOCK_EVT_FEAT_DUMMY) {
695 printk(KERN_WARNING 691 pr_warning("APIC timer disabled due to verification failure.\n");
696 "APIC timer disabled due to verification failure.\n");
697 return -1; 692 return -1;
698 } 693 }
699 694
@@ -714,7 +709,7 @@ void __init setup_boot_APIC_clock(void)
714 * broadcast mechanism is used. On UP systems simply ignore it. 709 * broadcast mechanism is used. On UP systems simply ignore it.
715 */ 710 */
716 if (disable_apic_timer) { 711 if (disable_apic_timer) {
717 printk(KERN_INFO "Disabling APIC timer\n"); 712 pr_info("Disabling APIC timer\n");
718 /* No broadcast on UP ! */ 713 /* No broadcast on UP ! */
719 if (num_possible_cpus() > 1) { 714 if (num_possible_cpus() > 1) {
720 lapic_clockevent.mult = 1; 715 lapic_clockevent.mult = 1;
@@ -741,7 +736,7 @@ void __init setup_boot_APIC_clock(void)
741 if (nmi_watchdog != NMI_IO_APIC) 736 if (nmi_watchdog != NMI_IO_APIC)
742 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; 737 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
743 else 738 else
744 printk(KERN_WARNING "APIC timer registered as dummy," 739 pr_warning("APIC timer registered as dummy,"
745 " due to nmi_watchdog=%d!\n", nmi_watchdog); 740 " due to nmi_watchdog=%d!\n", nmi_watchdog);
746 741
747 /* Setup the lapic or request the broadcast */ 742 /* Setup the lapic or request the broadcast */
@@ -773,8 +768,7 @@ static void local_apic_timer_interrupt(void)
773 * spurious. 768 * spurious.
774 */ 769 */
775 if (!evt->event_handler) { 770 if (!evt->event_handler) {
776 printk(KERN_WARNING 771 pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu);
777 "Spurious LAPIC timer interrupt on cpu %d\n", cpu);
778 /* Switch it off */ 772 /* Switch it off */
779 lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt); 773 lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
780 return; 774 return;
@@ -1093,7 +1087,7 @@ static void __cpuinit lapic_setup_esr(void)
1093 unsigned int oldvalue, value, maxlvt; 1087 unsigned int oldvalue, value, maxlvt;
1094 1088
1095 if (!lapic_is_integrated()) { 1089 if (!lapic_is_integrated()) {
1096 printk(KERN_INFO "No ESR for 82489DX.\n"); 1090 pr_info("No ESR for 82489DX.\n");
1097 return; 1091 return;
1098 } 1092 }
1099 1093
@@ -1104,7 +1098,7 @@ static void __cpuinit lapic_setup_esr(void)
1104 * ESR disabled - we can't do anything useful with the 1098 * ESR disabled - we can't do anything useful with the
1105 * errors anyway - mbligh 1099 * errors anyway - mbligh
1106 */ 1100 */
1107 printk(KERN_INFO "Leaving ESR disabled.\n"); 1101 pr_info("Leaving ESR disabled.\n");
1108 return; 1102 return;
1109 } 1103 }
1110 1104
@@ -1298,7 +1292,7 @@ void check_x2apic(void)
1298 rdmsr(MSR_IA32_APICBASE, msr, msr2); 1292 rdmsr(MSR_IA32_APICBASE, msr, msr2);
1299 1293
1300 if (msr & X2APIC_ENABLE) { 1294 if (msr & X2APIC_ENABLE) {
1301 printk("x2apic enabled by BIOS, switching to x2apic ops\n"); 1295 pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
1302 x2apic_preenabled = x2apic = 1; 1296 x2apic_preenabled = x2apic = 1;
1303 apic_ops = &x2apic_ops; 1297 apic_ops = &x2apic_ops;
1304 } 1298 }
@@ -1310,7 +1304,7 @@ void enable_x2apic(void)
1310 1304
1311 rdmsr(MSR_IA32_APICBASE, msr, msr2); 1305 rdmsr(MSR_IA32_APICBASE, msr, msr2);
1312 if (!(msr & X2APIC_ENABLE)) { 1306 if (!(msr & X2APIC_ENABLE)) {
1313 printk("Enabling x2apic\n"); 1307 pr_info("Enabling x2apic\n");
1314 wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0); 1308 wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
1315 } 1309 }
1316} 1310}
@@ -1325,9 +1319,8 @@ void __init enable_IR_x2apic(void)
1325 return; 1319 return;
1326 1320
1327 if (!x2apic_preenabled && disable_x2apic) { 1321 if (!x2apic_preenabled && disable_x2apic) {
1328 printk(KERN_INFO 1322 pr_info("Skipped enabling x2apic and Interrupt-remapping "
1329 "Skipped enabling x2apic and Interrupt-remapping " 1323 "because of nox2apic\n");
1330 "because of nox2apic\n");
1331 return; 1324 return;
1332 } 1325 }
1333 1326
@@ -1335,22 +1328,19 @@ void __init enable_IR_x2apic(void)
1335 panic("Bios already enabled x2apic, can't enforce nox2apic"); 1328 panic("Bios already enabled x2apic, can't enforce nox2apic");
1336 1329
1337 if (!x2apic_preenabled && skip_ioapic_setup) { 1330 if (!x2apic_preenabled && skip_ioapic_setup) {
1338 printk(KERN_INFO 1331 pr_info("Skipped enabling x2apic and Interrupt-remapping "
1339 "Skipped enabling x2apic and Interrupt-remapping " 1332 "because of skipping io-apic setup\n");
1340 "because of skipping io-apic setup\n");
1341 return; 1333 return;
1342 } 1334 }
1343 1335
1344 ret = dmar_table_init(); 1336 ret = dmar_table_init();
1345 if (ret) { 1337 if (ret) {
1346 printk(KERN_INFO 1338 pr_info("dmar_table_init() failed with %d:\n", ret);
1347 "dmar_table_init() failed with %d:\n", ret);
1348 1339
1349 if (x2apic_preenabled) 1340 if (x2apic_preenabled)
1350 panic("x2apic enabled by bios. But IR enabling failed"); 1341 panic("x2apic enabled by bios. But IR enabling failed");
1351 else 1342 else
1352 printk(KERN_INFO 1343 pr_info("Not enabling x2apic,Intr-remapping\n");
1353 "Not enabling x2apic,Intr-remapping\n");
1354 return; 1344 return;
1355 } 1345 }
1356 1346
@@ -1359,7 +1349,7 @@ void __init enable_IR_x2apic(void)
1359 1349
1360 ret = save_mask_IO_APIC_setup(); 1350 ret = save_mask_IO_APIC_setup();
1361 if (ret) { 1351 if (ret) {
1362 printk(KERN_INFO "Saving IO-APIC state failed: %d\n", ret); 1352 pr_info("Saving IO-APIC state failed: %d\n", ret);
1363 goto end; 1353 goto end;
1364 } 1354 }
1365 1355
@@ -1394,14 +1384,11 @@ end:
1394 1384
1395 if (!ret) { 1385 if (!ret) {
1396 if (!x2apic_preenabled) 1386 if (!x2apic_preenabled)
1397 printk(KERN_INFO 1387 pr_info("Enabled x2apic and interrupt-remapping\n");
1398 "Enabled x2apic and interrupt-remapping\n");
1399 else 1388 else
1400 printk(KERN_INFO 1389 pr_info("Enabled Interrupt-remapping\n");
1401 "Enabled Interrupt-remapping\n");
1402 } else 1390 } else
1403 printk(KERN_ERR 1391 pr_err("Failed to enable Interrupt-remapping and x2apic\n");
1404 "Failed to enable Interrupt-remapping and x2apic\n");
1405#else 1392#else
1406 if (!cpu_has_x2apic) 1393 if (!cpu_has_x2apic)
1407 return; 1394 return;
@@ -1410,8 +1397,8 @@ end:
1410 panic("x2apic enabled prior OS handover," 1397 panic("x2apic enabled prior OS handover,"
1411 " enable CONFIG_INTR_REMAP"); 1398 " enable CONFIG_INTR_REMAP");
1412 1399
1413 printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping " 1400 pr_info("Enable CONFIG_INTR_REMAP for enabling intr-remapping "
1414 " and x2apic\n"); 1401 " and x2apic\n");
1415#endif 1402#endif
1416 1403
1417 return; 1404 return;
@@ -1428,7 +1415,7 @@ end:
1428static int __init detect_init_APIC(void) 1415static int __init detect_init_APIC(void)
1429{ 1416{
1430 if (!cpu_has_apic) { 1417 if (!cpu_has_apic) {
1431 printk(KERN_INFO "No local APIC present\n"); 1418 pr_info("No local APIC present\n");
1432 return -1; 1419 return -1;
1433 } 1420 }
1434 1421
@@ -1469,8 +1456,8 @@ static int __init detect_init_APIC(void)
1469 * "lapic" specified. 1456 * "lapic" specified.
1470 */ 1457 */
1471 if (!force_enable_local_apic) { 1458 if (!force_enable_local_apic) {
1472 printk(KERN_INFO "Local APIC disabled by BIOS -- " 1459 pr_info("Local APIC disabled by BIOS -- "
1473 "you can enable it with \"lapic\"\n"); 1460 "you can enable it with \"lapic\"\n");
1474 return -1; 1461 return -1;
1475 } 1462 }
1476 /* 1463 /*
@@ -1480,8 +1467,7 @@ static int __init detect_init_APIC(void)
1480 */ 1467 */
1481 rdmsr(MSR_IA32_APICBASE, l, h); 1468 rdmsr(MSR_IA32_APICBASE, l, h);
1482 if (!(l & MSR_IA32_APICBASE_ENABLE)) { 1469 if (!(l & MSR_IA32_APICBASE_ENABLE)) {
1483 printk(KERN_INFO 1470 pr_info("Local APIC disabled by BIOS -- reenabling.\n");
1484 "Local APIC disabled by BIOS -- reenabling.\n");
1485 l &= ~MSR_IA32_APICBASE_BASE; 1471 l &= ~MSR_IA32_APICBASE_BASE;
1486 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; 1472 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
1487 wrmsr(MSR_IA32_APICBASE, l, h); 1473 wrmsr(MSR_IA32_APICBASE, l, h);
@@ -1494,7 +1480,7 @@ static int __init detect_init_APIC(void)
1494 */ 1480 */
1495 features = cpuid_edx(1); 1481 features = cpuid_edx(1);
1496 if (!(features & (1 << X86_FEATURE_APIC))) { 1482 if (!(features & (1 << X86_FEATURE_APIC))) {
1497 printk(KERN_WARNING "Could not enable APIC!\n"); 1483 pr_warning("Could not enable APIC!\n");
1498 return -1; 1484 return -1;
1499 } 1485 }
1500 set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); 1486 set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
@@ -1505,14 +1491,14 @@ static int __init detect_init_APIC(void)
1505 if (l & MSR_IA32_APICBASE_ENABLE) 1491 if (l & MSR_IA32_APICBASE_ENABLE)
1506 mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; 1492 mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
1507 1493
1508 printk(KERN_INFO "Found and enabled local APIC!\n"); 1494 pr_info("Found and enabled local APIC!\n");
1509 1495
1510 apic_pm_activate(); 1496 apic_pm_activate();
1511 1497
1512 return 0; 1498 return 0;
1513 1499
1514no_apic: 1500no_apic:
1515 printk(KERN_INFO "No local APIC present or hardware disabled\n"); 1501 pr_info("No local APIC present or hardware disabled\n");
1516 return -1; 1502 return -1;
1517} 1503}
1518#endif 1504#endif
@@ -1588,12 +1574,12 @@ int __init APIC_init_uniprocessor(void)
1588{ 1574{
1589#ifdef CONFIG_X86_64 1575#ifdef CONFIG_X86_64
1590 if (disable_apic) { 1576 if (disable_apic) {
1591 printk(KERN_INFO "Apic disabled\n"); 1577 pr_info("Apic disabled\n");
1592 return -1; 1578 return -1;
1593 } 1579 }
1594 if (!cpu_has_apic) { 1580 if (!cpu_has_apic) {
1595 disable_apic = 1; 1581 disable_apic = 1;
1596 printk(KERN_INFO "Apic disabled by BIOS\n"); 1582 pr_info("Apic disabled by BIOS\n");
1597 return -1; 1583 return -1;
1598 } 1584 }
1599#else 1585#else
@@ -1605,8 +1591,8 @@ int __init APIC_init_uniprocessor(void)
1605 */ 1591 */
1606 if (!cpu_has_apic && 1592 if (!cpu_has_apic &&
1607 APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { 1593 APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
1608 printk(KERN_ERR "BIOS bug, local APIC 0x%x not detected!...\n", 1594 pr_err("BIOS bug, local APIC 0x%x not detected!...\n",
1609 boot_cpu_physical_apicid); 1595 boot_cpu_physical_apicid);
1610 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); 1596 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
1611 return -1; 1597 return -1;
1612 } 1598 }
@@ -1699,8 +1685,8 @@ void smp_spurious_interrupt(struct pt_regs *regs)
1699 add_pda(irq_spurious_count, 1); 1685 add_pda(irq_spurious_count, 1);
1700#else 1686#else
1701 /* see sw-dev-man vol 3, chapter 7.4.13.5 */ 1687 /* see sw-dev-man vol 3, chapter 7.4.13.5 */
1702 printk(KERN_INFO "spurious APIC interrupt on CPU#%d, " 1688 pr_info("spurious APIC interrupt on CPU#%d, "
1703 "should never happen.\n", smp_processor_id()); 1689 "should never happen.\n", smp_processor_id());
1704 __get_cpu_var(irq_stat).irq_spurious_count++; 1690 __get_cpu_var(irq_stat).irq_spurious_count++;
1705#endif 1691#endif
1706 irq_exit(); 1692 irq_exit();
@@ -1724,17 +1710,18 @@ void smp_error_interrupt(struct pt_regs *regs)
1724 ack_APIC_irq(); 1710 ack_APIC_irq();
1725 atomic_inc(&irq_err_count); 1711 atomic_inc(&irq_err_count);
1726 1712
1727 /* Here is what the APIC error bits mean: 1713 /*
1728 0: Send CS error 1714 * Here is what the APIC error bits mean:
1729 1: Receive CS error 1715 * 0: Send CS error
1730 2: Send accept error 1716 * 1: Receive CS error
1731 3: Receive accept error 1717 * 2: Send accept error
1732 4: Reserved 1718 * 3: Receive accept error
1733 5: Send illegal vector 1719 * 4: Reserved
1734 6: Received illegal vector 1720 * 5: Send illegal vector
1735 7: Illegal register address 1721 * 6: Received illegal vector
1736 */ 1722 * 7: Illegal register address
1737 printk(KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n", 1723 */
1724 pr_debug("APIC error on CPU%d: %02x(%02x)\n",
1738 smp_processor_id(), v , v1); 1725 smp_processor_id(), v , v1);
1739 irq_exit(); 1726 irq_exit();
1740} 1727}
@@ -1838,15 +1825,15 @@ void __cpuinit generic_processor_info(int apicid, int version)
1838 * Validate version 1825 * Validate version
1839 */ 1826 */
1840 if (version == 0x0) { 1827 if (version == 0x0) {
1841 printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! " 1828 pr_warning("BIOS bug, APIC version is 0 for CPU#%d! "
1842 "fixing up to 0x10. (tell your hw vendor)\n", 1829 "fixing up to 0x10. (tell your hw vendor)\n",
1843 version); 1830 version);
1844 version = 0x10; 1831 version = 0x10;
1845 } 1832 }
1846 apic_version[apicid] = version; 1833 apic_version[apicid] = version;
1847 1834
1848 if (num_processors >= NR_CPUS) { 1835 if (num_processors >= NR_CPUS) {
1849 printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." 1836 pr_warning("WARNING: NR_CPUS limit of %i reached."
1850 " Processor ignored.\n", NR_CPUS); 1837 " Processor ignored.\n", NR_CPUS);
1851 return; 1838 return;
1852 } 1839 }
@@ -2209,7 +2196,7 @@ static int __init apic_set_verbosity(char *arg)
2209 else if (strcmp("verbose", arg) == 0) 2196 else if (strcmp("verbose", arg) == 0)
2210 apic_verbosity = APIC_VERBOSE; 2197 apic_verbosity = APIC_VERBOSE;
2211 else { 2198 else {
2212 printk(KERN_WARNING "APIC Verbosity level %s not recognised" 2199 pr_warning("APIC Verbosity level %s not recognised"
2213 " use apic=verbose or apic=debug\n", arg); 2200 " use apic=verbose or apic=debug\n", arg);
2214 return -EINVAL; 2201 return -EINVAL;
2215 } 2202 }
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index 2c97f07f1c2c..13316cf57cdb 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -131,6 +131,11 @@ static void report_broken_nmi(int cpu, int *prev_nmi_count)
131 atomic_dec(&nmi_active); 131 atomic_dec(&nmi_active);
132} 132}
133 133
134static void __acpi_nmi_disable(void *__unused)
135{
136 apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
137}
138
134int __init check_nmi_watchdog(void) 139int __init check_nmi_watchdog(void)
135{ 140{
136 unsigned int *prev_nmi_count; 141 unsigned int *prev_nmi_count;
@@ -179,8 +184,12 @@ int __init check_nmi_watchdog(void)
179 kfree(prev_nmi_count); 184 kfree(prev_nmi_count);
180 return 0; 185 return 0;
181error: 186error:
182 if (nmi_watchdog == NMI_IO_APIC && !timer_through_8259) 187 if (nmi_watchdog == NMI_IO_APIC) {
183 disable_8259A_irq(0); 188 if (!timer_through_8259)
189 disable_8259A_irq(0);
190 on_each_cpu(__acpi_nmi_disable, NULL, 1);
191 }
192
184#ifdef CONFIG_X86_32 193#ifdef CONFIG_X86_32
185 timer_ack = 0; 194 timer_ack = 0;
186#endif 195#endif
@@ -285,11 +294,6 @@ void acpi_nmi_enable(void)
285 on_each_cpu(__acpi_nmi_enable, NULL, 1); 294 on_each_cpu(__acpi_nmi_enable, NULL, 1);
286} 295}
287 296
288static void __acpi_nmi_disable(void *__unused)
289{
290 apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
291}
292
293/* 297/*
294 * Disable timer based NMIs on all CPUs: 298 * Disable timer based NMIs on all CPUs:
295 */ 299 */
@@ -340,6 +344,8 @@ void stop_apic_nmi_watchdog(void *unused)
340 return; 344 return;
341 if (nmi_watchdog == NMI_LOCAL_APIC) 345 if (nmi_watchdog == NMI_LOCAL_APIC)
342 lapic_watchdog_stop(); 346 lapic_watchdog_stop();
347 else
348 __acpi_nmi_disable(NULL);
343 __get_cpu_var(wd_enabled) = 0; 349 __get_cpu_var(wd_enabled) = 0;
344 atomic_dec(&nmi_active); 350 atomic_dec(&nmi_active);
345} 351}
@@ -465,6 +471,24 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
465 471
466#ifdef CONFIG_SYSCTL 472#ifdef CONFIG_SYSCTL
467 473
474static void enable_ioapic_nmi_watchdog_single(void *unused)
475{
476 __get_cpu_var(wd_enabled) = 1;
477 atomic_inc(&nmi_active);
478 __acpi_nmi_enable(NULL);
479}
480
481static void enable_ioapic_nmi_watchdog(void)
482{
483 on_each_cpu(enable_ioapic_nmi_watchdog_single, NULL, 1);
484 touch_nmi_watchdog();
485}
486
487static void disable_ioapic_nmi_watchdog(void)
488{
489 on_each_cpu(stop_apic_nmi_watchdog, NULL, 1);
490}
491
468static int __init setup_unknown_nmi_panic(char *str) 492static int __init setup_unknown_nmi_panic(char *str)
469{ 493{
470 unknown_nmi_panic = 1; 494 unknown_nmi_panic = 1;
@@ -507,6 +531,11 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
507 enable_lapic_nmi_watchdog(); 531 enable_lapic_nmi_watchdog();
508 else 532 else
509 disable_lapic_nmi_watchdog(); 533 disable_lapic_nmi_watchdog();
534 } else if (nmi_watchdog == NMI_IO_APIC) {
535 if (nmi_watchdog_enabled)
536 enable_ioapic_nmi_watchdog();
537 else
538 disable_ioapic_nmi_watchdog();
510 } else { 539 } else {
511 printk(KERN_WARNING 540 printk(KERN_WARNING
512 "NMI watchdog doesn't know what hardware to touch\n"); 541 "NMI watchdog doesn't know what hardware to touch\n");