Skip to content

Commit 9d1988c

Browse files
npigginmpe
authored andcommitted
powerpc/64: treat low kernel text as irqs soft-masked
Treat code below __end_soft_masked as soft-masked for the purpose of alternate return. 64s already mostly does this for scv entry. This will be used to exit from interrupts without disabling MSR[EE]. Signed-off-by: Nicholas Piggin <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 862fa56 commit 9d1988c

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

arch/powerpc/include/asm/interrupt.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,13 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
146146
* CT_WARN_ON comes here via program_check_exception,
147147
* so avoid recursion.
148148
*/
149-
if (TRAP(regs) != INTERRUPT_PROGRAM)
149+
if (TRAP(regs) != INTERRUPT_PROGRAM) {
150150
CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
151+
BUG_ON(regs->nip < (unsigned long)__end_soft_masked);
152+
}
153+
/* Move this under a debugging check */
154+
if (arch_irq_disabled_regs(regs))
155+
BUG_ON(search_kernel_restart_table(regs->nip));
151156
}
152157
#endif
153158

@@ -238,8 +243,8 @@ static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct inte
238243
local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
239244

240245
if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !(regs->msr & MSR_PR) &&
241-
regs->nip < (unsigned long)__end_interrupts) {
242-
// Kernel code running below __end_interrupts is
246+
regs->nip < (unsigned long)__end_soft_masked) {
247+
// Kernel code running below __end_soft_masked is
243248
// implicitly soft-masked.
244249
regs->softe = IRQS_ALL_DISABLED;
245250
}

arch/powerpc/kernel/exceptions-64e.S

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,17 @@ ret_from_mc_except:
342342
#define PROLOG_ADDITION_MASKABLE_GEN(n) \
343343
lbz r10,PACAIRQSOFTMASK(r13); /* are irqs soft-masked? */ \
344344
andi. r10,r10,IRQS_DISABLED; /* yes -> go out of line */ \
345-
bne masked_interrupt_book3e_##n
345+
bne masked_interrupt_book3e_##n; \
346+
/* Kernel code below __end_soft_masked is implicitly masked */ \
347+
andi. r10,r11,MSR_PR; \
348+
bne 1f; /* user -> not masked */ \
349+
std r14,PACA_EXGEN+EX_R14(r13); \
350+
LOAD_REG_IMMEDIATE_SYM(r14, r10, __end_soft_masked); \
351+
mfspr r10,SPRN_SRR0; \
352+
cmpld r10,r14; \
353+
ld r14,PACA_EXGEN+EX_R14(r13); \
354+
blt masked_interrupt_book3e_##n; \
355+
1:
346356

347357
/*
348358
* Additional regs must be re-loaded from paca before EXCEPTION_COMMON* is

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -430,10 +430,13 @@ DEFINE_FIXED_SYMBOL(\name\()_common_real)
430430
andi. r10,r12,MSR_PR
431431
bne 2f
432432

433-
/* Kernel code running below __end_interrupts is implicitly
434-
* soft-masked */
435-
LOAD_HANDLER(r10, __end_interrupts)
433+
/*
434+
* Kernel code running below __end_soft_masked is implicitly
435+
* soft-masked
436+
*/
437+
LOAD_HANDLER(r10, __end_soft_masked)
436438
cmpld r11,r10
439+
437440
li r10,IMASK
438441
blt- 1f
439442

@@ -751,17 +754,17 @@ __start_interrupts:
751754
* scv instructions enter the kernel without changing EE, RI, ME, or HV.
752755
* In particular, this means we can take a maskable interrupt at any point
753756
* in the scv handler, which is unlike any other interrupt. This is solved
754-
* by treating the instruction addresses below __end_interrupts as being
757+
* by treating the instruction addresses below __end_soft_masked as being
755758
* soft-masked.
756759
*
757760
* AIL-0 mode scv exceptions go to 0x17000-0x17fff, but we set AIL-3 and
758761
* ensure scv is never executed with relocation off, which means AIL-0
759762
* should never happen.
760763
*
761-
* Before leaving the below __end_interrupts text, at least of the following
762-
* must be true:
764+
* Before leaving the following inside-__end_soft_masked text, at least of the
765+
* following must be true:
763766
* - MSR[PR]=1 (i.e., return to userspace)
764-
* - MSR_EE|MSR_RI is set (no reentrant exceptions)
767+
* - MSR_EE|MSR_RI is clear (no reentrant exceptions)
765768
* - Standard kernel environment is set up (stack, paca, etc)
766769
*
767770
* Call convention:
@@ -2957,7 +2960,7 @@ MASKED_INTERRUPT hsrr=1
29572960

29582961
USE_FIXED_SECTION(virt_trampolines)
29592962
/*
2960-
* All code below __end_interrupts is treated as soft-masked. If
2963+
* All code below __end_soft_masked is treated as soft-masked. If
29612964
* any code runs here with MSR[EE]=1, it must then cope with pending
29622965
* soft interrupt being raised (i.e., by ensuring it is replayed).
29632966
*

arch/powerpc/kernel/interrupt_64.S

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,4 +632,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
632632
interrupt_return_macro srr
633633
#ifdef CONFIG_PPC_BOOK3S
634634
interrupt_return_macro hsrr
635-
#endif
635+
#endif /* CONFIG_PPC_BOOK3S */
636+
637+
.globl __end_soft_masked
638+
__end_soft_masked:
639+
DEFINE_FIXED_SYMBOL(__end_soft_masked)

0 commit comments

Comments
 (0)