mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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:
1 parent
1408cf7a28
commit
ea59e7d780
4 files changed
+76
-4
No files matched your search
@@ -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 */
|
||||
@@ -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__))
|
||||
|
||||
|
||||
@@ -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_; \
|
||||
|
||||
@@ -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 */
|
||||