lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240310020509.647319-10-irogers@google.com>
Date: Sat,  9 Mar 2024 18:05:04 -0800
From: Ian Rogers <irogers@...gle.com>
To: Arnd Bergmann <arnd@...db.de>, Andrii Nakryiko <andrii@...nel.org>, 
	Alexei Starovoitov <ast@...nel.org>, Daniel Borkmann <daniel@...earbox.net>, 
	Martin KaFai Lau <martin.lau@...ux.dev>, Song Liu <song@...nel.org>, 
	Yonghong Song <yonghong.song@...ux.dev>, John Fastabend <john.fastabend@...il.com>, 
	KP Singh <kpsingh@...nel.org>, Stanislav Fomichev <sdf@...gle.com>, Hao Luo <haoluo@...gle.com>, 
	Jiri Olsa <jolsa@...nel.org>, Peter Zijlstra <peterz@...radead.org>, Ingo Molnar <mingo@...hat.com>, 
	Arnaldo Carvalho de Melo <acme@...nel.org>, Namhyung Kim <namhyung@...nel.org>, 
	Mark Rutland <mark.rutland@....com>, 
	Alexander Shishkin <alexander.shishkin@...ux.intel.com>, Ian Rogers <irogers@...gle.com>, 
	Adrian Hunter <adrian.hunter@...el.com>, Paolo Bonzini <pbonzini@...hat.com>, 
	Shuah Khan <shuah@...nel.org>, Kees Cook <keescook@...omium.org>, 
	"Gustavo A. R. Silva" <gustavoars@...nel.org>, Nathan Chancellor <nathan@...nel.org>, 
	Nick Desaulniers <ndesaulniers@...gle.com>, Bill Wendling <morbo@...gle.com>, 
	Justin Stitt <justinstitt@...gle.com>, Andrew Morton <akpm@...ux-foundation.org>, 
	Liam Howlett <liam.howlett@...cle.com>, Miguel Ojeda <ojeda@...nel.org>, 
	Will Deacon <will@...nel.org>, Mark Brown <broonie@...nel.org>, 
	David Laight <David.Laight@...LAB.COM>, "Michael S. Tsirkin" <mst@...hat.com>, Shunsuke Mie <mie@...l.co.jp>, 
	Yafang Shao <laoar.shao@...il.com>, Kui-Feng Lee <kuifeng@...a.com>, 
	James Clark <james.clark@....com>, Nick Forrington <nick.forrington@....com>, 
	Leo Yan <leo.yan@...ux.dev>, German Gomez <german.gomez@....com>, Rob Herring <robh@...nel.org>, 
	John Garry <john.g.garry@...cle.com>, Sean Christopherson <seanjc@...gle.com>, 
	Anup Patel <anup@...infault.org>, Fuad Tabba <tabba@...gle.com>, 
	Andrew Jones <ajones@...tanamicro.com>, Chao Peng <chao.p.peng@...ux.intel.com>, 
	Haibo Xu <haibo1.xu@...el.com>, Peter Xu <peterx@...hat.com>, 
	Vishal Annapurve <vannapurve@...gle.com>, linux-kernel@...r.kernel.org, 
	linux-arch@...r.kernel.org, bpf@...r.kernel.org, 
	linux-perf-users@...r.kernel.org, kvm@...r.kernel.org, 
	linux-kselftest@...r.kernel.org, linux-hardening@...r.kernel.org, 
	llvm@...ts.linux.dev
Subject: [PATCH v1 09/13] tools headers: Rewrite linux/atomic.h using C11's stdatomic.h

Code in tools tries to follow the patterns of the kernel, so the
atomic functions names match. However, having include/linux/atomic.h
in tools complicates building code in tools as assembly and other
functions are necessary - these are often configured in the kernel
using CONFIG options. As tools C code is compiled with the -std=gnu11
flag, it is possible to use stdatomic.h and move the build and other
complications to the compiler/libc.

Signed-off-by: Ian Rogers <irogers@...gle.com>
---
 tools/arch/x86/include/asm/atomic.h           |  84 --------------
 tools/include/asm-generic/atomic-gcc.h        |  95 ----------------
 tools/include/asm/atomic.h                    |  11 --
 tools/include/linux/atomic.h                  | 107 ++++++++++++++++--
 tools/include/linux/types.h                   |  15 ++-
 .../selftests/kvm/include/kvm_util_base.h     |   3 +-
 6 files changed, 110 insertions(+), 205 deletions(-)
 delete mode 100644 tools/arch/x86/include/asm/atomic.h
 delete mode 100644 tools/include/asm-generic/atomic-gcc.h
 delete mode 100644 tools/include/asm/atomic.h

diff --git a/tools/arch/x86/include/asm/atomic.h b/tools/arch/x86/include/asm/atomic.h
deleted file mode 100644
index 365cf182df12..000000000000
--- a/tools/arch/x86/include/asm/atomic.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _TOOLS_LINUX_ASM_X86_ATOMIC_H
-#define _TOOLS_LINUX_ASM_X86_ATOMIC_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include "rmwcc.h"
-
-#define LOCK_PREFIX "\n\tlock; "
-
-#include <asm/asm.h>
-#include <asm/cmpxchg.h>
-
-/*
- * Atomic operations that C can't guarantee us.  Useful for
- * resource counting etc..
- */
-
-#define ATOMIC_INIT(i)	{ (i) }
-
-/**
- * atomic_read - read atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically reads the value of @v.
- */
-static inline int atomic_read(const atomic_t *v)
-{
-	return READ_ONCE((v)->counter);
-}
-
-/**
- * atomic_set - set atomic variable
- * @v: pointer of type atomic_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
-static inline void atomic_set(atomic_t *v, int i)
-{
-	v->counter = i;
-}
-
-/**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.
- */
-static inline void atomic_inc(atomic_t *v)
-{
-	asm volatile(LOCK_PREFIX "incl %0"
-		     : "+m" (v->counter));
-}
-
-/**
- * atomic_dec_and_test - decrement and test
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1 and
- * returns true if the result is 0, or false for all other
- * cases.
- */
-static inline int atomic_dec_and_test(atomic_t *v)
-{
-	GEN_UNARY_RMWcc(LOCK_PREFIX "decl", v->counter, "%0", "e");
-}
-
-static __always_inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
-	return cmpxchg(&v->counter, old, new);
-}
-
-static inline int test_and_set_bit(long nr, unsigned long *addr)
-{
-	GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(bts), *addr, "Ir", nr, "%0", "c");
-}
-
-static inline int test_and_clear_bit(long nr, unsigned long *addr)
-{
-	GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(btc), *addr, "Ir", nr, "%0", "c");
-}
-
-#endif /* _TOOLS_LINUX_ASM_X86_ATOMIC_H */
diff --git a/tools/include/asm-generic/atomic-gcc.h b/tools/include/asm-generic/atomic-gcc.h
deleted file mode 100644
index 9b3c528bab92..000000000000
--- a/tools/include/asm-generic/atomic-gcc.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __TOOLS_ASM_GENERIC_ATOMIC_H
-#define __TOOLS_ASM_GENERIC_ATOMIC_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-
-/*
- * Atomic operations that C can't guarantee us.  Useful for
- * resource counting etc..
- *
- * Excerpts obtained from the Linux kernel sources.
- */
-
-#define ATOMIC_INIT(i)	{ (i) }
-
-/**
- * atomic_read - read atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically reads the value of @v.
- */
-static inline int atomic_read(const atomic_t *v)
-{
-	return READ_ONCE((v)->counter);
-}
-
-/**
- * atomic_set - set atomic variable
- * @v: pointer of type atomic_t
- * @i: required value
- *
- * Atomically sets the value of @v to @i.
- */
-static inline void atomic_set(atomic_t *v, int i)
-{
-        v->counter = i;
-}
-
-/**
- * atomic_inc - increment atomic variable
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1.
- */
-static inline void atomic_inc(atomic_t *v)
-{
-	__sync_add_and_fetch(&v->counter, 1);
-}
-
-/**
- * atomic_dec_and_test - decrement and test
- * @v: pointer of type atomic_t
- *
- * Atomically decrements @v by 1 and
- * returns true if the result is 0, or false for all other
- * cases.
- */
-static inline int atomic_dec_and_test(atomic_t *v)
-{
-	return __sync_sub_and_fetch(&v->counter, 1) == 0;
-}
-
-#define cmpxchg(ptr, oldval, newval) \
-	__sync_val_compare_and_swap(ptr, oldval, newval)
-
-static inline int atomic_cmpxchg(atomic_t *v, int oldval, int newval)
-{
-	return cmpxchg(&(v)->counter, oldval, newval);
-}
-
-static inline int test_and_set_bit(long nr, unsigned long *addr)
-{
-	unsigned long mask = BIT_MASK(nr);
-	long old;
-
-	addr += BIT_WORD(nr);
-
-	old = __sync_fetch_and_or(addr, mask);
-	return !!(old & mask);
-}
-
-static inline int test_and_clear_bit(long nr, unsigned long *addr)
-{
-	unsigned long mask = BIT_MASK(nr);
-	long old;
-
-	addr += BIT_WORD(nr);
-
-	old = __sync_fetch_and_and(addr, ~mask);
-	return !!(old & mask);
-}
-
-#endif /* __TOOLS_ASM_GENERIC_ATOMIC_H */
diff --git a/tools/include/asm/atomic.h b/tools/include/asm/atomic.h
deleted file mode 100644
index 8c9bfffd4191..000000000000
--- a/tools/include/asm/atomic.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __TOOLS_LINUX_ASM_ATOMIC_H
-#define __TOOLS_LINUX_ASM_ATOMIC_H
-
-#if defined(__i386__) || defined(__x86_64__)
-#include "../../arch/x86/include/asm/atomic.h"
-#else
-#include <asm-generic/atomic-gcc.h>
-#endif
-
-#endif /* __TOOLS_LINUX_ASM_ATOMIC_H */
diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h
index 01907b33537e..2cf4791ddd5d 100644
--- a/tools/include/linux/atomic.h
+++ b/tools/include/linux/atomic.h
@@ -2,14 +2,107 @@
 #ifndef __TOOLS_LINUX_ATOMIC_H
 #define __TOOLS_LINUX_ATOMIC_H
 
-#include <asm/atomic.h>
+#include <stdatomic.h>
+#include <linux/types.h>  // For atomic_t
 
-void atomic_long_set(atomic_long_t *v, long i);
+/*
+ * Reimplementation of the kernel's atomic.h using C11's stdatomic.h to avoid
+ * build logic around compilers, inline assembler, etc.
+ */
 
-/* atomic_cmpxchg_relaxed */
-#ifndef atomic_cmpxchg_relaxed
-#define  atomic_cmpxchg_relaxed		atomic_cmpxchg
-#define  atomic_cmpxchg_release         atomic_cmpxchg
-#endif /* atomic_cmpxchg_relaxed */
+#define ATOMIC_OP(op, c_op)						\
+static inline void generic_atomic_##op(int i, atomic_t *v)		\
+{									\
+	atomic_fetch_##op(v, i);				\
+}
+
+#define ATOMIC_OP_RETURN(op, c_op)					\
+static inline int generic_atomic_##op##_return(int i, atomic_t *v)	\
+{									\
+	int c =	atomic_fetch_##op(v, i);			\
+									\
+	return c c_op i;						\
+}
+
+#define ATOMIC_FETCH_OP(op, c_op)					\
+static inline int generic_atomic_fetch_##op(int i, atomic_t *v)		\
+{									\
+	return atomic_fetch_##op(v, i);			\
+}
+
+static inline int generic_atomic_read(const atomic_t *v)
+{
+	return atomic_load(v);
+}
+
+static inline void generic_atomic_set(atomic_t *v, int i)
+{
+	atomic_store(v, i);
+}
+
+static inline int generic_atomic_cmpxchg_relaxed(atomic_t *v, int old, int new)
+{
+	int expected = old;
+
+	atomic_compare_exchange_weak_explicit(v, &expected, new,
+					memory_order_relaxed, memory_order_relaxed);
+	return expected;
+}
+
+static inline int generic_atomic_cmpxchg_release(atomic_t *v, int old, int new)
+{
+	int expected = old;
+
+	/*
+	 * Note, the stricter memory_order_seq_cst is used as
+	 * memory_order_release fails with an invalid-memory-model error.
+	 */
+	atomic_compare_exchange_weak_explicit(v, &expected, new,
+					memory_order_seq_cst, memory_order_seq_cst);
+	return expected;
+}
+
+ATOMIC_OP_RETURN(add, +)
+ATOMIC_OP_RETURN(sub, -)
+
+ATOMIC_FETCH_OP(add, +)
+ATOMIC_FETCH_OP(sub, -)
+ATOMIC_FETCH_OP(and, &)
+ATOMIC_FETCH_OP(or, |)
+ATOMIC_FETCH_OP(xor, ^)
+
+ATOMIC_OP(add, +)
+ATOMIC_OP(sub, -)
+ATOMIC_OP(and, &)
+ATOMIC_OP(or, |)
+ATOMIC_OP(xor, ^)
+
+#undef ATOMIC_FETCH_OP
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
+
+#define arch_atomic_add_return			generic_atomic_add_return
+#define arch_atomic_sub_return			generic_atomic_sub_return
+
+#define arch_atomic_fetch_add			generic_atomic_fetch_add
+#define arch_atomic_fetch_sub			generic_atomic_fetch_sub
+#define arch_atomic_fetch_and			generic_atomic_fetch_and
+#define arch_atomic_fetch_or			generic_atomic_fetch_or
+#define arch_atomic_fetch_xor			generic_atomic_fetch_xor
+
+#define arch_atomic_add				generic_atomic_add
+#define arch_atomic_sub				generic_atomic_sub
+#define arch_atomic_and				generic_atomic_and
+#define arch_atomic_or				generic_atomic_or
+#define arch_atomic_xor				generic_atomic_xor
+
+#define arch_atomic_read(v)			generic_atomic_read(v)
+#define arch_atomic_set(v, i)			generic_atomic_set(v, i)
+#define atomic_set(v, i)			generic_atomic_set(v, i)
+#define atomic_read(v)				generic_atomic_read(v)
+#define atomic_cmpxchg_relaxed(v, o, n)		generic_atomic_cmpxchg_relaxed(v, o, n)
+#define atomic_cmpxchg_release(v, o, n)		generic_atomic_cmpxchg_release(v, o, n)
+#define atomic_inc(v)				generic_atomic_add(1, v)
+#define atomic_dec(v)				generic_atomic_sub(1, v)
 
 #endif /* __TOOLS_LINUX_ATOMIC_H */
diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h
index 8519386acd23..cb1f44f1ed5e 100644
--- a/tools/include/linux/types.h
+++ b/tools/include/linux/types.h
@@ -74,13 +74,16 @@ typedef u64 phys_addr_t;
 typedef u32 phys_addr_t;
 #endif
 
-typedef struct {
-	int counter;
-} atomic_t;
+#ifndef __cplusplus
+/* C++17 doesn't support stdatomic.h but C++23 does. */
+#include <stdatomic.h>
 
-typedef struct {
-	long counter;
-} atomic_long_t;
+typedef atomic_int atomic_t;
+
+#define ATOMIC_INIT(i) (i)
+
+typedef atomic_long atomic_long_t;
+#endif
 
 #ifndef __aligned_u64
 # define __aligned_u64 __u64 __attribute__((aligned(8)))
diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
index 9e5afc472c14..7c81da425abc 100644
--- a/tools/testing/selftests/kvm/include/kvm_util_base.h
+++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
@@ -9,6 +9,7 @@
 
 #include "test_util.h"
 
+#include <linux/atomic.h>
 #include <linux/compiler.h>
 #include "linux/hashtable.h"
 #include "linux/list.h"
@@ -17,8 +18,6 @@
 #include "linux/rbtree.h"
 #include <linux/types.h>
 
-#include <asm/atomic.h>
-
 #include <sys/ioctl.h>
 
 #include "sparsebit.h"
-- 
2.44.0.278.ge034bb2e1d-goog


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ