diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-01 14:29:12 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-01 14:29:12 -0500 |
commit | 6e07e16404deafadf45895a7d2aeb5feba53b479 (patch) | |
tree | a7025d6632f0b3eb6232eafba79f331ead812fcf /arch/i386/kernel/apic.c | |
parent | 08a556db919f67e1e4d33ae8d40f7222da34d994 (diff) | |
parent | e8e0619f68bff8f39d98c46aac85ed1d4557ccfd (diff) | |
download | kernel-crypto-6e07e16404deafadf45895a7d2aeb5feba53b479.tar.gz kernel-crypto-6e07e16404deafadf45895a7d2aeb5feba53b479.tar.xz kernel-crypto-6e07e16404deafadf45895a7d2aeb5feba53b479.zip |
Merge branch 'upstream'
Diffstat (limited to 'arch/i386/kernel/apic.c')
-rw-r--r-- | arch/i386/kernel/apic.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index eb5279d23b7..6273bf74c20 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -415,6 +415,7 @@ void __init init_bsp_APIC(void) void __devinit setup_local_APIC(void) { unsigned long oldvalue, value, ver, maxlvt; + int i, j; /* Pound the ESR really hard over the head with a big hammer - mbligh */ if (esr_disable) { @@ -452,6 +453,25 @@ void __devinit setup_local_APIC(void) apic_write_around(APIC_TASKPRI, value); /* + * After a crash, we no longer service the interrupts and a pending + * interrupt from previous kernel might still have ISR bit set. + * + * Most probably by now CPU has serviced that pending interrupt and + * it might not have done the ack_APIC_irq() because it thought, + * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it + * does not clear the ISR bit and cpu thinks it has already serivced + * the interrupt. Hence a vector might get locked. It was noticed + * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. + */ + for (i = APIC_ISR_NR - 1; i >= 0; i--) { + value = apic_read(APIC_ISR + i*0x10); + for (j = 31; j >= 0; j--) { + if (value & (1<<j)) + ack_APIC_irq(); + } + } + + /* * Now that we are all set up, enable the APIC */ value = apic_read(APIC_SPIV); @@ -732,7 +752,7 @@ static int __init apic_set_verbosity(char *str) printk(KERN_WARNING "APIC Verbosity level %s not recognised" " use apic=verbose or apic=debug\n", str); - return 0; + return 1; } __setup("apic=", apic_set_verbosity); |