|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] xen/bitops: Cleanup and new infrastructure ahead of rearrangements
commit ea59e7d780d9506793226b8cd1b402e341b195a7
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Fri Mar 8 23:45:08 2024 +0000
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Sat Jun 1 02:28:14 2024 +0100
xen/bitops: Cleanup and new infrastructure ahead of rearrangements
* Rename __attribute_pure__ to just __pure before it gains users.
* Introduce __constructor which is going to be used in lib/, and is
unconditionally cf_check.
* Identify the areas of xen/bitops.h which are a mess.
* Introduce xen/self-tests.h as helpers for compile and boot time testing.
This provides a statement of the ABI, and a confirmation that
arch-specific
implementations behave as expected.
* Introduce HIDE() in macros.h. While it's only used in self-tests.h for
now, we're going to consolidate similar constructs in due course.
Sadly Clang 7 and older isn't happy with the compile time checks. Skip
them,
and just rely on the runtime checks.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
Release-acked-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
xen/include/xen/bitops.h | 13 +++++++---
xen/include/xen/compiler.h | 3 ++-
xen/include/xen/macros.h | 8 +++++++
xen/include/xen/self-tests.h | 56 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 76 insertions(+), 4 deletions(-)
diff --git a/xen/include/xen/bitops.h b/xen/include/xen/bitops.h
index e3c5a4ccf3..9b40f20381 100644
--- a/xen/include/xen/bitops.h
+++ b/xen/include/xen/bitops.h
@@ -1,5 +1,7 @@
-#ifndef _LINUX_BITOPS_H
-#define _LINUX_BITOPS_H
+#ifndef XEN_BITOPS_H
+#define XEN_BITOPS_H
+
+#include <xen/compiler.h>
#include <xen/types.h>
/*
@@ -103,8 +105,13 @@ static inline int generic_flsl(unsigned long x)
* Include this here because some architectures need generic_ffs/fls in
* scope
*/
+
+/* --------------------- Please tidy above here --------------------- */
+
#include <asm/bitops.h>
+/* --------------------- Please tidy below here --------------------- */
+
#ifndef find_next_bit
/**
* find_next_bit - find the next set bit in a memory region
@@ -294,4 +301,4 @@ static inline __u32 ror32(__u32 word, unsigned int shift)
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
-#endif
+#endif /* XEN_BITOPS_H */
diff --git a/xen/include/xen/compiler.h b/xen/include/xen/compiler.h
index 179ff23e62..444bf80142 100644
--- a/xen/include/xen/compiler.h
+++ b/xen/include/xen/compiler.h
@@ -86,7 +86,8 @@
#define inline inline __init
#endif
-#define __attribute_pure__ __attribute__((__pure__))
+#define __constructor __attribute__((__constructor__)) cf_check
+#define __pure __attribute__((__pure__))
#define __attribute_const__ __attribute__((__const__))
#define __transparent__ __attribute__((__transparent_union__))
diff --git a/xen/include/xen/macros.h b/xen/include/xen/macros.h
index e64373f018..ec89f4654f 100644
--- a/xen/include/xen/macros.h
+++ b/xen/include/xen/macros.h
@@ -59,6 +59,14 @@
#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond))
#endif
+/* Hide a value from the optimiser. */
+#define HIDE(x) \
+ ({ \
+ typeof(x) _x = (x); \
+ asm volatile ( "" : "+r" (_x) ); \
+ _x; \
+ })
+
#define ABS(x) ({ \
typeof(x) x_ = (x); \
(x_ < 0) ? -x_ : x_; \
diff --git a/xen/include/xen/self-tests.h b/xen/include/xen/self-tests.h
new file mode 100644
index 0000000000..8410db7aaa
--- /dev/null
+++ b/xen/include/xen/self-tests.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * Helpers for Xen self-tests of basic logic, including confirming that
+ * examples which should be calculated by the compiler are.
+ */
+#ifndef XEN_SELF_TESTS_H
+#define XEN_SELF_TESTS_H
+
+#include <xen/lib.h>
+
+/*
+ * Check that fn(val) can be calcuated by the compiler, and that it gives the
+ * expected answer.
+ *
+ * Clang < 8 can't fold constants through static inlines, causing this to
+ * fail. Simply skip it for incredibly old compilers.
+ */
+#if !CONFIG_CC_IS_CLANG || CONFIG_CLANG_VERSION >= 80000
+#define COMPILE_CHECK(fn, val, res) \
+ do { \
+ typeof(fn(val)) real = fn(val); \
+ \
+ if ( !__builtin_constant_p(real) ) \
+ asm ( ".error \"'" STR(fn(val)) "' not compile-time constant\"" );
\
+ else if ( real != res ) \
+ asm ( ".error \"Compile time check '" STR(fn(val) == res) "'
failed\"" ); \
+ } while ( 0 )
+#else
+#define COMPILE_CHECK(fn, val, res)
+#endif
+
+/*
+ * Check that Xen's runtime logic for fn(val) gives the expected answer. This
+ * requires using HIDE() to prevent the optimiser from collapsing the logic
+ * into a constant.
+ */
+#define RUNTIME_CHECK(fn, val, res) \
+ do { \
+ typeof(fn(val)) real = fn(HIDE(val)); \
+ \
+ if ( real != res ) \
+ panic("%s: %s(%s) expected %u, got %u\n", \
+ __func__, #fn, #val, real, res); \
+ } while ( 0 )
+
+/*
+ * Perform compile-time and runtime checks for fn(val) == res.
+ */
+#define CHECK(fn, val, res) \
+ do { \
+ COMPILE_CHECK(fn, val, res); \
+ RUNTIME_CHECK(fn, val, res); \
+ } while ( 0 )
+
+#endif /* XEN_SELF_TESTS_H */
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |