* [PATCH v2 0/3] powerpc/64: interrupt soft-mask management fixes
@ 2022-09-06 6:03 Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 1/3] powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending Nicholas Piggin
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Nicholas Piggin @ 2022-09-06 6:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Sachin Sant, Nicholas Piggin
Since last posting I've added more debugging and done some test code
that tires to irritate this on hardware (e.g., put DEC into the
MUST_HARD_MASK category, set_dec(1) in the hash fault handler, run
with perf, etc), and also trigger interrupts at various points stepping
through in the simulator.
I haven't been able to break it. Sachin reported he couldn't reproduce
the previous lockups he saw so possibly that was a red herring.
I'd like to try again to close this if possible, it's probably one of
the last major known uglinesses in the soft masking code.
Thanks,
Nick
Nicholas Piggin (3):
powerpc/64/interrupt: Fix return to masked context after hard-mask irq
becomes pending
powerpc/64s: Fix irq state management in runlatch functions
powerpc/64s/interrupt: masked handler debug check for previous hard
disable
arch/powerpc/include/asm/runlatch.h | 6 ++---
arch/powerpc/kernel/exceptions-64s.S | 10 ++++++++
arch/powerpc/kernel/interrupt.c | 10 --------
arch/powerpc/kernel/interrupt_64.S | 34 +++++++++++++++++++++++++---
4 files changed, 43 insertions(+), 17 deletions(-)
--
2.37.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/3] powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending
2022-09-06 6:03 [PATCH v2 0/3] powerpc/64: interrupt soft-mask management fixes Nicholas Piggin
@ 2022-09-06 6:03 ` Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 2/3] powerpc/64s: Fix irq state management in runlatch functions Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 3/3] powerpc/64s/interrupt: masked handler debug check for previous hard disable Nicholas Piggin
2 siblings, 0 replies; 4+ messages in thread
From: Nicholas Piggin @ 2022-09-06 6:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Sachin Sant, Nicholas Piggin
If a synchronous interrupt (e.g., hash fault) is taken inside an
irqs-disabled region which has MSR[EE]=1, then an asynchronous interrupt
that is PACA_IRQ_MUST_HARD_MASK (e.g., PMI) is taken inside the
synchronous interrupt handler, then the synchronous interrupt will
return with MSR[EE]=1 and the asynchronous interrupt fires again.
If the asynchronous interrupt is a PMI and the original context does not
have PMIs disabled (only Linux IRQs), the asynchronous interrupt will
fire despite having the PMI marked soft pending. This can confuse the
perf code and cause warnings.
This patch changes the interrupt return so that irqs-disabled MSR[EE]=1
contexts will be returned to with MSR[EE]=0 if a PACA_IRQ_MUST_HARD_MASK
interrupt has become pending in the meantime.
The longer explanation for what happens:
1. local_irq_disable()
2. Hash fault interrupt fires, do_hash_fault handler runs
3. interrupt_enter_prepare() sets IRQS_ALL_DISABLED
4. interrupt_enter_prepare() sets MSR[EE]=1
5. PMU interrupt fires, masked handler runs
6. Masked handler marks PMI pending
7. Masked handler returns with PACA_IRQ_HARD_DIS set, MSR[EE]=0
8. do_hash_fault interrupt return handler runs
9. interrupt_exit_kernel_prepare() clears PACA_IRQ_HARD_DIS
10. interrupt returns with MSR[EE]=1
11. PMU interrupt fires, perf handler runs
Fixes: 4423eb5ae32e ("powerpc/64/interrupt: make normal synchronous interrupts enable MSR[EE] if possible")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/interrupt.c | 10 ---------
arch/powerpc/kernel/interrupt_64.S | 34 +++++++++++++++++++++++++++---
2 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 0e75cb03244a..f9db0a172401 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -431,16 +431,6 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
if (unlikely(stack_store))
__hard_EE_RI_disable();
- /*
- * Returning to a kernel context with local irqs disabled.
- * Here, if EE was enabled in the interrupted context, enable
- * it on return as well. A problem exists here where a soft
- * masked interrupt may have cleared MSR[EE] and set HARD_DIS
- * here, and it will still exist on return to the caller. This
- * will be resolved by the masked interrupt firing again.
- */
- if (regs->msr & MSR_EE)
- local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
#endif /* CONFIG_PPC64 */
}
diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
index ce25b28cf418..d76376ce7291 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -559,15 +559,43 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
ld r11,SOFTE(r1)
cmpwi r11,IRQS_ENABLED
stb r11,PACAIRQSOFTMASK(r13)
- bne 1f
+ beq .Linterrupt_return_\srr\()_soft_enabled
+
+ /*
+ * Returning to soft-disabled context.
+ * Check if a MUST_HARD_MASK interrupt has become pending, in which
+ * case we need to disable MSR[EE] in the return context.
+ */
+ ld r12,_MSR(r1)
+ andi. r10,r12,MSR_EE
+ beq .Lfast_kernel_interrupt_return_\srr\() // EE already disabled
+ lbz r11,PACAIRQHAPPENED(r13)
+ andi. r10,r11,PACA_IRQ_MUST_HARD_MASK
+ beq 1f // No HARD_MASK pending
+
+ /* Must clear MSR_EE from _MSR */
+#ifdef CONFIG_PPC_BOOK3S
+ li r10,0
+ /* Clear valid before changing _MSR */
+ .ifc \srr,srr
+ stb r10,PACASRR_VALID(r13)
+ .else
+ stb r10,PACAHSRR_VALID(r13)
+ .endif
+#endif
+ xori r12,r12,MSR_EE
+ std r12,_MSR(r1)
+ b .Lfast_kernel_interrupt_return_\srr\()
+
+.Linterrupt_return_\srr\()_soft_enabled:
#ifdef CONFIG_PPC_BOOK3S
lbz r11,PACAIRQHAPPENED(r13)
andi. r11,r11,(~PACA_IRQ_HARD_DIS)@l
bne- interrupt_return_\srr\()_kernel_restart
#endif
- li r11,0
- stb r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
1:
+ li r11,0
+ stb r11,PACAIRQHAPPENED(r13) // clear the possible HARD_DIS
.Lfast_kernel_interrupt_return_\srr\():
cmpdi cr1,r3,0
--
2.37.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/3] powerpc/64s: Fix irq state management in runlatch functions
2022-09-06 6:03 [PATCH v2 0/3] powerpc/64: interrupt soft-mask management fixes Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 1/3] powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending Nicholas Piggin
@ 2022-09-06 6:03 ` Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 3/3] powerpc/64s/interrupt: masked handler debug check for previous hard disable Nicholas Piggin
2 siblings, 0 replies; 4+ messages in thread
From: Nicholas Piggin @ 2022-09-06 6:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Sachin Sant, Nicholas Piggin
When irqs are soft-disabled, MSR[EE] is volatile and can change from
1 to 0 asynchronously (if a PACA_IRQ_MUST_HARD_MASK interrupt hits).
So it can not be used to check hard IRQ enabled status, except to
confirm it is disabled.
ppc64_runlatch_o* functions use MSR this way to decide whether to
re-enable MSR[EE] after disabling it, which leads to MSR[EE] being
enabled when it shouldn't be (when a PACA_IRQ_MUST_HARD_MASK had
disabled it between reading the MSR and clearing EE).
This has been tolerated in the kernel previously, and it doesn't seem
to cause a problem, but it is ugly and unexpected. Fix this by only
re-enabling if PACA_IRQ_HARD_DIS was set.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/runlatch.h | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/runlatch.h b/arch/powerpc/include/asm/runlatch.h
index cfb390edf7d0..ceb66d761fe1 100644
--- a/arch/powerpc/include/asm/runlatch.h
+++ b/arch/powerpc/include/asm/runlatch.h
@@ -19,10 +19,9 @@ extern void __ppc64_runlatch_off(void);
do { \
if (cpu_has_feature(CPU_FTR_CTRL) && \
test_thread_local_flags(_TLF_RUNLATCH)) { \
- unsigned long msr = mfmsr(); \
__hard_irq_disable(); \
__ppc64_runlatch_off(); \
- if (msr & MSR_EE) \
+ if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) \
__hard_irq_enable(); \
} \
} while (0)
@@ -31,10 +30,9 @@ extern void __ppc64_runlatch_off(void);
do { \
if (cpu_has_feature(CPU_FTR_CTRL) && \
!test_thread_local_flags(_TLF_RUNLATCH)) { \
- unsigned long msr = mfmsr(); \
__hard_irq_disable(); \
__ppc64_runlatch_on(); \
- if (msr & MSR_EE) \
+ if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) \
__hard_irq_enable(); \
} \
} while (0)
--
2.37.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 3/3] powerpc/64s/interrupt: masked handler debug check for previous hard disable
2022-09-06 6:03 [PATCH v2 0/3] powerpc/64: interrupt soft-mask management fixes Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 1/3] powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 2/3] powerpc/64s: Fix irq state management in runlatch functions Nicholas Piggin
@ 2022-09-06 6:03 ` Nicholas Piggin
2 siblings, 0 replies; 4+ messages in thread
From: Nicholas Piggin @ 2022-09-06 6:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Sachin Sant, Nicholas Piggin
Prior changes eliminated cases of masked PACA_IRQ_MUST_HARD_MASK
interrupts that re-fire due to MSR[EE] being enabled while they are
pending. Add a debug check in the masked interrupt handler to catch
if this occurs.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 3d0dc133a9ae..dafa275f18bc 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -2794,6 +2794,16 @@ masked_Hinterrupt:
masked_interrupt:
.endif
stw r9,PACA_EXGEN+EX_CCR(r13)
+#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
+ /*
+ * Ensure there was no previous MUST_HARD_MASK interrupt or
+ * HARD_DIS setting.
+ */
+ lbz r9,PACAIRQHAPPENED(r13)
+ andi. r9,r9,(PACA_IRQ_MUST_HARD_MASK|PACA_IRQ_HARD_DIS)
+0: tdnei r9,0
+ EMIT_BUG_ENTRY 0b,__FILE__,__LINE__,0
+#endif
lbz r9,PACAIRQHAPPENED(r13)
or r9,r9,r10
stb r9,PACAIRQHAPPENED(r13)
--
2.37.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-09-06 6:06 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-06 6:03 [PATCH v2 0/3] powerpc/64: interrupt soft-mask management fixes Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 1/3] powerpc/64/interrupt: Fix return to masked context after hard-mask irq becomes pending Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 2/3] powerpc/64s: Fix irq state management in runlatch functions Nicholas Piggin
2022-09-06 6:03 ` [PATCH v2 3/3] powerpc/64s/interrupt: masked handler debug check for previous hard disable Nicholas Piggin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).