Skip to content

Commit cc879ab

Browse files
BenjaminGrayNp1mpe
authored andcommitted
powerpc/watchpoints: Disable preemption in thread_change_pc()
thread_change_pc() uses CPU local data, so must be protected from swapping CPUs while it is reading the breakpoint struct. The error is more noticeable after 1e60f35 ("powerpc/watchpoints: Track perf single step directly on the breakpoint"), which added an unconditional __this_cpu_read() call in thread_change_pc(). However the existing __this_cpu_read() that runs if a breakpoint does need to be re-inserted has the same issue. Signed-off-by: Benjamin Gray <bgray@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20230829063457.54157-2-bgray@linux.ibm.com
1 parent 4ff3ba4 commit cc879ab

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

arch/powerpc/kernel/hw_breakpoint.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,15 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
230230
struct arch_hw_breakpoint *info;
231231
int i;
232232

233+
preempt_disable();
234+
233235
for (i = 0; i < nr_wp_slots(); i++) {
234236
struct perf_event *bp = __this_cpu_read(bp_per_reg[i]);
235237

236238
if (unlikely(bp && counter_arch_bp(bp)->perf_single_step))
237239
goto reset;
238240
}
239-
return;
241+
goto out;
240242

241243
reset:
242244
regs_set_return_msr(regs, regs->msr & ~MSR_SE);
@@ -245,6 +247,9 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
245247
__set_breakpoint(i, info);
246248
info->perf_single_step = false;
247249
}
250+
251+
out:
252+
preempt_enable();
248253
}
249254

250255
static bool is_larx_stcx_instr(int type)

0 commit comments

Comments
 (0)