aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/apic.c')
-rw-r--r--arch/x86_64/kernel/apic.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index e5b14c57ea..100a30c400 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -342,6 +342,7 @@ void __init init_bsp_APIC(void)
342void __cpuinit setup_local_APIC (void) 342void __cpuinit setup_local_APIC (void)
343{ 343{
344 unsigned int value, maxlvt; 344 unsigned int value, maxlvt;
345 int i, j;
345 346
346 value = apic_read(APIC_LVR); 347 value = apic_read(APIC_LVR);
347 348
@@ -371,6 +372,25 @@ void __cpuinit setup_local_APIC (void)
371 apic_write(APIC_TASKPRI, value); 372 apic_write(APIC_TASKPRI, value);
372 373
373 /* 374 /*
375 * After a crash, we no longer service the interrupts and a pending
376 * interrupt from previous kernel might still have ISR bit set.
377 *
378 * Most probably by now CPU has serviced that pending interrupt and
379 * it might not have done the ack_APIC_irq() because it thought,
380 * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
381 * does not clear the ISR bit and cpu thinks it has already serivced
382 * the interrupt. Hence a vector might get locked. It was noticed
383 * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
384 */
385 for (i = APIC_ISR_NR - 1; i >= 0; i--) {
386 value = apic_read(APIC_ISR + i*0x10);
387 for (j = 31; j >= 0; j--) {
388 if (value & (1<<j))
389 ack_APIC_irq();
390 }
391 }
392
393 /*
374 * Now that we are all set up, enable the APIC 394 * Now that we are all set up, enable the APIC
375 */ 395 */
376 value = apic_read(APIC_SPIV); 396 value = apic_read(APIC_SPIV);
@@ -595,7 +615,7 @@ static int __init apic_set_verbosity(char *str)
595 printk(KERN_WARNING "APIC Verbosity level %s not recognised" 615 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
596 " use apic=verbose or apic=debug", str); 616 " use apic=verbose or apic=debug", str);
597 617
598 return 0; 618 return 1;
599} 619}
600 620
601__setup("apic=", apic_set_verbosity); 621__setup("apic=", apic_set_verbosity);
@@ -1117,35 +1137,35 @@ int __init APIC_init_uniprocessor (void)
1117static __init int setup_disableapic(char *str) 1137static __init int setup_disableapic(char *str)
1118{ 1138{
1119 disable_apic = 1; 1139 disable_apic = 1;
1120 return 0; 1140 return 1;
1121} 1141}
1122 1142
1123static __init int setup_nolapic(char *str) 1143static __init int setup_nolapic(char *str)
1124{ 1144{
1125 disable_apic = 1; 1145 disable_apic = 1;
1126 return 0; 1146 return 1;
1127} 1147}
1128 1148
1129static __init int setup_noapictimer(char *str) 1149static __init int setup_noapictimer(char *str)
1130{ 1150{
1131 if (str[0] != ' ' && str[0] != 0) 1151 if (str[0] != ' ' && str[0] != 0)
1132 return -1; 1152 return 0;
1133 disable_apic_timer = 1; 1153 disable_apic_timer = 1;
1134 return 0; 1154 return 1;
1135} 1155}
1136 1156
1137static __init int setup_apicmaintimer(char *str) 1157static __init int setup_apicmaintimer(char *str)
1138{ 1158{
1139 apic_runs_main_timer = 1; 1159 apic_runs_main_timer = 1;
1140 nohpet = 1; 1160 nohpet = 1;
1141 return 0; 1161 return 1;
1142} 1162}
1143__setup("apicmaintimer", setup_apicmaintimer); 1163__setup("apicmaintimer", setup_apicmaintimer);
1144 1164
1145static __init int setup_noapicmaintimer(char *str) 1165static __init int setup_noapicmaintimer(char *str)
1146{ 1166{
1147 apic_runs_main_timer = -1; 1167 apic_runs_main_timer = -1;
1148 return 0; 1168 return 1;
1149} 1169}
1150__setup("noapicmaintimer", setup_noapicmaintimer); 1170__setup("noapicmaintimer", setup_noapicmaintimer);
1151 1171