mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-27 13:43:53 +00:00
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: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
abcaa2b831
commit
f72dccace7
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
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");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user