powerpc: Avoid discarding flags in system_call_exception()
authorMark Rutland <mark.rutland@arm.com>
Mon, 29 Nov 2021 13:06:51 +0000 (13:06 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jan 2022 10:03:22 +0000 (11:03 +0100)
commit0c1cf578a8822cc1a92c955b87a4b2cd27caed9a
tree418bddc074b45513ef5585f2b1875bb7923c076c
parentf38d669aab337e496e803d56ab22d09b309a902f
powerpc: Avoid discarding flags in system_call_exception()

[ Upstream commit 08b0af5b2affbe7419853e8dd1330e4b3fe27125 ]

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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Eirik Fuller <efuller@redhat.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Link: https://lore.kernel.org/r/20211129130653.2037928-10-mark.rutland@arm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/powerpc/kernel/interrupt.c