aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Rutland <[email protected]>2021-11-29 13:06:51 +0000
committerThomas Gleixner <[email protected]>2021-12-01 00:06:44 +0100
commit08b0af5b2affbe7419853e8dd1330e4b3fe27125 (patch)
treecb752f27a73706c78c9407156ca579ecc95dc5ba
parent4ea7ce0a79b9450b71b9a88f9f5adbfe2bc3f2e5 (diff)
powerpc: Avoid discarding flags in system_call_exception()
Some thread flags can be set remotely, and so even when IRQs are disabled, the flags can change under our feet. Thus, when setting flags we must use an atomic operation rather than a plain read-modify-write sequence, as a plain read-modify-write may discard flags which are concurrently set by a remote thread, e.g. // task A // task B tmp = A->thread_info.flags; set_tsk_thread_flag(A, NEWFLAG_B); tmp |= NEWFLAG_A; A->thread_info.flags = tmp; arch/powerpc/kernel/interrupt.c's system_call_exception() sets _TIF_RESTOREALL in the thread info flags with a read-modify-write, which may result in other flags being discarded. Elsewhere in the file it uses clear_bits() to atomically remove flag bits, so use set_bits() here for consistency with those. There may be reasons (e.g. instrumentation) that prevent the use of set_thread_flag() and clear_thread_flag() here, which would otherwise be preferable. Fixes: ae7aaecc3f2f78b7 ("powerpc/64s: system call rfscv workaround for TM bugs") Signed-off-by: Mark Rutland <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: Eirik Fuller <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Nicholas Piggin <[email protected]> Link: https://lore.kernel.org/r/[email protected]
-rw-r--r--arch/powerpc/kernel/interrupt.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 835b626cd476..df048e331cbf 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -148,7 +148,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
*/
if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
unlikely(MSR_TM_TRANSACTIONAL(regs->msr)))
- current_thread_info()->flags |= _TIF_RESTOREALL;
+ set_bits(_TIF_RESTOREALL, &current_thread_info()->flags);
/*
* If the system call was made with a transaction active, doom it and