Skip to content

Commit be286b8

Browse files
rohanmclurempe
authored andcommitted
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 <[email protected]> Reported-by: Michael Ellerman <[email protected]> Reviewed-by: Nicholas Piggin <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://msgid.link/[email protected]
1 parent 6f31363 commit be286b8

File tree

2 files changed

+8
-10
lines changed

2 files changed

+8
-10
lines changed

arch/powerpc/include/asm/ptrace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ void do_syscall_trace_leave(struct pt_regs *regs);
180180
static inline void set_return_regs_changed(void)
181181
{
182182
#ifdef CONFIG_PPC_BOOK3S_64
183-
local_paca->hsrr_valid = 0;
184-
local_paca->srr_valid = 0;
183+
WRITE_ONCE(local_paca->hsrr_valid, 0);
184+
WRITE_ONCE(local_paca->srr_valid, 0);
185185
#endif
186186
}
187187

arch/powerpc/kernel/interrupt.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ static notrace void check_return_regs_valid(struct pt_regs *regs)
125125
case 0x1600:
126126
case 0x1800:
127127
validp = &local_paca->hsrr_valid;
128-
if (!*validp)
128+
if (!READ_ONCE(*validp))
129129
return;
130130

131131
srr0 = mfspr(SPRN_HSRR0);
@@ -135,7 +135,7 @@ static notrace void check_return_regs_valid(struct pt_regs *regs)
135135
break;
136136
default:
137137
validp = &local_paca->srr_valid;
138-
if (!*validp)
138+
if (!READ_ONCE(*validp))
139139
return;
140140

141141
srr0 = mfspr(SPRN_SRR0);
@@ -161,19 +161,17 @@ static notrace void check_return_regs_valid(struct pt_regs *regs)
161161
* such things will get caught most of the time, statistically
162162
* enough to be able to get a warning out.
163163
*/
164-
barrier();
165-
166-
if (!*validp)
164+
if (!READ_ONCE(*validp))
167165
return;
168166

169-
if (!warned) {
170-
warned = true;
167+
if (!data_race(warned)) {
168+
data_race(warned = true);
171169
printk("%sSRR0 was: %lx should be: %lx\n", h, srr0, regs->nip);
172170
printk("%sSRR1 was: %lx should be: %lx\n", h, srr1, regs->msr);
173171
show_regs(regs);
174172
}
175173

176-
*validp = 0; /* fixup */
174+
WRITE_ONCE(*validp, 0); /* fixup */
177175
#endif
178176
}
179177

0 commit comments

Comments
 (0)