From b5af4d6fbb1d47c6c26e355a1f4f4b1c0c861045 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 21 Mar 2008 14:32:36 +0100 Subject: [PATCH] --- yaml --- r: 88907 b: refs/heads/master c: 6e908947b4995bc0e551a8257c586d5c3e428201 h: refs/heads/master i: 88905: 4ba56fea50b4431b595cb1d652399f060c1ed2b6 88903: 87ead845bc5c2acb9a863fd1dc2827538db6b9e5 v: v3 --- [refs] | 2 +- trunk/arch/x86/kernel/io_apic_32.c | 12 ++++++++++-- trunk/arch/x86/kernel/nmi_32.c | 9 +++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 077779436e23..301c9f60b9bd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f2e576b8141ec1cf2669ff7bbc92f0a9c147f34f +refs/heads/master: 6e908947b4995bc0e551a8257c586d5c3e428201 diff --git a/trunk/arch/x86/kernel/io_apic_32.c b/trunk/arch/x86/kernel/io_apic_32.c index 742fab45e1c6..8ed6eb967652 100644 --- a/trunk/arch/x86/kernel/io_apic_32.c +++ b/trunk/arch/x86/kernel/io_apic_32.c @@ -2124,10 +2124,14 @@ static inline void __init check_timer(void) { int apic1, pin1, apic2, pin2; int vector; + unsigned int ver; unsigned long flags; local_irq_save(flags); + ver = apic_read(APIC_LVR); + ver = GET_APIC_VERSION(ver); + /* * get/set the timer IRQ vector: */ @@ -2140,11 +2144,15 @@ static inline void __init check_timer(void) * mode for the 8259A whenever interrupts are routed * through I/O APICs. Also IRQ0 has to be enabled in * the 8259A which implies the virtual wire has to be - * disabled in the local APIC. + * disabled in the local APIC. Finally timer interrupts + * need to be acknowledged manually in the 8259A for + * timer_interrupt() and for the i82489DX when using + * the NMI watchdog. */ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); init_8259A(1); - timer_ack = 1; + timer_ack = !cpu_has_tsc; + timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); if (timer_over_8254 > 0) enable_8259A_irq(0); diff --git a/trunk/arch/x86/kernel/nmi_32.c b/trunk/arch/x86/kernel/nmi_32.c index 662e63e1cd57..8421d0ac6f22 100644 --- a/trunk/arch/x86/kernel/nmi_32.c +++ b/trunk/arch/x86/kernel/nmi_32.c @@ -26,6 +26,7 @@ #include #include +#include #include "mach_traps.h" @@ -81,7 +82,7 @@ int __init check_nmi_watchdog(void) prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); if (!prev_nmi_count) - return -1; + goto error; printk(KERN_INFO "Testing NMI watchdog ... "); @@ -118,7 +119,7 @@ int __init check_nmi_watchdog(void) if (!atomic_read(&nmi_active)) { kfree(prev_nmi_count); atomic_set(&nmi_active, -1); - return -1; + goto error; } printk("OK.\n"); @@ -129,6 +130,10 @@ int __init check_nmi_watchdog(void) kfree(prev_nmi_count); return 0; +error: + timer_ack = !cpu_has_tsc; + + return -1; } static int __init setup_nmi_watchdog(char *str)