Skip to content

Commit 985faa7

Browse files
mrutland-armKAGA-KOKO
authored andcommitted
powerpc: Snapshot thread flags
Some thread flags can be set remotely, and so even when IRQs are disabled, the flags can change under our feet. Generally this is unlikely to cause a problem in practice, but it is somewhat unsound, and KCSAN will legitimately warn that there is a data race. To avoid such issues, a snapshot of the flags has to be taken prior to using them. Some places already use READ_ONCE() for that, others do not. Convert them all to the new flag accessor helpers. Signed-off-by: Mark Rutland <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: Paul E. McKenney <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Paul Mackerras <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 08b0af5 commit 985faa7

File tree

2 files changed

+7
-9
lines changed

2 files changed

+7
-9
lines changed

arch/powerpc/kernel/interrupt.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
181181

182182
local_irq_enable();
183183

184-
if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
184+
if (unlikely(read_thread_flags() & _TIF_SYSCALL_DOTRACE)) {
185185
if (unlikely(trap_is_unsupported_scv(regs))) {
186186
/* Unsupported scv vector */
187187
_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
@@ -343,7 +343,7 @@ interrupt_exit_user_prepare_main(unsigned long ret, struct pt_regs *regs)
343343
unsigned long ti_flags;
344344

345345
again:
346-
ti_flags = READ_ONCE(current_thread_info()->flags);
346+
ti_flags = read_thread_flags();
347347
while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) {
348348
local_irq_enable();
349349
if (ti_flags & _TIF_NEED_RESCHED) {
@@ -359,7 +359,7 @@ interrupt_exit_user_prepare_main(unsigned long ret, struct pt_regs *regs)
359359
do_notify_resume(regs, ti_flags);
360360
}
361361
local_irq_disable();
362-
ti_flags = READ_ONCE(current_thread_info()->flags);
362+
ti_flags = read_thread_flags();
363363
}
364364

365365
if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && IS_ENABLED(CONFIG_PPC_FPU)) {
@@ -437,7 +437,7 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3,
437437
/* Check whether the syscall is issued inside a restartable sequence */
438438
rseq_syscall(regs);
439439

440-
ti_flags = current_thread_info()->flags;
440+
ti_flags = read_thread_flags();
441441

442442
if (unlikely(r3 >= (unsigned long)-MAX_ERRNO) && is_not_scv) {
443443
if (likely(!(ti_flags & (_TIF_NOERROR | _TIF_RESTOREALL)))) {
@@ -532,8 +532,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
532532
unsigned long flags;
533533
unsigned long ret = 0;
534534
unsigned long kuap;
535-
bool stack_store = current_thread_info()->flags &
536-
_TIF_EMULATE_STACK_STORE;
535+
bool stack_store = read_thread_flags() & _TIF_EMULATE_STACK_STORE;
537536

538537
if (regs_is_unrecoverable(regs))
539538
unrecoverable_exception(regs);
@@ -554,7 +553,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
554553
again:
555554
if (IS_ENABLED(CONFIG_PREEMPT)) {
556555
/* Return to preemptible kernel context */
557-
if (unlikely(current_thread_info()->flags & _TIF_NEED_RESCHED)) {
556+
if (unlikely(read_thread_flags() & _TIF_NEED_RESCHED)) {
558557
if (preempt_count() == 0)
559558
preempt_schedule_irq();
560559
}

arch/powerpc/kernel/ptrace/ptrace.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
260260
{
261261
u32 flags;
262262

263-
flags = READ_ONCE(current_thread_info()->flags) &
264-
(_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
263+
flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
265264

266265
if (flags) {
267266
int rc = tracehook_report_syscall_entry(regs);

0 commit comments

Comments
 (0)