From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86C2BC4338F for ; Tue, 3 Aug 2021 09:54:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6669460F9C for ; Tue, 3 Aug 2021 09:54:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235041AbhHCJy5 (ORCPT ); Tue, 3 Aug 2021 05:54:57 -0400 Received: from foss.arm.com ([217.140.110.172]:45698 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234910AbhHCJy4 (ORCPT ); Tue, 3 Aug 2021 05:54:56 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id ED6E112FC; Tue, 3 Aug 2021 02:54:45 -0700 (PDT) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id DC0623F40C; Tue, 3 Aug 2021 02:54:42 -0700 (PDT) From: Mark Rutland To: linux-kernel@vger.kernel.org Cc: benh@kernel.crashing.org, boqun.feng@gmail.com, bp@alien8.de, catalin.marinas@arm.com, dvyukov@google.com, elver@google.com, ink@jurassic.park.msu.ru, jonas@southpole.se, juri.lelli@redhat.com, linux@armlinux.org.uk, luto@kernel.org, mark.rutland@arm.com, mattst88@gmail.com, mingo@redhat.com, monstr@monstr.eu, mpe@ellerman.id.au, paulmck@kernel.org, paulus@samba.org, peterz@infradead.org, rth@twiddle.net, shorne@gmail.com, stefan.kristiansson@saunalahti.fi, tglx@linutronix.de, vincent.guittot@linaro.org, will@kernel.org Subject: [PATCH v4 01/10] thread_info: add helpers to snapshot thread flags Date: Tue, 3 Aug 2021 10:54:19 +0100 Message-Id: <20210803095428.17009-2-mark.rutland@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20210803095428.17009-1-mark.rutland@arm.com> References: <20210803095428.17009-1-mark.rutland@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In 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 Reviewed-by: Thomas Gleixner Acked-by: Marco Elver Cc: Boqun Feng Cc: Dmitry Vyukov Cc: Paul E. McKenney Cc: Peter Zijlstra Cc: Will Deacon --- 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 0999f6317978..9a073535c0bd 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