Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powerpc/32: Restore disabling of interrupts at interrupt/syscall exit

Commit 2997876c4a1a ("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: 2997876c4a1a ("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

authored by

Christophe Leroy (CS GROUP) and committed by
Madhavan Srinivasan
608328ba fbe409d1

+6 -17
+1 -1
arch/powerpc/include/asm/hw_irq.h
··· 90 90 if (IS_ENABLED(CONFIG_BOOKE)) 91 91 wrtee(0); 92 92 else if (IS_ENABLED(CONFIG_PPC_8xx)) 93 - wrtspr(SPRN_NRI); 93 + wrtspr_sync(SPRN_NRI); 94 94 else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) 95 95 __mtmsrd(0, 1); 96 96 else
+1
arch/powerpc/include/asm/reg.h
··· 1400 1400 : "r" ((unsigned long)(v)) \ 1401 1401 : "memory") 1402 1402 #define wrtspr(rn) asm volatile("mtspr " __stringify(rn) ",2" : : : "memory") 1403 + #define wrtspr_sync(rn) asm volatile("mtspr " __stringify(rn) ",2; sync" : : : "memory") 1403 1404 1404 1405 static inline void wrtee(unsigned long val) 1405 1406 {
-15
arch/powerpc/kernel/entry_32.S
··· 101 101 .endm 102 102 #endif 103 103 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 - 115 104 .globl transfer_to_syscall 116 105 transfer_to_syscall: 117 106 stw r3, ORIG_GPR3(r1) ··· 149 160 cmpwi r3,0 150 161 REST_GPR(3, r1) 151 162 syscall_exit_finish: 152 - clr_ri r4 153 163 mtspr SPRN_SRR0,r7 154 164 mtspr SPRN_SRR1,r8 155 165 ··· 225 237 /* Clear the exception marker on the stack to avoid confusing stacktrace */ 226 238 li r10, 0 227 239 stw r10, 8(r11) 228 - clr_ri r10 229 240 mtspr SPRN_SRR1,r9 230 241 mtspr SPRN_SRR0,r12 231 242 REST_GPR(9, r11) ··· 257 270 .Lfast_user_interrupt_return: 258 271 lwz r11,_NIP(r1) 259 272 lwz r12,_MSR(r1) 260 - clr_ri r4 261 273 mtspr SPRN_SRR0,r11 262 274 mtspr SPRN_SRR1,r12 263 275 ··· 299 313 cmpwi cr1,r3,0 300 314 lwz r11,_NIP(r1) 301 315 lwz r12,_MSR(r1) 302 - clr_ri r4 303 316 mtspr SPRN_SRR0,r11 304 317 mtspr SPRN_SRR1,r12 305 318
+4 -1
arch/powerpc/kernel/interrupt.c
··· 38 38 #else 39 39 static inline bool exit_must_hard_disable(void) 40 40 { 41 - return false; 41 + return true; 42 42 } 43 43 #endif 44 44 ··· 443 443 444 444 if (unlikely(stack_store)) 445 445 __hard_EE_RI_disable(); 446 + #else 447 + } else { 448 + __hard_EE_RI_disable(); 446 449 #endif /* CONFIG_PPC64 */ 447 450 } 448 451