Skip to content

Commit

Permalink
x86/ioapic: Cleanup the timer_works() irqflags mess
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Thomas Gleixner committed Dec 10, 2020
1 parent 26ab12b commit 058df19
Showing 1 changed file with 6 additions and 16 deletions.
22 changes: 6 additions & 16 deletions arch/x86/kernel/apic/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1620,21 +1620,16 @@ static void __init delay_without_tsc(void)
static int __init timer_irq_works(void)
{
unsigned long t1 = jiffies;
unsigned long flags;

if (no_timer_check)
return 1;

local_save_flags(flags);
local_irq_enable();

if (boot_cpu_has(X86_FEATURE_TSC))
delay_with_tsc();
else
delay_without_tsc();

local_irq_restore(flags);

/*
* Expect a few ticks at least, to be sure some possible
* glue logic does not lock up after one or two first
Expand All @@ -1643,10 +1638,10 @@ static int __init timer_irq_works(void)
* least one tick may be lost due to delays.
*/

/* jiffies wrap? */
if (time_after(jiffies, t1 + 4))
return 1;
return 0;
local_irq_disable();

/* Did jiffies advance? */
return time_after(jiffies, t1 + 4);
}

/*
Expand Down Expand Up @@ -2163,13 +2158,12 @@ static inline void __init check_timer(void)
struct irq_cfg *cfg = irqd_cfg(irq_data);
int node = cpu_to_node(0);
int apic1, pin1, apic2, pin2;
unsigned long flags;
int no_pin1 = 0;

if (!global_clock_event)
return;

local_irq_save(flags);
local_irq_disable();

/*
* get/set the timer IRQ vector:
Expand Down Expand Up @@ -2237,7 +2231,6 @@ static inline void __init check_timer(void)
goto out;
}
panic_if_irq_remap("timer doesn't work through Interrupt-remapped IO-APIC");
local_irq_disable();
clear_IO_APIC_pin(apic1, pin1);
if (!no_pin1)
apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
Expand All @@ -2261,7 +2254,6 @@ static inline void __init check_timer(void)
/*
* Cleanup, just in case ...
*/
local_irq_disable();
legacy_pic->mask(0);
clear_IO_APIC_pin(apic2, pin2);
apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
Expand All @@ -2278,7 +2270,6 @@ static inline void __init check_timer(void)
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
goto out;
}
local_irq_disable();
legacy_pic->mask(0);
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
Expand All @@ -2297,7 +2288,6 @@ static inline void __init check_timer(void)
apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
goto out;
}
local_irq_disable();
apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
if (apic_is_x2apic_enabled())
apic_printk(APIC_QUIET, KERN_INFO
Expand All @@ -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 "
"report. Then try booting with the 'noapic' option.\n");
out:
local_irq_restore(flags);
local_irq_enable();
}

/*
Expand Down

0 comments on commit 058df19

Please sign in to comment.