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@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
This commit is contained in:
Andrew Cooper committed 2024-06-01 02:28:14 +01:00
1 parent 1408cf7a28
commit ea59e7d780
4 files changed
+76 -4

No files matched your search

+10 -3
View File
@@ -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 */
+2 -1
View File
@@ -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__))
+8
View File
@@ -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_; \
+56
View File
@@ -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 */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.