All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv7 00/11]  thread_info: use helpers to snapshot thread flags
@ 2021-11-17 16:30 Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 01/11] thread_info: add " Mark Rutland
                   ` (10 more replies)
  0 siblings, 11 replies; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel, tglx, mingo, peterz
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mpe, npiggin, paulmck, paulus, rth,
	shorne, stefan.kristiansson, vincent.guittot, will

TIP folk (Peter?), I've been assuming this would go via the TIP tree. Are you
happy to pick this up nowish, or as a fixup after the next -rc1? There have
been no significant changes since v3 (aisde from the addition of the PPC fix
for v7), and this has continued to apply cleanly since then (with no conflicts
when rebasing up to v5.16-rc1).

If nothing else, it would be really nice to get the first patch (adding the
accessors) merged, so that we can convert each architecture in turn.

Usual blurb below...

As thread_info::flags scan be manipulated by remote threads, it is
necessary to use atomics or READ_ONCE() to ensure that code manipulates
a consistent snapshot, but we open-code plain accesses to
thread_info::flags across the kernel tree.

Generally we get away with this, but tools like KCSAN legitimately warn
that there is a data-race, and this is potentially fragile with compiler
optimizations, LTO, etc.

These patches introduce new helpers to snapshot the thread flags, with the
intent being that these should replace all plain accesses.

Since v1 [1]:
* Drop RFC
* Make read_ti_thread_flags() __always_inline
* Clarify commit messages
* Fix typo in arm64 patch
* Accumulate Reviewed-by / Acked-by tags
* Drop powerpc patch to avoid potential conflicts (per [2])

Since v2 [3]:
* Rebase to v5.14-rc1
* Reinstate powerpc patch

Since v3 [4]:
* Rebase to v5.14-rc4

Since v4 [5]:
* Rebase to v5.15-rc1
* Apply Acked-by / Tested-by tags

Since v5 [6]:
* Fix trivial whitespace bug in x86 patch

Since v6 [7]:
* Rebase to v5.16-rc1
* Fix new issue on PPC where thread flags could be discarded

[1] https://lore.kernel.org/r/20210609122001.18277-1-mark.rutland@arm.com
[2] https://lore.kernel.org/r/87k0mvtgeb.fsf@mpe.ellerman.id.au
[3] https://lore.kernel.org/r/20210621090602.16883-1-mark.rutland@arm.com
[4] https://lore.kernel.org/r/20210713113842.2106-1-mark.rutland@arm.com
[5] https://lore.kernel.org/r/20210803095428.17009-1-mark.rutland@arm.com
[6] https://lore.kernel.org/r/20210914103027.53565-1-mark.rutland@arm.com
[7] https://lore.kernel.org/lkml/20211022135643.7442-1-mark.rutland@arm.com

Thanks,
Mark.

Mark Rutland (11):
  thread_info: add helpers to snapshot thread flags
  entry: snapshot thread flags
  sched: snapshot thread flags
  alpha: snapshot thread flags
  arm: snapshot thread flags
  arm64: snapshot thread flags
  microblaze: snapshot thread flags
  openrisc: snapshot thread flags
  powerpc: avoid discarding flags in system_call_exception()
  powerpc: snapshot thread flags
  x86: snapshot thread flags

 arch/alpha/kernel/signal.c          |  2 +-
 arch/arm/kernel/signal.c            |  2 +-
 arch/arm/mm/alignment.c             |  2 +-
 arch/arm64/kernel/entry-common.c    |  2 +-
 arch/arm64/kernel/ptrace.c          |  4 ++--
 arch/arm64/kernel/signal.c          |  2 +-
 arch/arm64/kernel/syscall.c         |  4 ++--
 arch/microblaze/kernel/signal.c     |  2 +-
 arch/openrisc/kernel/signal.c       |  2 +-
 arch/powerpc/kernel/interrupt.c     | 15 +++++++--------
 arch/powerpc/kernel/ptrace/ptrace.c |  3 +--
 arch/x86/kernel/process.c           |  8 ++++----
 arch/x86/kernel/process.h           |  4 ++--
 arch/x86/mm/tlb.c                   |  2 +-
 include/linux/entry-kvm.h           |  2 +-
 include/linux/thread_info.h         | 14 ++++++++++++++
 kernel/entry/common.c               |  4 ++--
 kernel/entry/kvm.c                  |  4 ++--
 kernel/sched/core.c                 |  2 +-
 19 files changed, 46 insertions(+), 34 deletions(-)

-- 
2.11.0


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCHv7 01/11] thread_info: add helpers to snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:23   ` [tip: core/entry] thread_info: Add " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 02/11] entry: " Mark Rutland
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

In <linux/thread_info.h> there are helpers to manipulate individual
thread flags, but where code wants to check several flags at once, it
must open code reading current_thread_info()->flags and operating on a
snapshot.

As some flags can be set remotely it's necessary to use READ_ONCE() to
get a consistent snapshot even when IRQs are disabled, but some code
forgets to do this. Generally this is unlike to cause a problem in
practice, but it is somewhat unsound, and KCSAN will legitimately warn
that there is a data race.

To make it easier to do the right thing, and to highlight that
concurrent modification is possible, add new helpers to snapshot the
flags, which should be used in preference to plain reads. Subsequent
patches will move existing code to use the new helpers.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Marco Elver <elver@google.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
---
 include/linux/thread_info.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index ad0c4e041030..73a6f34b3847 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -118,6 +118,15 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
 	return test_bit(flag, (unsigned long *)&ti->flags);
 }
 
+/*
+ * This may be used in noinstr code, and needs to be __always_inline to prevent
+ * inadvertent instrumentation.
+ */
+static __always_inline unsigned long read_ti_thread_flags(struct thread_info *ti)
+{
+	return READ_ONCE(ti->flags);
+}
+
 #define set_thread_flag(flag) \
 	set_ti_thread_flag(current_thread_info(), flag)
 #define clear_thread_flag(flag) \
@@ -130,6 +139,11 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
 	test_and_clear_ti_thread_flag(current_thread_info(), flag)
 #define test_thread_flag(flag) \
 	test_ti_thread_flag(current_thread_info(), flag)
+#define read_thread_flags() \
+	read_ti_thread_flags(current_thread_info())
+
+#define read_task_thread_flags(t) \
+	read_ti_thread_flags(task_thread_info(t))
 
 #ifdef CONFIG_GENERIC_ENTRY
 #define set_syscall_work(fl) \
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 02/11] entry: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 01/11] thread_info: add " Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] entry: Snapshot " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 03/11] sched: snapshot " Mark Rutland
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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 <mark.rutland@arm.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/entry-kvm.h | 2 +-
 kernel/entry/common.c     | 4 ++--
 kernel/entry/kvm.c        | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/entry-kvm.h b/include/linux/entry-kvm.h
index 0d7865a0731c..07c878d6e323 100644
--- a/include/linux/entry-kvm.h
+++ b/include/linux/entry-kvm.h
@@ -75,7 +75,7 @@ static inline void xfer_to_guest_mode_prepare(void)
  */
 static inline bool __xfer_to_guest_mode_work_pending(void)
 {
-	unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
+	unsigned long ti_work = read_thread_flags();
 
 	return !!(ti_work & XFER_TO_GUEST_MODE_WORK);
 }
diff --git a/kernel/entry/common.c b/kernel/entry/common.c
index d5a61d565ad5..bad713684c2e 100644
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -187,7 +187,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 		/* Check if any of the above work has queued a deferred wakeup */
 		tick_nohz_user_enter_prepare();
 
-		ti_work = READ_ONCE(current_thread_info()->flags);
+		ti_work = read_thread_flags();
 	}
 
 	/* Return the latest work state for arch_exit_to_user_mode() */
@@ -196,7 +196,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 
 static void exit_to_user_mode_prepare(struct pt_regs *regs)
 {
-	unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
+	unsigned long ti_work = read_thread_flags();
 
 	lockdep_assert_irqs_disabled();
 
diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
index 49972ee99aff..96d476e06c77 100644
--- a/kernel/entry/kvm.c
+++ b/kernel/entry/kvm.c
@@ -26,7 +26,7 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
 		if (ret)
 			return ret;
 
-		ti_work = READ_ONCE(current_thread_info()->flags);
+		ti_work = read_thread_flags();
 	} while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched());
 	return 0;
 }
@@ -43,7 +43,7 @@ int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
 	 * disabled in the inner loop before going into guest mode. No need
 	 * to disable interrupts here.
 	 */
-	ti_work = READ_ONCE(current_thread_info()->flags);
+	ti_work = read_thread_flags();
 	if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
 		return 0;
 
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 03/11] sched: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 01/11] thread_info: add " Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 02/11] entry: " Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] sched: Snapshot " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 04/11] alpha: snapshot " Mark Rutland
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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.

The READ_ONCE(ti->flags) .. cmpxchg(ti->flags) loop in
set_nr_if_polling() is left as-is for clarity.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
---
 kernel/sched/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3c9b0fda64ac..7ba05dedaf5b 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8520,7 +8520,7 @@ void sched_show_task(struct task_struct *p)
 	rcu_read_unlock();
 	pr_cont(" stack:%5lu pid:%5d ppid:%6d flags:0x%08lx\n",
 		free, task_pid_nr(p), ppid,
-		(unsigned long)task_thread_info(p)->flags);
+		read_task_thread_flags(p));
 
 	print_worker_info(KERN_INFO, p);
 	print_stop_info(KERN_INFO, p);
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 04/11] alpha: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
                   ` (2 preceding siblings ...)
  2021-11-17 16:30 ` [PATCHv7 03/11] sched: snapshot " Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] alpha: Snapshot " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 05/11] arm: snapshot " Mark Rutland
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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 <mark.rutland@arm.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Richard Henderson <rth@twiddle.net>
---
 arch/alpha/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index bc077babafab..d8ed71d5bed3 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -535,6 +535,6 @@ do_work_pending(struct pt_regs *regs, unsigned long thread_flags,
 			}
 		}
 		local_irq_disable();
-		thread_flags = current_thread_info()->flags;
+		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 }
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 05/11] arm: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
                   ` (3 preceding siblings ...)
  2021-11-17 16:30 ` [PATCHv7 04/11] alpha: snapshot " Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] ARM: Snapshot " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 06/11] arm64: snapshot " Mark Rutland
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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 <mark.rutland@arm.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Russell King <linux@armlinux.org.uk>
---
 arch/arm/kernel/signal.c | 2 +-
 arch/arm/mm/alignment.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index a41e27ace391..c532a6041066 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -631,7 +631,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 			}
 		}
 		local_irq_disable();
-		thread_flags = current_thread_info()->flags;
+		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 	return 0;
 }
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index ea81e89e7740..adbb3817d0be 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -990,7 +990,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 		 * there is no work pending for this thread.
 		 */
 		raw_local_irq_disable();
-		if (!(current_thread_info()->flags & _TIF_WORK_MASK))
+		if (!(read_thread_flags() & _TIF_WORK_MASK))
 			set_cr(cr_no_alignment);
 	}
 
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 06/11] arm64: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
                   ` (4 preceding siblings ...)
  2021-11-17 16:30 ` [PATCHv7 05/11] arm: snapshot " Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 07/11] microblaze: " Mark Rutland
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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 <mark.rutland@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/kernel/entry-common.c | 2 +-
 arch/arm64/kernel/ptrace.c       | 4 ++--
 arch/arm64/kernel/signal.c       | 2 +-
 arch/arm64/kernel/syscall.c      | 4 ++--
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index f7408edf8571..ef7fcefb96bd 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -129,7 +129,7 @@ static __always_inline void prepare_exit_to_user_mode(struct pt_regs *regs)
 
 	local_daif_mask();
 
-	flags = READ_ONCE(current_thread_info()->flags);
+	flags = read_thread_flags();
 	if (unlikely(flags & _TIF_WORK_MASK))
 		do_notify_resume(regs, flags);
 }
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 88a9034fb9b5..33cac3d75150 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1839,7 +1839,7 @@ static void tracehook_report_syscall(struct pt_regs *regs,
 
 int syscall_trace_enter(struct pt_regs *regs)
 {
-	unsigned long flags = READ_ONCE(current_thread_info()->flags);
+	unsigned long flags = read_thread_flags();
 
 	if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
 		tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
@@ -1862,7 +1862,7 @@ int syscall_trace_enter(struct pt_regs *regs)
 
 void syscall_trace_exit(struct pt_regs *regs)
 {
-	unsigned long flags = READ_ONCE(current_thread_info()->flags);
+	unsigned long flags = read_thread_flags();
 
 	audit_syscall_exit(regs);
 
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 8f6372b44b65..d8aaf4b6f432 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -948,7 +948,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
 		}
 
 		local_daif_mask();
-		thread_flags = READ_ONCE(current_thread_info()->flags);
+		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 }
 
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 50a0f1a38e84..c938603b3ba0 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -81,7 +81,7 @@ void syscall_trace_exit(struct pt_regs *regs);
 static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 			   const syscall_fn_t syscall_table[])
 {
-	unsigned long flags = current_thread_info()->flags;
+	unsigned long flags = read_thread_flags();
 
 	regs->orig_x0 = regs->regs[0];
 	regs->syscallno = scno;
@@ -148,7 +148,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 	 */
 	if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
 		local_daif_mask();
-		flags = current_thread_info()->flags;
+		flags = read_thread_flags();
 		if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP))
 			return;
 		local_daif_restore(DAIF_PROCCTX);
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 07/11] microblaze: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
                   ` (5 preceding siblings ...)
  2021-11-17 16:30 ` [PATCHv7 06/11] arm64: snapshot " Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] microblaze: Snapshot " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 08/11] openrisc: snapshot " Mark Rutland
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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 <mark.rutland@arm.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Tested-by: Michal Simek <michal.simek@xilinx.com>
---
 arch/microblaze/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index fc61eb0eb8dd..23e8a9336a29 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -283,7 +283,7 @@ static void do_signal(struct pt_regs *regs, int in_syscall)
 #ifdef DEBUG_SIG
 	pr_info("do signal: %p %d\n", regs, in_syscall);
 	pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
-			regs->r12, current_thread_info()->flags);
+			regs->r12, read_thread_flags());
 #endif
 
 	if (get_signal(&ksig)) {
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 08/11] openrisc: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
                   ` (6 preceding siblings ...)
  2021-11-17 16:30 ` [PATCHv7 07/11] microblaze: " Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] openrisc: Snapshot " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception() Mark Rutland
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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 <mark.rutland@arm.com>
Acked-by: Stafford Horne <shorne@gmail.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
---
 arch/openrisc/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index 99516c9191c7..92c5b70740f5 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -313,7 +313,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 			}
 		}
 		local_irq_disable();
-		thread_flags = current_thread_info()->flags;
+		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 	return 0;
 }
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception()
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
                   ` (7 preceding siblings ...)
  2021-11-17 16:30 ` [PATCHv7 08/11] openrisc: snapshot " Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-17 21:39   ` kernel test robot
                     ` (2 more replies)
  2021-11-17 16:30 ` [PATCHv7 10/11] powerpc: snapshot thread flags Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 11/11] x86: snapshot " Mark Rutland
  10 siblings, 3 replies; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel, Michael Ellerman
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, npiggin, paulmck, paulus, peterz,
	rth, shorne, stefan.kristiansson, tglx, vincent.guittot, will

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;

In arch/powerpc/kernel/interrupt.c's system_call_exception(), we set
_TIF_RESTOREALL in the thread info flags with a read-modify-write, which
may result in other flags being discarded.

Elsewhere in the file we use clear_bits() to atomically remove flag
bits, so let's use set_bits() here for consistency with those.

I presume 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>
Cc: Eirik Fuller <efuller@redhat.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/kernel/interrupt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Michael, I found this by inspection when rebasing the rest of the series
to v5.16-rc1. Is this something you'd like to pick on its own? As the
commit message says, I'm not sure whether you can use
{set,clear}_thread_flag() here, or whether it was a deliberate choice to
avoid those.

Mark.

diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 835b626cd476..1c821b76c2d1 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
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 10/11] powerpc: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
                   ` (8 preceding siblings ...)
  2021-11-17 16:30 ` [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception() Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] powerpc: Snapshot " tip-bot2 for Mark Rutland
  2021-11-17 16:30 ` [PATCHv7 11/11] x86: snapshot " Mark Rutland
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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 <mark.rutland@arm.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/kernel/interrupt.c     | 13 ++++++-------
 arch/powerpc/kernel/ptrace/ptrace.c |  3 +--
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 1c821b76c2d1..ff25888ffc25 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -181,7 +181,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
 
 	local_irq_enable();
 
-	if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
+	if (unlikely(read_thread_flags() & _TIF_SYSCALL_DOTRACE)) {
 		if (unlikely(trap_is_unsupported_scv(regs))) {
 			/* Unsupported scv vector */
 			_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
@@ -343,7 +343,7 @@ interrupt_exit_user_prepare_main(unsigned long ret, struct pt_regs *regs)
 	unsigned long ti_flags;
 
 again:
-	ti_flags = READ_ONCE(current_thread_info()->flags);
+	ti_flags = read_thread_flags();
 	while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) {
 		local_irq_enable();
 		if (ti_flags & _TIF_NEED_RESCHED) {
@@ -359,7 +359,7 @@ interrupt_exit_user_prepare_main(unsigned long ret, struct pt_regs *regs)
 			do_notify_resume(regs, ti_flags);
 		}
 		local_irq_disable();
-		ti_flags = READ_ONCE(current_thread_info()->flags);
+		ti_flags = read_thread_flags();
 	}
 
 	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,
 	/* Check whether the syscall is issued inside a restartable sequence */
 	rseq_syscall(regs);
 
-	ti_flags = current_thread_info()->flags;
+	ti_flags = read_thread_flags();
 
 	if (unlikely(r3 >= (unsigned long)-MAX_ERRNO) && is_not_scv) {
 		if (likely(!(ti_flags & (_TIF_NOERROR | _TIF_RESTOREALL)))) {
@@ -532,8 +532,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
 	unsigned long flags;
 	unsigned long ret = 0;
 	unsigned long kuap;
-	bool stack_store = current_thread_info()->flags &
-						_TIF_EMULATE_STACK_STORE;
+	bool stack_store = read_thread_flags() & _TIF_EMULATE_STACK_STORE;
 
 	if (regs_is_unrecoverable(regs))
 		unrecoverable_exception(regs);
@@ -554,7 +553,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
 again:
 		if (IS_ENABLED(CONFIG_PREEMPT)) {
 			/* Return to preemptible kernel context */
-			if (unlikely(current_thread_info()->flags & _TIF_NEED_RESCHED)) {
+			if (unlikely(read_thread_flags() & _TIF_NEED_RESCHED)) {
 				if (preempt_count() == 0)
 					preempt_schedule_irq();
 			}
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index 7c7093c17c45..c43f77e2ac31 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -260,8 +260,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
 {
 	u32 flags;
 
-	flags = READ_ONCE(current_thread_info()->flags) &
-		(_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
+	flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
 
 	if (flags) {
 		int rc = tracehook_report_syscall_entry(regs);
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCHv7 11/11] x86: snapshot thread flags
  2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
                   ` (9 preceding siblings ...)
  2021-11-17 16:30 ` [PATCHv7 10/11] powerpc: snapshot thread flags Mark Rutland
@ 2021-11-17 16:30 ` Mark Rutland
  2021-11-26 20:22   ` [tip: core/entry] x86: Snapshot " tip-bot2 for Mark Rutland
  10 siblings, 1 reply; 25+ messages in thread
From: Mark Rutland @ 2021-11-17 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: benh, boqun.feng, bp, catalin.marinas, dvyukov, efuller, elver,
	ink, joey.gouly, jonas, juri.lelli, linux, luto, mark.rutland,
	mattst88, michal.simek, mingo, mpe, npiggin, paulmck, paulus,
	peterz, rth, shorne, stefan.kristiansson, tglx, vincent.guittot,
	will

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 <mark.rutland@arm.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Ingo Molnar <mingo@redhat.com>
---
 arch/x86/kernel/process.c | 8 ++++----
 arch/x86/kernel/process.h | 4 ++--
 arch/x86/mm/tlb.c         | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index e9ee8b526319..180d7a00cb66 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -365,7 +365,7 @@ void arch_setup_new_exec(void)
 		clear_thread_flag(TIF_SSBD);
 		task_clear_spec_ssb_disable(current);
 		task_clear_spec_ssb_noexec(current);
-		speculation_ctrl_update(task_thread_info(current)->flags);
+		speculation_ctrl_update(read_thread_flags());
 	}
 }
 
@@ -617,7 +617,7 @@ static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk)
 			clear_tsk_thread_flag(tsk, TIF_SPEC_IB);
 	}
 	/* Return the updated threadinfo flags*/
-	return task_thread_info(tsk)->flags;
+	return read_task_thread_flags(tsk);
 }
 
 void speculation_ctrl_update(unsigned long tif)
@@ -653,8 +653,8 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p)
 {
 	unsigned long tifp, tifn;
 
-	tifn = READ_ONCE(task_thread_info(next_p)->flags);
-	tifp = READ_ONCE(task_thread_info(prev_p)->flags);
+	tifn = read_task_thread_flags(next_p);
+	tifp = read_task_thread_flags(prev_p);
 
 	switch_to_bitmap(tifp);
 
diff --git a/arch/x86/kernel/process.h b/arch/x86/kernel/process.h
index 1d0797b2338a..76b547b83232 100644
--- a/arch/x86/kernel/process.h
+++ b/arch/x86/kernel/process.h
@@ -13,8 +13,8 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p);
 static inline void switch_to_extra(struct task_struct *prev,
 				   struct task_struct *next)
 {
-	unsigned long next_tif = task_thread_info(next)->flags;
-	unsigned long prev_tif = task_thread_info(prev)->flags;
+	unsigned long next_tif = read_task_thread_flags(next);
+	unsigned long prev_tif = read_task_thread_flags(prev);
 
 	if (IS_ENABLED(CONFIG_SMP)) {
 		/*
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 59ba2968af1b..92bb03b9ceb5 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -361,7 +361,7 @@ static void l1d_flush_evaluate(unsigned long prev_mm, unsigned long next_mm,
 
 static unsigned long mm_mangle_tif_spec_bits(struct task_struct *next)
 {
-	unsigned long next_tif = task_thread_info(next)->flags;
+	unsigned long next_tif = read_task_thread_flags(next);
 	unsigned long spec_bits = (next_tif >> TIF_SPEC_IB) & LAST_USER_MM_SPEC_MASK;
 
 	/*
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception()
  2021-11-17 16:30 ` [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception() Mark Rutland
@ 2021-11-17 21:39   ` kernel test robot
  2021-11-17 22:17   ` kernel test robot
  2021-11-26 20:22   ` [tip: core/entry] powerpc: Avoid " tip-bot2 for Mark Rutland
  2 siblings, 0 replies; 25+ messages in thread
From: kernel test robot @ 2021-11-17 21:39 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 8934 bytes --]

Hi Mark,

I love your patch! Yet something to improve:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on powerpc/next linus/master v5.16-rc1 next-20211117]
[cannot apply to tip/core/entry]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Mark-Rutland/thread_info-use-helpers-to-snapshot-thread-flags/20211118-004322
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/e1afc9f363490d24e2c29f28f27ba8673d9c8612
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Mark-Rutland/thread_info-use-helpers-to-snapshot-thread-flags/20211118-004322
        git checkout e1afc9f363490d24e2c29f28f27ba8673d9c8612
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   arch/powerpc/kernel/interrupt.c: In function 'system_call_exception':
>> arch/powerpc/kernel/interrupt.c:151:64: error: passing argument 2 of 'set_bits' makes pointer from integer without a cast [-Werror=int-conversion]
     151 |                 set_bits(_TIF_RESTOREALL, current_thread_info()->flags);
   In file included from include/linux/bitops.h:33,
                    from include/linux/kernel.h:12,
                    from include/linux/list.h:9,
                    from include/linux/rculist.h:10,
                    from include/linux/pid.h:5,
                    from include/linux/sched.h:14,
                    from include/linux/context_tracking.h:5,
                    from arch/powerpc/kernel/interrupt.c:3:
   arch/powerpc/include/asm/bitops.h:67:41: note: expected 'volatile long unsigned int *' but argument is of type 'long unsigned int'
      67 |                 volatile unsigned long *_p)     \
         |                 ~~~~~~~~~~~~~~~~~~~~~~~~^~
   arch/powerpc/include/asm/bitops.h:82:1: note: in expansion of macro 'DEFINE_BITOP'
      82 | DEFINE_BITOP(set_bits, or, "")
         | ^~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/set_bits +151 arch/powerpc/kernel/interrupt.c

    76	
    77	/* Has to run notrace because it is entered not completely "reconciled" */
    78	notrace long system_call_exception(long r3, long r4, long r5,
    79					   long r6, long r7, long r8,
    80					   unsigned long r0, struct pt_regs *regs)
    81	{
    82		syscall_fn f;
    83	
    84		kuep_lock();
    85	
    86		regs->orig_gpr3 = r3;
    87	
    88		if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
    89			BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
    90	
    91		trace_hardirqs_off(); /* finish reconciling */
    92	
    93		CT_WARN_ON(ct_state() == CONTEXT_KERNEL);
    94		user_exit_irqoff();
    95	
    96		BUG_ON(regs_is_unrecoverable(regs));
    97		BUG_ON(!(regs->msr & MSR_PR));
    98		BUG_ON(arch_irq_disabled_regs(regs));
    99	
   100	#ifdef CONFIG_PPC_PKEY
   101		if (mmu_has_feature(MMU_FTR_PKEY)) {
   102			unsigned long amr, iamr;
   103			bool flush_needed = false;
   104			/*
   105			 * When entering from userspace we mostly have the AMR/IAMR
   106			 * different from kernel default values. Hence don't compare.
   107			 */
   108			amr = mfspr(SPRN_AMR);
   109			iamr = mfspr(SPRN_IAMR);
   110			regs->amr  = amr;
   111			regs->iamr = iamr;
   112			if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) {
   113				mtspr(SPRN_AMR, AMR_KUAP_BLOCKED);
   114				flush_needed = true;
   115			}
   116			if (mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) {
   117				mtspr(SPRN_IAMR, AMR_KUEP_BLOCKED);
   118				flush_needed = true;
   119			}
   120			if (flush_needed)
   121				isync();
   122		} else
   123	#endif
   124			kuap_assert_locked();
   125	
   126		booke_restore_dbcr0();
   127	
   128		account_cpu_user_entry();
   129	
   130		account_stolen_time();
   131	
   132		/*
   133		 * This is not required for the syscall exit path, but makes the
   134		 * stack frame look nicer. If this was initialised in the first stack
   135		 * frame, or if the unwinder was taught the first stack frame always
   136		 * returns to user with IRQS_ENABLED, this store could be avoided!
   137		 */
   138		irq_soft_mask_regs_set_state(regs, IRQS_ENABLED);
   139	
   140		/*
   141		 * If system call is called with TM active, set _TIF_RESTOREALL to
   142		 * prevent RFSCV being used to return to userspace, because POWER9
   143		 * TM implementation has problems with this instruction returning to
   144		 * transactional state. Final register values are not relevant because
   145		 * the transaction will be aborted upon return anyway. Or in the case
   146		 * of unsupported_scv SIGILL fault, the return state does not much
   147		 * matter because it's an edge case.
   148		 */
   149		if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
   150				unlikely(MSR_TM_TRANSACTIONAL(regs->msr)))
 > 151			set_bits(_TIF_RESTOREALL, current_thread_info()->flags);
   152	
   153		/*
   154		 * If the system call was made with a transaction active, doom it and
   155		 * return without performing the system call. Unless it was an
   156		 * unsupported scv vector, in which case it's treated like an illegal
   157		 * instruction.
   158		 */
   159	#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
   160		if (unlikely(MSR_TM_TRANSACTIONAL(regs->msr)) &&
   161		    !trap_is_unsupported_scv(regs)) {
   162			/* Enable TM in the kernel, and disable EE (for scv) */
   163			hard_irq_disable();
   164			mtmsr(mfmsr() | MSR_TM);
   165	
   166			/* tabort, this dooms the transaction, nothing else */
   167			asm volatile(".long 0x7c00071d | ((%0) << 16)"
   168					:: "r"(TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT));
   169	
   170			/*
   171			 * Userspace will never see the return value. Execution will
   172			 * resume after the tbegin. of the aborted transaction with the
   173			 * checkpointed register state. A context switch could occur
   174			 * or signal delivered to the process before resuming the
   175			 * doomed transaction context, but that should all be handled
   176			 * as expected.
   177			 */
   178			return -ENOSYS;
   179		}
   180	#endif // CONFIG_PPC_TRANSACTIONAL_MEM
   181	
   182		local_irq_enable();
   183	
   184		if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
   185			if (unlikely(trap_is_unsupported_scv(regs))) {
   186				/* Unsupported scv vector */
   187				_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
   188				return regs->gpr[3];
   189			}
   190			/*
   191			 * We use the return value of do_syscall_trace_enter() as the
   192			 * syscall number. If the syscall was rejected for any reason
   193			 * do_syscall_trace_enter() returns an invalid syscall number
   194			 * and the test against NR_syscalls will fail and the return
   195			 * value to be used is in regs->gpr[3].
   196			 */
   197			r0 = do_syscall_trace_enter(regs);
   198			if (unlikely(r0 >= NR_syscalls))
   199				return regs->gpr[3];
   200			r3 = regs->gpr[3];
   201			r4 = regs->gpr[4];
   202			r5 = regs->gpr[5];
   203			r6 = regs->gpr[6];
   204			r7 = regs->gpr[7];
   205			r8 = regs->gpr[8];
   206	
   207		} else if (unlikely(r0 >= NR_syscalls)) {
   208			if (unlikely(trap_is_unsupported_scv(regs))) {
   209				/* Unsupported scv vector */
   210				_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
   211				return regs->gpr[3];
   212			}
   213			return -ENOSYS;
   214		}
   215	
   216		/* May be faster to do array_index_nospec? */
   217		barrier_nospec();
   218	
   219		if (unlikely(is_compat_task())) {
   220			f = (void *)compat_sys_call_table[r0];
   221	
   222			r3 &= 0x00000000ffffffffULL;
   223			r4 &= 0x00000000ffffffffULL;
   224			r5 &= 0x00000000ffffffffULL;
   225			r6 &= 0x00000000ffffffffULL;
   226			r7 &= 0x00000000ffffffffULL;
   227			r8 &= 0x00000000ffffffffULL;
   228	
   229		} else {
   230			f = (void *)sys_call_table[r0];
   231		}
   232	
   233		return f(r3, r4, r5, r6, r7, r8);
   234	}
   235	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 7634 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception()
  2021-11-17 16:30 ` [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception() Mark Rutland
  2021-11-17 21:39   ` kernel test robot
@ 2021-11-17 22:17   ` kernel test robot
  2021-11-26 20:22   ` [tip: core/entry] powerpc: Avoid " tip-bot2 for Mark Rutland
  2 siblings, 0 replies; 25+ messages in thread
From: kernel test robot @ 2021-11-17 22:17 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 8895 bytes --]

Hi Mark,

I love your patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on powerpc/next linus/master v5.16-rc1 next-20211117]
[cannot apply to tip/core/entry]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Mark-Rutland/thread_info-use-helpers-to-snapshot-thread-flags/20211118-004322
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/e1afc9f363490d24e2c29f28f27ba8673d9c8612
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Mark-Rutland/thread_info-use-helpers-to-snapshot-thread-flags/20211118-004322
        git checkout e1afc9f363490d24e2c29f28f27ba8673d9c8612
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   arch/powerpc/kernel/interrupt.c: In function 'system_call_exception':
>> arch/powerpc/kernel/interrupt.c:151:64: warning: passing argument 2 of 'set_bits' makes pointer from integer without a cast [-Wint-conversion]
     151 |                 set_bits(_TIF_RESTOREALL, current_thread_info()->flags);
   In file included from include/linux/bitops.h:33,
                    from include/linux/kernel.h:12,
                    from include/linux/list.h:9,
                    from include/linux/rculist.h:10,
                    from include/linux/pid.h:5,
                    from include/linux/sched.h:14,
                    from include/linux/context_tracking.h:5,
                    from arch/powerpc/kernel/interrupt.c:3:
   arch/powerpc/include/asm/bitops.h:67:41: note: expected 'volatile long unsigned int *' but argument is of type 'long unsigned int'
      67 |                 volatile unsigned long *_p)     \
         |                 ~~~~~~~~~~~~~~~~~~~~~~~~^~
   arch/powerpc/include/asm/bitops.h:82:1: note: in expansion of macro 'DEFINE_BITOP'
      82 | DEFINE_BITOP(set_bits, or, "")
         | ^~~~~~~~~~~~


vim +/set_bits +151 arch/powerpc/kernel/interrupt.c

    76	
    77	/* Has to run notrace because it is entered not completely "reconciled" */
    78	notrace long system_call_exception(long r3, long r4, long r5,
    79					   long r6, long r7, long r8,
    80					   unsigned long r0, struct pt_regs *regs)
    81	{
    82		syscall_fn f;
    83	
    84		kuep_lock();
    85	
    86		regs->orig_gpr3 = r3;
    87	
    88		if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
    89			BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
    90	
    91		trace_hardirqs_off(); /* finish reconciling */
    92	
    93		CT_WARN_ON(ct_state() == CONTEXT_KERNEL);
    94		user_exit_irqoff();
    95	
    96		BUG_ON(regs_is_unrecoverable(regs));
    97		BUG_ON(!(regs->msr & MSR_PR));
    98		BUG_ON(arch_irq_disabled_regs(regs));
    99	
   100	#ifdef CONFIG_PPC_PKEY
   101		if (mmu_has_feature(MMU_FTR_PKEY)) {
   102			unsigned long amr, iamr;
   103			bool flush_needed = false;
   104			/*
   105			 * When entering from userspace we mostly have the AMR/IAMR
   106			 * different from kernel default values. Hence don't compare.
   107			 */
   108			amr = mfspr(SPRN_AMR);
   109			iamr = mfspr(SPRN_IAMR);
   110			regs->amr  = amr;
   111			regs->iamr = iamr;
   112			if (mmu_has_feature(MMU_FTR_BOOK3S_KUAP)) {
   113				mtspr(SPRN_AMR, AMR_KUAP_BLOCKED);
   114				flush_needed = true;
   115			}
   116			if (mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) {
   117				mtspr(SPRN_IAMR, AMR_KUEP_BLOCKED);
   118				flush_needed = true;
   119			}
   120			if (flush_needed)
   121				isync();
   122		} else
   123	#endif
   124			kuap_assert_locked();
   125	
   126		booke_restore_dbcr0();
   127	
   128		account_cpu_user_entry();
   129	
   130		account_stolen_time();
   131	
   132		/*
   133		 * This is not required for the syscall exit path, but makes the
   134		 * stack frame look nicer. If this was initialised in the first stack
   135		 * frame, or if the unwinder was taught the first stack frame always
   136		 * returns to user with IRQS_ENABLED, this store could be avoided!
   137		 */
   138		irq_soft_mask_regs_set_state(regs, IRQS_ENABLED);
   139	
   140		/*
   141		 * If system call is called with TM active, set _TIF_RESTOREALL to
   142		 * prevent RFSCV being used to return to userspace, because POWER9
   143		 * TM implementation has problems with this instruction returning to
   144		 * transactional state. Final register values are not relevant because
   145		 * the transaction will be aborted upon return anyway. Or in the case
   146		 * of unsupported_scv SIGILL fault, the return state does not much
   147		 * matter because it's an edge case.
   148		 */
   149		if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
   150				unlikely(MSR_TM_TRANSACTIONAL(regs->msr)))
 > 151			set_bits(_TIF_RESTOREALL, current_thread_info()->flags);
   152	
   153		/*
   154		 * If the system call was made with a transaction active, doom it and
   155		 * return without performing the system call. Unless it was an
   156		 * unsupported scv vector, in which case it's treated like an illegal
   157		 * instruction.
   158		 */
   159	#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
   160		if (unlikely(MSR_TM_TRANSACTIONAL(regs->msr)) &&
   161		    !trap_is_unsupported_scv(regs)) {
   162			/* Enable TM in the kernel, and disable EE (for scv) */
   163			hard_irq_disable();
   164			mtmsr(mfmsr() | MSR_TM);
   165	
   166			/* tabort, this dooms the transaction, nothing else */
   167			asm volatile(".long 0x7c00071d | ((%0) << 16)"
   168					:: "r"(TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT));
   169	
   170			/*
   171			 * Userspace will never see the return value. Execution will
   172			 * resume after the tbegin. of the aborted transaction with the
   173			 * checkpointed register state. A context switch could occur
   174			 * or signal delivered to the process before resuming the
   175			 * doomed transaction context, but that should all be handled
   176			 * as expected.
   177			 */
   178			return -ENOSYS;
   179		}
   180	#endif // CONFIG_PPC_TRANSACTIONAL_MEM
   181	
   182		local_irq_enable();
   183	
   184		if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
   185			if (unlikely(trap_is_unsupported_scv(regs))) {
   186				/* Unsupported scv vector */
   187				_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
   188				return regs->gpr[3];
   189			}
   190			/*
   191			 * We use the return value of do_syscall_trace_enter() as the
   192			 * syscall number. If the syscall was rejected for any reason
   193			 * do_syscall_trace_enter() returns an invalid syscall number
   194			 * and the test against NR_syscalls will fail and the return
   195			 * value to be used is in regs->gpr[3].
   196			 */
   197			r0 = do_syscall_trace_enter(regs);
   198			if (unlikely(r0 >= NR_syscalls))
   199				return regs->gpr[3];
   200			r3 = regs->gpr[3];
   201			r4 = regs->gpr[4];
   202			r5 = regs->gpr[5];
   203			r6 = regs->gpr[6];
   204			r7 = regs->gpr[7];
   205			r8 = regs->gpr[8];
   206	
   207		} else if (unlikely(r0 >= NR_syscalls)) {
   208			if (unlikely(trap_is_unsupported_scv(regs))) {
   209				/* Unsupported scv vector */
   210				_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
   211				return regs->gpr[3];
   212			}
   213			return -ENOSYS;
   214		}
   215	
   216		/* May be faster to do array_index_nospec? */
   217		barrier_nospec();
   218	
   219		if (unlikely(is_compat_task())) {
   220			f = (void *)compat_sys_call_table[r0];
   221	
   222			r3 &= 0x00000000ffffffffULL;
   223			r4 &= 0x00000000ffffffffULL;
   224			r5 &= 0x00000000ffffffffULL;
   225			r6 &= 0x00000000ffffffffULL;
   226			r7 &= 0x00000000ffffffffULL;
   227			r8 &= 0x00000000ffffffffULL;
   228	
   229		} else {
   230			f = (void *)sys_call_table[r0];
   231		}
   232	
   233		return f(r3, r4, r5, r6, r7, r8);
   234	}
   235	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 72193 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [tip: core/entry] x86: Snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 11/11] x86: snapshot " Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Paul E. McKenney, x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     5796ee48d26a18930a8b86fb865ba195282889d0
Gitweb:        https://git.kernel.org/tip/5796ee48d26a18930a8b86fb865ba195282889d0
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:49 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:14 +01:00

x86: 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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Link: https://lore.kernel.org/r/20211117163050.53986-12-mark.rutland@arm.com
---
 arch/x86/kernel/process.c | 8 ++++----
 arch/x86/kernel/process.h | 4 ++--
 arch/x86/mm/tlb.c         | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 04143a6..5d48103 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -365,7 +365,7 @@ void arch_setup_new_exec(void)
 		clear_thread_flag(TIF_SSBD);
 		task_clear_spec_ssb_disable(current);
 		task_clear_spec_ssb_noexec(current);
-		speculation_ctrl_update(task_thread_info(current)->flags);
+		speculation_ctrl_update(read_thread_flags());
 	}
 }
 
@@ -617,7 +617,7 @@ static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk)
 			clear_tsk_thread_flag(tsk, TIF_SPEC_IB);
 	}
 	/* Return the updated threadinfo flags*/
-	return task_thread_info(tsk)->flags;
+	return read_task_thread_flags(tsk);
 }
 
 void speculation_ctrl_update(unsigned long tif)
@@ -653,8 +653,8 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p)
 {
 	unsigned long tifp, tifn;
 
-	tifn = READ_ONCE(task_thread_info(next_p)->flags);
-	tifp = READ_ONCE(task_thread_info(prev_p)->flags);
+	tifn = read_task_thread_flags(next_p);
+	tifp = read_task_thread_flags(prev_p);
 
 	switch_to_bitmap(tifp);
 
diff --git a/arch/x86/kernel/process.h b/arch/x86/kernel/process.h
index 1d0797b..76b547b 100644
--- a/arch/x86/kernel/process.h
+++ b/arch/x86/kernel/process.h
@@ -13,8 +13,8 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p);
 static inline void switch_to_extra(struct task_struct *prev,
 				   struct task_struct *next)
 {
-	unsigned long next_tif = task_thread_info(next)->flags;
-	unsigned long prev_tif = task_thread_info(prev)->flags;
+	unsigned long next_tif = read_task_thread_flags(next);
+	unsigned long prev_tif = read_task_thread_flags(prev);
 
 	if (IS_ENABLED(CONFIG_SMP)) {
 		/*
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 59ba296..92bb03b 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -361,7 +361,7 @@ static void l1d_flush_evaluate(unsigned long prev_mm, unsigned long next_mm,
 
 static unsigned long mm_mangle_tif_spec_bits(struct task_struct *next)
 {
-	unsigned long next_tif = task_thread_info(next)->flags;
+	unsigned long next_tif = read_task_thread_flags(next);
 	unsigned long spec_bits = (next_tif >> TIF_SPEC_IB) & LAST_USER_MM_SPEC_MASK;
 
 	/*

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] powerpc: Snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 10/11] powerpc: snapshot thread flags Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Paul E. McKenney,
	Benjamin Herrenschmidt, Michael Ellerman, Paul Mackerras, x86,
	linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     72e2920678507649ca100eadca8ec6f06744575d
Gitweb:        https://git.kernel.org/tip/72e2920678507649ca100eadca8ec6f06744575d
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:48 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:14 +01:00

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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Link: https://lore.kernel.org/r/20211117163050.53986-11-mark.rutland@arm.com
---
 arch/powerpc/kernel/interrupt.c     | 13 ++++++-------
 arch/powerpc/kernel/ptrace/ptrace.c |  3 +--
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 1c821b7..ff25888 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -181,7 +181,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
 
 	local_irq_enable();
 
-	if (unlikely(current_thread_info()->flags & _TIF_SYSCALL_DOTRACE)) {
+	if (unlikely(read_thread_flags() & _TIF_SYSCALL_DOTRACE)) {
 		if (unlikely(trap_is_unsupported_scv(regs))) {
 			/* Unsupported scv vector */
 			_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
@@ -343,7 +343,7 @@ interrupt_exit_user_prepare_main(unsigned long ret, struct pt_regs *regs)
 	unsigned long ti_flags;
 
 again:
-	ti_flags = READ_ONCE(current_thread_info()->flags);
+	ti_flags = read_thread_flags();
 	while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) {
 		local_irq_enable();
 		if (ti_flags & _TIF_NEED_RESCHED) {
@@ -359,7 +359,7 @@ again:
 			do_notify_resume(regs, ti_flags);
 		}
 		local_irq_disable();
-		ti_flags = READ_ONCE(current_thread_info()->flags);
+		ti_flags = read_thread_flags();
 	}
 
 	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,
 	/* Check whether the syscall is issued inside a restartable sequence */
 	rseq_syscall(regs);
 
-	ti_flags = current_thread_info()->flags;
+	ti_flags = read_thread_flags();
 
 	if (unlikely(r3 >= (unsigned long)-MAX_ERRNO) && is_not_scv) {
 		if (likely(!(ti_flags & (_TIF_NOERROR | _TIF_RESTOREALL)))) {
@@ -532,8 +532,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
 	unsigned long flags;
 	unsigned long ret = 0;
 	unsigned long kuap;
-	bool stack_store = current_thread_info()->flags &
-						_TIF_EMULATE_STACK_STORE;
+	bool stack_store = read_thread_flags() & _TIF_EMULATE_STACK_STORE;
 
 	if (regs_is_unrecoverable(regs))
 		unrecoverable_exception(regs);
@@ -554,7 +553,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
 again:
 		if (IS_ENABLED(CONFIG_PREEMPT)) {
 			/* Return to preemptible kernel context */
-			if (unlikely(current_thread_info()->flags & _TIF_NEED_RESCHED)) {
+			if (unlikely(read_thread_flags() & _TIF_NEED_RESCHED)) {
 				if (preempt_count() == 0)
 					preempt_schedule_irq();
 			}
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index 7c7093c..c43f77e 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -260,8 +260,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
 {
 	u32 flags;
 
-	flags = READ_ONCE(current_thread_info()->flags) &
-		(_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
+	flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
 
 	if (flags) {
 		int rc = tracehook_report_syscall_entry(regs);

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] powerpc: Avoid discarding flags in system_call_exception()
  2021-11-17 16:30 ` [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception() Mark Rutland
  2021-11-17 21:39   ` kernel test robot
  2021-11-17 22:17   ` kernel test robot
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  2 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Eirik Fuller, Michael Ellerman,
	Nicholas Piggin, x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     51ed65dcfd9c61a15920a40178d471d236a7514c
Gitweb:        https://git.kernel.org/tip/51ed65dcfd9c61a15920a40178d471d236a7514c
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:47 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:13 +01:00

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;

In arch/powerpc/kernel/interrupt.c's system_call_exception(), we set
_TIF_RESTOREALL in the thread info flags with a read-modify-write, which
may result in other flags being discarded.

Elsewhere in the file we use clear_bits() to atomically remove flag
bits, so let's use set_bits() here for consistency with those.

I presume 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/20211117163050.53986-10-mark.rutland@arm.com
---
 arch/powerpc/kernel/interrupt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 835b626..1c821b7 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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] openrisc: Snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 08/11] openrisc: snapshot " Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Stafford Horne, Paul E. McKenney,
	Jonas Bonn, Stefan Kristiansson, x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     b67c4b87d2a6893dd6bddc8b0400715cafc30cd5
Gitweb:        https://git.kernel.org/tip/b67c4b87d2a6893dd6bddc8b0400715cafc30cd5
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:46 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:13 +01:00

openrisc: 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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Stafford Horne <shorne@gmail.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Link: https://lore.kernel.org/r/20211117163050.53986-9-mark.rutland@arm.com
---
 arch/openrisc/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index 99516c9..92c5b70 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -313,7 +313,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 			}
 		}
 		local_irq_disable();
-		thread_flags = current_thread_info()->flags;
+		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 	return 0;
 }

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] microblaze: Snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 07/11] microblaze: " Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Michal Simek, Paul E. McKenney,
	x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     a9455e33ce5f0516046ca0da3aedd80f147ecb38
Gitweb:        https://git.kernel.org/tip/a9455e33ce5f0516046ca0da3aedd80f147ecb38
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:45 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:13 +01:00

microblaze: 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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Michal Simek <michal.simek@xilinx.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Link: https://lore.kernel.org/r/20211117163050.53986-8-mark.rutland@arm.com
---
 arch/microblaze/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index fc61eb0..23e8a93 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -283,7 +283,7 @@ static void do_signal(struct pt_regs *regs, int in_syscall)
 #ifdef DEBUG_SIG
 	pr_info("do signal: %p %d\n", regs, in_syscall);
 	pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
-			regs->r12, current_thread_info()->flags);
+			regs->r12, read_thread_flags());
 #endif
 
 	if (get_signal(&ksig)) {

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] arm64: snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 06/11] arm64: snapshot " Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Will Deacon, Paul E. McKenney,
	Catalin Marinas, x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     67c76c3dc0ef46f44715e866c7d4ef81a5a2872d
Gitweb:        https://git.kernel.org/tip/67c76c3dc0ef46f44715e866c7d4ef81a5a2872d
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:44 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:13 +01:00

arm64: 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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20211117163050.53986-7-mark.rutland@arm.com
---
 arch/arm64/kernel/entry-common.c | 2 +-
 arch/arm64/kernel/ptrace.c       | 4 ++--
 arch/arm64/kernel/signal.c       | 2 +-
 arch/arm64/kernel/syscall.c      | 4 ++--
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index f7408ed..ef7fcef 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -129,7 +129,7 @@ static __always_inline void prepare_exit_to_user_mode(struct pt_regs *regs)
 
 	local_daif_mask();
 
-	flags = READ_ONCE(current_thread_info()->flags);
+	flags = read_thread_flags();
 	if (unlikely(flags & _TIF_WORK_MASK))
 		do_notify_resume(regs, flags);
 }
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 88a9034..33cac3d 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1839,7 +1839,7 @@ static void tracehook_report_syscall(struct pt_regs *regs,
 
 int syscall_trace_enter(struct pt_regs *regs)
 {
-	unsigned long flags = READ_ONCE(current_thread_info()->flags);
+	unsigned long flags = read_thread_flags();
 
 	if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
 		tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
@@ -1862,7 +1862,7 @@ int syscall_trace_enter(struct pt_regs *regs)
 
 void syscall_trace_exit(struct pt_regs *regs)
 {
-	unsigned long flags = READ_ONCE(current_thread_info()->flags);
+	unsigned long flags = read_thread_flags();
 
 	audit_syscall_exit(regs);
 
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 8f6372b..d8aaf4b 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -948,7 +948,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
 		}
 
 		local_daif_mask();
-		thread_flags = READ_ONCE(current_thread_info()->flags);
+		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 }
 
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 50a0f1a..c938603 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -81,7 +81,7 @@ void syscall_trace_exit(struct pt_regs *regs);
 static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 			   const syscall_fn_t syscall_table[])
 {
-	unsigned long flags = current_thread_info()->flags;
+	unsigned long flags = read_thread_flags();
 
 	regs->orig_x0 = regs->regs[0];
 	regs->syscallno = scno;
@@ -148,7 +148,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 	 */
 	if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
 		local_daif_mask();
-		flags = current_thread_info()->flags;
+		flags = read_thread_flags();
 		if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP))
 			return;
 		local_daif_restore(DAIF_PROCCTX);

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] ARM: Snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 05/11] arm: snapshot " Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Paul E. McKenney, Russell King,
	x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     3fe5dec062dfc8344356823457f5f43e0730c074
Gitweb:        https://git.kernel.org/tip/3fe5dec062dfc8344356823457f5f43e0730c074
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:43 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:13 +01:00

ARM: 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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Russell King <linux@armlinux.org.uk>
Link: https://lore.kernel.org/r/20211117163050.53986-6-mark.rutland@arm.com
---
 arch/arm/kernel/signal.c | 2 +-
 arch/arm/mm/alignment.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index a41e27a..c532a60 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -631,7 +631,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 			}
 		}
 		local_irq_disable();
-		thread_flags = current_thread_info()->flags;
+		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 	return 0;
 }
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index ea81e89..adbb381 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -990,7 +990,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 		 * there is no work pending for this thread.
 		 */
 		raw_local_irq_disable();
-		if (!(current_thread_info()->flags & _TIF_WORK_MASK))
+		if (!(read_thread_flags() & _TIF_WORK_MASK))
 			set_cr(cr_no_alignment);
 	}
 

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] alpha: Snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 04/11] alpha: snapshot " Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Paul E. McKenney, Ivan Kokshaysky,
	Matt Turner, Richard Henderson, x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     b8cdd8873327b967fe088ffab84c1f9456ef1767
Gitweb:        https://git.kernel.org/tip/b8cdd8873327b967fe088ffab84c1f9456ef1767
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:42 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:13 +01:00

alpha: 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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Richard Henderson <rth@twiddle.net>
Link: https://lore.kernel.org/r/20211117163050.53986-5-mark.rutland@arm.com
---
 arch/alpha/kernel/signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index bc077ba..d8ed71d 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -535,6 +535,6 @@ do_work_pending(struct pt_regs *regs, unsigned long thread_flags,
 			}
 		}
 		local_irq_disable();
-		thread_flags = current_thread_info()->flags;
+		thread_flags = read_thread_flags();
 	} while (thread_flags & _TIF_WORK_MASK);
 }

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] entry: Snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 02/11] entry: " Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Paul E. McKenney, Andy Lutomirski,
	x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     f6af43531342c55c34a851bd455508edc29f6e06
Gitweb:        https://git.kernel.org/tip/f6af43531342c55c34a851bd455508edc29f6e06
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:40 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:13 +01:00

entry: 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 <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Link: https://lore.kernel.org/r/20211117163050.53986-3-mark.rutland@arm.com
---
 include/linux/entry-kvm.h | 2 +-
 kernel/entry/common.c     | 4 ++--
 kernel/entry/kvm.c        | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/entry-kvm.h b/include/linux/entry-kvm.h
index 0d7865a..07c878d 100644
--- a/include/linux/entry-kvm.h
+++ b/include/linux/entry-kvm.h
@@ -75,7 +75,7 @@ static inline void xfer_to_guest_mode_prepare(void)
  */
 static inline bool __xfer_to_guest_mode_work_pending(void)
 {
-	unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
+	unsigned long ti_work = read_thread_flags();
 
 	return !!(ti_work & XFER_TO_GUEST_MODE_WORK);
 }
diff --git a/kernel/entry/common.c b/kernel/entry/common.c
index d5a61d5..bad7136 100644
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -187,7 +187,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 		/* Check if any of the above work has queued a deferred wakeup */
 		tick_nohz_user_enter_prepare();
 
-		ti_work = READ_ONCE(current_thread_info()->flags);
+		ti_work = read_thread_flags();
 	}
 
 	/* Return the latest work state for arch_exit_to_user_mode() */
@@ -196,7 +196,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 
 static void exit_to_user_mode_prepare(struct pt_regs *regs)
 {
-	unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
+	unsigned long ti_work = read_thread_flags();
 
 	lockdep_assert_irqs_disabled();
 
diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
index 49972ee..96d476e 100644
--- a/kernel/entry/kvm.c
+++ b/kernel/entry/kvm.c
@@ -26,7 +26,7 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
 		if (ret)
 			return ret;
 
-		ti_work = READ_ONCE(current_thread_info()->flags);
+		ti_work = read_thread_flags();
 	} while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched());
 	return 0;
 }
@@ -43,7 +43,7 @@ int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
 	 * disabled in the inner loop before going into guest mode. No need
 	 * to disable interrupts here.
 	 */
-	ti_work = READ_ONCE(current_thread_info()->flags);
+	ti_work = read_thread_flags();
 	if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
 		return 0;
 

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] sched: Snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 03/11] sched: snapshot " Mark Rutland
@ 2021-11-26 20:22   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:22 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Paul E. McKenney, Juri Lelli,
	Vincent Guittot, x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     13a405dc6f7f01635c1e849c42b2b8941cec2968
Gitweb:        https://git.kernel.org/tip/13a405dc6f7f01635c1e849c42b2b8941cec2968
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:41 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:13 +01:00

sched: 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.

The READ_ONCE(ti->flags) .. cmpxchg(ti->flags) loop in set_nr_if_polling()
is left as-is for clarity.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Link: https://lore.kernel.org/r/20211117163050.53986-4-mark.rutland@arm.com
---
 kernel/sched/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3c9b0fd..7ba05de 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8520,7 +8520,7 @@ void sched_show_task(struct task_struct *p)
 	rcu_read_unlock();
 	pr_cont(" stack:%5lu pid:%5d ppid:%6d flags:0x%08lx\n",
 		free, task_pid_nr(p), ppid,
-		(unsigned long)task_thread_info(p)->flags);
+		read_task_thread_flags(p));
 
 	print_worker_info(KERN_INFO, p);
 	print_stop_info(KERN_INFO, p);

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip: core/entry] thread_info: Add helpers to snapshot thread flags
  2021-11-17 16:30 ` [PATCHv7 01/11] thread_info: add " Mark Rutland
@ 2021-11-26 20:23   ` tip-bot2 for Mark Rutland
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot2 for Mark Rutland @ 2021-11-26 20:23 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Mark Rutland, Thomas Gleixner, Marco Elver, Paul E. McKenney,
	Boqun Feng, Dmitry Vyukov, Will Deacon, x86, linux-kernel

The following commit has been merged into the core/entry branch of tip:

Commit-ID:     669bcfc0ffe06d9623b48babf5d609d6a36ebdfa
Gitweb:        https://git.kernel.org/tip/669bcfc0ffe06d9623b48babf5d609d6a36ebdfa
Author:        Mark Rutland <mark.rutland@arm.com>
AuthorDate:    Wed, 17 Nov 2021 16:30:39 
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 26 Nov 2021 21:20:12 +01:00

thread_info: Add helpers to snapshot thread flags

In <linux/thread_info.h> there are helpers to manipulate individual
thread flags, but where code wants to check several flags at once, it
must open code reading current_thread_info()->flags and operating on a
snapshot.

As some flags can be set remotely it's necessary to use READ_ONCE() to
get a consistent snapshot even when IRQs are disabled, but some code
forgets to do this. Generally this is unlike to cause a problem in
practice, but it is somewhat unsound, and KCSAN will legitimately warn
that there is a data race.

To make it easier to do the right thing, and to highlight that
concurrent modification is possible, add new helpers to snapshot the
flags, which should be used in preference to plain reads. Subsequent
patches will move existing code to use the new helpers.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Marco Elver <elver@google.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20211117163050.53986-2-mark.rutland@arm.com
---
 include/linux/thread_info.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index ad0c4e0..73a6f34 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -118,6 +118,15 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
 	return test_bit(flag, (unsigned long *)&ti->flags);
 }
 
+/*
+ * This may be used in noinstr code, and needs to be __always_inline to prevent
+ * inadvertent instrumentation.
+ */
+static __always_inline unsigned long read_ti_thread_flags(struct thread_info *ti)
+{
+	return READ_ONCE(ti->flags);
+}
+
 #define set_thread_flag(flag) \
 	set_ti_thread_flag(current_thread_info(), flag)
 #define clear_thread_flag(flag) \
@@ -130,6 +139,11 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
 	test_and_clear_ti_thread_flag(current_thread_info(), flag)
 #define test_thread_flag(flag) \
 	test_ti_thread_flag(current_thread_info(), flag)
+#define read_thread_flags() \
+	read_ti_thread_flags(current_thread_info())
+
+#define read_task_thread_flags(t) \
+	read_ti_thread_flags(task_thread_info(t))
 
 #ifdef CONFIG_GENERIC_ENTRY
 #define set_syscall_work(fl) \

^ permalink raw reply related	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2021-11-26 20:26 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-17 16:30 [PATCHv7 00/11] thread_info: use helpers to snapshot thread flags Mark Rutland
2021-11-17 16:30 ` [PATCHv7 01/11] thread_info: add " Mark Rutland
2021-11-26 20:23   ` [tip: core/entry] thread_info: Add " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 02/11] entry: " Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] entry: Snapshot " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 03/11] sched: snapshot " Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] sched: Snapshot " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 04/11] alpha: snapshot " Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] alpha: Snapshot " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 05/11] arm: snapshot " Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] ARM: Snapshot " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 06/11] arm64: snapshot " Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 07/11] microblaze: " Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] microblaze: Snapshot " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 08/11] openrisc: snapshot " Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] openrisc: Snapshot " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 09/11] powerpc: avoid discarding flags in system_call_exception() Mark Rutland
2021-11-17 21:39   ` kernel test robot
2021-11-17 22:17   ` kernel test robot
2021-11-26 20:22   ` [tip: core/entry] powerpc: Avoid " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 10/11] powerpc: snapshot thread flags Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] powerpc: Snapshot " tip-bot2 for Mark Rutland
2021-11-17 16:30 ` [PATCHv7 11/11] x86: snapshot " Mark Rutland
2021-11-26 20:22   ` [tip: core/entry] x86: Snapshot " tip-bot2 for Mark Rutland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.