--- linux/arch/i386/kernel/io_apic.c.orig 2004-05-10 14:08:00.000000000 +0200 +++ linux/arch/i386/kernel/io_apic.c 2004-05-10 14:12:17.000000000 +0200 @@ -2159,6 +2159,10 @@ { int pin1, pin2; int vector; + unsigned int ver; + + ver = apic_read(APIC_LVR); + ver = GET_APIC_VERSION(ver); /* * get/set the timer IRQ vector: @@ -2172,11 +2176,15 @@ * 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 + * do_slow_timeoffset() 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); enable_8259A_irq(0); pin1 = find_isa_irq_pin(0, mp_INT); @@ -2194,7 +2202,8 @@ disable_8259A_irq(0); setup_nmi(); enable_8259A_irq(0); - check_nmi_watchdog(); + if (check_nmi_watchdog() < 0) + timer_ack = !cpu_has_tsc; } return; } @@ -2217,7 +2226,8 @@ add_pin_to_irq(0, 0, pin2); if (nmi_watchdog == NMI_IO_APIC) { setup_nmi(); - check_nmi_watchdog(); + if (check_nmi_watchdog() < 0) + timer_ack = !cpu_has_tsc; } return; }