Skip to content

Commit 4423eb5

Browse files
npigginmpe
authored andcommitted
powerpc/64/interrupt: make normal synchronous interrupts enable MSR[EE] if possible
Make synchronous interrupt handler entry wrappers enable MSR[EE] if MSR[EE] was enabled in the interrupted context. IRQs are soft-disabled at this point so there is no change to high level code, but it's a masked interrupt could fire. This is a performance disadvantage for interrupts which do not later call interrupt_cond_local_irq_enable(), because an an additional mtmsrd or wrtee instruction is executed. However the important synchronous interrupts (e.g., page fault) do enable interrupts, so the performance disadvantage is mostly avoided. In the next patch, MSR[RI] enabling can be combined with MSR[EE] enabling, which mitigates the performance drop for the former and gives a performance advanage for the latter interrupts, on 64s machines. 64e is coming along for the ride for now to avoid divergences with 64s in this tricky code. Signed-off-by: Nicholas Piggin <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 0a006ac commit 4423eb5

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

arch/powerpc/include/asm/interrupt.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,20 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
151151
#ifdef CONFIG_PPC64
152152
if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
153153
trace_hardirqs_off();
154-
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
154+
155+
/*
156+
* If the interrupt was taken with HARD_DIS clear, then enable MSR[EE].
157+
* Asynchronous interrupts get here with HARD_DIS set (see below), so
158+
* this enables MSR[EE] for synchronous interrupts. IRQs remain
159+
* soft-masked. The interrupt handler may later call
160+
* interrupt_cond_local_irq_enable() to achieve a regular process
161+
* context.
162+
*/
163+
if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) {
164+
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
165+
BUG_ON(!(regs->msr & MSR_EE));
166+
__hard_irq_enable();
167+
}
155168

156169
if (user_mode(regs)) {
157170
kuap_lock();
@@ -203,6 +216,10 @@ static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt
203216

204217
static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
205218
{
219+
#ifdef CONFIG_PPC64
220+
/* Ensure interrupt_enter_prepare does not enable MSR[EE] */
221+
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
222+
#endif
206223
#ifdef CONFIG_PPC_BOOK3S_64
207224
if (cpu_has_feature(CPU_FTR_CTRL) &&
208225
!test_thread_local_flags(_TLF_RUNLATCH))

0 commit comments

Comments
 (0)