Commit f72dccac authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar

x86: check_timer cleanup

Impact: make check-timer more robust potentially solve boot fragility

For edge trigger io-apic routing, we already unmasked the pin via
setup_IO_APIC_irq(), so don't unmask it again.

Also call local_irq_disable() between timer_irq_works(), because it
calls local_irq_enable() inside.

Also remove not needed apic version reading for 64-bit
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent abcaa2b8
...@@ -1657,7 +1657,7 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, ...@@ -1657,7 +1657,7 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin,
* to the first CPU. * to the first CPU.
*/ */
entry.dest_mode = apic->irq_dest_mode; entry.dest_mode = apic->irq_dest_mode;
entry.mask = 1; /* mask IRQ now */ entry.mask = 0; /* don't mask IRQ for edge */
entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus()); entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus());
entry.delivery_mode = apic->irq_delivery_mode; entry.delivery_mode = apic->irq_delivery_mode;
entry.polarity = 0; entry.polarity = 0;
...@@ -2863,14 +2863,10 @@ static inline void __init check_timer(void) ...@@ -2863,14 +2863,10 @@ static inline void __init check_timer(void)
int cpu = boot_cpu_id; int cpu = boot_cpu_id;
int apic1, pin1, apic2, pin2; int apic1, pin1, apic2, pin2;
unsigned long flags; unsigned long flags;
unsigned int ver;
int no_pin1 = 0; int no_pin1 = 0;
local_irq_save(flags); local_irq_save(flags);
ver = apic_read(APIC_LVR);
ver = GET_APIC_VERSION(ver);
/* /*
* get/set the timer IRQ vector: * get/set the timer IRQ vector:
*/ */
...@@ -2889,7 +2885,13 @@ static inline void __init check_timer(void) ...@@ -2889,7 +2885,13 @@ static inline void __init check_timer(void)
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1); init_8259A(1);
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); {
unsigned int ver;
ver = apic_read(APIC_LVR);
ver = GET_APIC_VERSION(ver);
timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
}
#endif #endif
pin1 = find_isa_irq_pin(0, mp_INT); pin1 = find_isa_irq_pin(0, mp_INT);
...@@ -2928,8 +2930,17 @@ static inline void __init check_timer(void) ...@@ -2928,8 +2930,17 @@ static inline void __init check_timer(void)
if (no_pin1) { if (no_pin1) {
add_pin_to_irq_cpu(cfg, cpu, apic1, pin1); add_pin_to_irq_cpu(cfg, cpu, apic1, pin1);
setup_timer_IRQ0_pin(apic1, pin1, cfg->vector); setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
} else {
/* for edge trigger, setup_IO_APIC_irq already
* leave it unmasked.
* so only need to unmask if it is level-trigger
* do we really have level trigger timer?
*/
int idx;
idx = find_irq_entry(apic1, pin1, mp_INT);
if (idx != -1 && irq_trigger(idx))
unmask_IO_APIC_irq_desc(desc);
} }
unmask_IO_APIC_irq_desc(desc);
if (timer_irq_works()) { if (timer_irq_works()) {
if (nmi_watchdog == NMI_IO_APIC) { if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi(); setup_nmi();
...@@ -2943,6 +2954,7 @@ static inline void __init check_timer(void) ...@@ -2943,6 +2954,7 @@ static inline void __init check_timer(void)
if (intr_remapping_enabled) if (intr_remapping_enabled)
panic("timer doesn't work through Interrupt-remapped IO-APIC"); panic("timer doesn't work through Interrupt-remapped IO-APIC");
#endif #endif
local_irq_disable();
clear_IO_APIC_pin(apic1, pin1); clear_IO_APIC_pin(apic1, pin1);
if (!no_pin1) if (!no_pin1)
apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: " apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
...@@ -2957,7 +2969,6 @@ static inline void __init check_timer(void) ...@@ -2957,7 +2969,6 @@ static inline void __init check_timer(void)
*/ */
replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2); replace_pin_at_irq_cpu(cfg, cpu, apic1, pin1, apic2, pin2);
setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
unmask_IO_APIC_irq_desc(desc);
enable_8259A_irq(0); enable_8259A_irq(0);
if (timer_irq_works()) { if (timer_irq_works()) {
apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
...@@ -2972,6 +2983,7 @@ static inline void __init check_timer(void) ...@@ -2972,6 +2983,7 @@ static inline void __init check_timer(void)
/* /*
* Cleanup, just in case ... * Cleanup, just in case ...
*/ */
local_irq_disable();
disable_8259A_irq(0); disable_8259A_irq(0);
clear_IO_APIC_pin(apic2, pin2); clear_IO_APIC_pin(apic2, pin2);
apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
...@@ -2997,6 +3009,7 @@ static inline void __init check_timer(void) ...@@ -2997,6 +3009,7 @@ static inline void __init check_timer(void)
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
goto out; goto out;
} }
local_irq_disable();
disable_8259A_irq(0); disable_8259A_irq(0);
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
...@@ -3014,6 +3027,7 @@ static inline void __init check_timer(void) ...@@ -3014,6 +3027,7 @@ static inline void __init check_timer(void)
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
goto out; goto out;
} }
local_irq_disable();
apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n"); apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a "
"report. Then try booting with the 'noapic' option.\n"); "report. Then try booting with the 'noapic' option.\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment