x86/ioapic: Cleanup the timer_works() irqflags mess

Mark tripped over the creative irqflags handling in the IO-APIC timer
delivery check which ends up doing:

        local_irq_save(flags);
	local_irq_enable();
        local_irq_restore(flags);

which triggered a new consistency check he's working on required for
replacing the POPF based restore with a conditional STI.

That code is a historical mess and none of this is needed. Make it
straightforward use local_irq_disable()/enable() as that's all what is
required. It is invoked from interrupt enabled code nowadays.

Reported-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/87k0tpju47.fsf@nanos.tec.linutronix.de
This commit is contained in:
Thomas Gleixner 2020-12-10 21:15:04 +01:00
parent 26ab12bb9d
commit 058df195c2

@ -1620,21 +1620,16 @@ static void __init delay_without_tsc(void)
static int __init timer_irq_works(void) static int __init timer_irq_works(void)
{ {
unsigned long t1 = jiffies; unsigned long t1 = jiffies;
unsigned long flags;
if (no_timer_check) if (no_timer_check)
return 1; return 1;
local_save_flags(flags);
local_irq_enable(); local_irq_enable();
if (boot_cpu_has(X86_FEATURE_TSC)) if (boot_cpu_has(X86_FEATURE_TSC))
delay_with_tsc(); delay_with_tsc();
else else
delay_without_tsc(); delay_without_tsc();
local_irq_restore(flags);
/* /*
* Expect a few ticks at least, to be sure some possible * Expect a few ticks at least, to be sure some possible
* glue logic does not lock up after one or two first * glue logic does not lock up after one or two first
@ -1643,10 +1638,10 @@ static int __init timer_irq_works(void)
* least one tick may be lost due to delays. * least one tick may be lost due to delays.
*/ */
/* jiffies wrap? */ local_irq_disable();
if (time_after(jiffies, t1 + 4))
return 1; /* Did jiffies advance? */
return 0; return time_after(jiffies, t1 + 4);
} }
/* /*
@ -2163,13 +2158,12 @@ static inline void __init check_timer(void)
struct irq_cfg *cfg = irqd_cfg(irq_data); struct irq_cfg *cfg = irqd_cfg(irq_data);
int node = cpu_to_node(0); int node = cpu_to_node(0);
int apic1, pin1, apic2, pin2; int apic1, pin1, apic2, pin2;
unsigned long flags;
int no_pin1 = 0; int no_pin1 = 0;
if (!global_clock_event) if (!global_clock_event)
return; return;
local_irq_save(flags); local_irq_disable();
/* /*
* get/set the timer IRQ vector: * get/set the timer IRQ vector:
@ -2237,7 +2231,6 @@ static inline void __init check_timer(void)
goto out; goto out;
} }
panic_if_irq_remap("timer doesn't work through Interrupt-remapped IO-APIC"); panic_if_irq_remap("timer doesn't work through Interrupt-remapped IO-APIC");
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: "
@ -2261,7 +2254,6 @@ static inline void __init check_timer(void)
/* /*
* Cleanup, just in case ... * Cleanup, just in case ...
*/ */
local_irq_disable();
legacy_pic->mask(0); legacy_pic->mask(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");
@ -2278,7 +2270,6 @@ 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();
legacy_pic->mask(0); legacy_pic->mask(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");
@ -2297,7 +2288,6 @@ 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");
if (apic_is_x2apic_enabled()) if (apic_is_x2apic_enabled())
apic_printk(APIC_QUIET, KERN_INFO apic_printk(APIC_QUIET, KERN_INFO
@ -2306,7 +2296,7 @@ static inline void __init check_timer(void)
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");
out: out:
local_irq_restore(flags); local_irq_enable();
} }
/* /*