summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorRohan McLure <rmclure@linux.ibm.com>2023-05-10 13:31:10 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2023-06-21 15:13:57 +1000
commitbe286b8637d417a7d7eb25dc3a509c10d0afef66 (patch)
tree8478d86bc6c86a05ebc435ecfbdd1590fabf6832 /arch/powerpc/kernel
parent6f3136326ee47ae2dd5dac9306c9b08ccbc7e81e (diff)
downloadlinux-stable-be286b8637d417a7d7eb25dc3a509c10d0afef66.tar.gz
linux-stable-be286b8637d417a7d7eb25dc3a509c10d0afef66.tar.bz2
linux-stable-be286b8637d417a7d7eb25dc3a509c10d0afef66.zip
powerpc: Mark [h]ssr_valid accesses in check_return_regs_valid
Checks to see if the [H]SRR registers have been clobbered by (soft) NMI interrupts imply the possibility for a data race on the [h]srr_valid entries in the PACA. Annotate accesses to these fields with READ_ONCE, removing the need for the barrier. The diagnostic can use plain-access reads and writes, but annotate with data_race. Signed-off-by: Rohan McLure <rmclure@linux.ibm.com> Reported-by: Michael Ellerman <mpe@ellerman.id.au> Reviewed-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20230510033117.1395895-5-rmclure@linux.ibm.com
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/interrupt.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index f3fc5fe919d9..c4f6d3c69ba9 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -125,7 +125,7 @@ static notrace void check_return_regs_valid(struct pt_regs *regs)
case 0x1600:
case 0x1800:
validp = &local_paca->hsrr_valid;
- if (!*validp)
+ if (!READ_ONCE(*validp))
return;
srr0 = mfspr(SPRN_HSRR0);
@@ -135,7 +135,7 @@ static notrace void check_return_regs_valid(struct pt_regs *regs)
break;
default:
validp = &local_paca->srr_valid;
- if (!*validp)
+ if (!READ_ONCE(*validp))
return;
srr0 = mfspr(SPRN_SRR0);
@@ -161,19 +161,17 @@ static notrace void check_return_regs_valid(struct pt_regs *regs)
* such things will get caught most of the time, statistically
* enough to be able to get a warning out.
*/
- barrier();
-
- if (!*validp)
+ if (!READ_ONCE(*validp))
return;
- if (!warned) {
- warned = true;
+ if (!data_race(warned)) {
+ data_race(warned = true);
printk("%sSRR0 was: %lx should be: %lx\n", h, srr0, regs->nip);
printk("%sSRR1 was: %lx should be: %lx\n", h, srr1, regs->msr);
show_regs(regs);
}
- *validp = 0; /* fixup */
+ WRITE_ONCE(*validp, 0); /* fixup */
#endif
}