Skip to content

Commit 608328b

Browse files
Christophe Leroy (CS GROUP)maddy-kerneldev
authored andcommitted
powerpc/32: Restore disabling of interrupts at interrupt/syscall exit
Commit 2997876 ("powerpc/32: Restore clearing of MSR[RI] at interrupt/syscall exit") delayed clearing of MSR[RI], but missed that both MSR[RI] and MSR[EE] are cleared at the same time, so the commit also delayed the disabling of interrupts, leading to unexpected behaviour. To fix that, mostly revert the blamed commit and restore the clearing of MSR[RI] in interrupt_exit_kernel_prepare() instead. For 8xx it implies adding a synchronising instruction after the mtspr in order to make sure no instruction counter interrupt (used for perf events) will fire just after clearing MSR[RI]. Reported-by: Christian Zigotzky <chzigotzky@xenosoft.de> Closes: https://lore.kernel.org/all/4d0bd05d-6158-1323-3509-744d3fbe8fc7@xenosoft.de/ Reported-by: Guenter Roeck <linux@roeck-us.net> Closes: https://lore.kernel.org/all/6b05eb1c-fdef-44e0-91a7-8286825e68f1@roeck-us.net/ Fixes: 2997876 ("powerpc/32: Restore clearing of MSR[RI] at interrupt/syscall exit") Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/585ea521b2be99d293b539bbfae148366cfb3687.1766146895.git.chleroy@kernel.org
1 parent fbe409d commit 608328b

4 files changed

Lines changed: 6 additions & 17 deletions

File tree

arch/powerpc/include/asm/hw_irq.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static inline void __hard_EE_RI_disable(void)
9090
if (IS_ENABLED(CONFIG_BOOKE))
9191
wrtee(0);
9292
else if (IS_ENABLED(CONFIG_PPC_8xx))
93-
wrtspr(SPRN_NRI);
93+
wrtspr_sync(SPRN_NRI);
9494
else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
9595
__mtmsrd(0, 1);
9696
else

arch/powerpc/include/asm/reg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,7 @@ static inline void mtmsr_isync(unsigned long val)
14001400
: "r" ((unsigned long)(v)) \
14011401
: "memory")
14021402
#define wrtspr(rn) asm volatile("mtspr " __stringify(rn) ",2" : : : "memory")
1403+
#define wrtspr_sync(rn) asm volatile("mtspr " __stringify(rn) ",2; sync" : : : "memory")
14031404

14041405
static inline void wrtee(unsigned long val)
14051406
{

arch/powerpc/kernel/entry_32.S

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,6 @@ SYM_FUNC_END(__kuep_unlock)
101101
.endm
102102
#endif
103103

104-
.macro clr_ri trash
105-
#ifndef CONFIG_BOOKE
106-
#ifdef CONFIG_PPC_8xx
107-
mtspr SPRN_NRI, \trash
108-
#else
109-
li \trash, MSR_KERNEL & ~MSR_RI
110-
mtmsr \trash
111-
#endif
112-
#endif
113-
.endm
114-
115104
.globl transfer_to_syscall
116105
transfer_to_syscall:
117106
stw r3, ORIG_GPR3(r1)
@@ -160,7 +149,6 @@ ret_from_syscall:
160149
cmpwi r3,0
161150
REST_GPR(3, r1)
162151
syscall_exit_finish:
163-
clr_ri r4
164152
mtspr SPRN_SRR0,r7
165153
mtspr SPRN_SRR1,r8
166154

@@ -237,7 +225,6 @@ fast_exception_return:
237225
/* Clear the exception marker on the stack to avoid confusing stacktrace */
238226
li r10, 0
239227
stw r10, 8(r11)
240-
clr_ri r10
241228
mtspr SPRN_SRR1,r9
242229
mtspr SPRN_SRR0,r12
243230
REST_GPR(9, r11)
@@ -270,7 +257,6 @@ interrupt_return:
270257
.Lfast_user_interrupt_return:
271258
lwz r11,_NIP(r1)
272259
lwz r12,_MSR(r1)
273-
clr_ri r4
274260
mtspr SPRN_SRR0,r11
275261
mtspr SPRN_SRR1,r12
276262

@@ -313,7 +299,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
313299
cmpwi cr1,r3,0
314300
lwz r11,_NIP(r1)
315301
lwz r12,_MSR(r1)
316-
clr_ri r4
317302
mtspr SPRN_SRR0,r11
318303
mtspr SPRN_SRR1,r12
319304

arch/powerpc/kernel/interrupt.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static inline bool exit_must_hard_disable(void)
3838
#else
3939
static inline bool exit_must_hard_disable(void)
4040
{
41-
return false;
41+
return true;
4242
}
4343
#endif
4444

@@ -443,6 +443,9 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
443443

444444
if (unlikely(stack_store))
445445
__hard_EE_RI_disable();
446+
#else
447+
} else {
448+
__hard_EE_RI_disable();
446449
#endif /* CONFIG_PPC64 */
447450
}
448451

0 commit comments

Comments
 (0)