Skip to content

Commit 6e90894

Browse files
author
Ingo Molnar
committed
x86: fix ioapic bug again
un-revert: commit 4960c9d Author: Thomas Gleixner <[email protected]> Date: Tue Jan 22 10:23:01 2008 +0100 Revert "x86: fix NMI watchdog & 'stopped time' problem" This reverts commit d4d25de. needs a proper fix though ... Signed-off-by: Ingo Molnar <[email protected]>
1 parent f2e576b commit 6e90894

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

arch/x86/kernel/io_apic_32.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,10 +2124,14 @@ static inline void __init check_timer(void)
21242124
{
21252125
int apic1, pin1, apic2, pin2;
21262126
int vector;
2127+
unsigned int ver;
21272128
unsigned long flags;
21282129

21292130
local_irq_save(flags);
21302131

2132+
ver = apic_read(APIC_LVR);
2133+
ver = GET_APIC_VERSION(ver);
2134+
21312135
/*
21322136
* get/set the timer IRQ vector:
21332137
*/
@@ -2140,11 +2144,15 @@ static inline void __init check_timer(void)
21402144
* mode for the 8259A whenever interrupts are routed
21412145
* through I/O APICs. Also IRQ0 has to be enabled in
21422146
* the 8259A which implies the virtual wire has to be
2143-
* disabled in the local APIC.
2147+
* disabled in the local APIC. Finally timer interrupts
2148+
* need to be acknowledged manually in the 8259A for
2149+
* timer_interrupt() and for the i82489DX when using
2150+
* the NMI watchdog.
21442151
*/
21452152
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
21462153
init_8259A(1);
2147-
timer_ack = 1;
2154+
timer_ack = !cpu_has_tsc;
2155+
timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
21482156
if (timer_over_8254 > 0)
21492157
enable_8259A_irq(0);
21502158

arch/x86/kernel/nmi_32.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <asm/smp.h>
2828
#include <asm/nmi.h>
29+
#include <asm/timer.h>
2930

3031
#include "mach_traps.h"
3132

@@ -81,7 +82,7 @@ int __init check_nmi_watchdog(void)
8182

8283
prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
8384
if (!prev_nmi_count)
84-
return -1;
85+
goto error;
8586

8687
printk(KERN_INFO "Testing NMI watchdog ... ");
8788

@@ -118,7 +119,7 @@ int __init check_nmi_watchdog(void)
118119
if (!atomic_read(&nmi_active)) {
119120
kfree(prev_nmi_count);
120121
atomic_set(&nmi_active, -1);
121-
return -1;
122+
goto error;
122123
}
123124
printk("OK.\n");
124125

@@ -129,6 +130,10 @@ int __init check_nmi_watchdog(void)
129130

130131
kfree(prev_nmi_count);
131132
return 0;
133+
error:
134+
timer_ack = !cpu_has_tsc;
135+
136+
return -1;
132137
}
133138

134139
static int __init setup_nmi_watchdog(char *str)

0 commit comments

Comments
 (0)