[PATCH 3/3] host/aarch64: Implement atomic64_{read, set} with FEAT_LS64
Richard Henderson <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Detect the host feature in cpuid, then use it. Signed-off-by: Richard Henderson <[email protected]> --- host/include/aarch64/host/cpuinfo.h | 1 + include/qemu/value64.h | 7 ++++ util/cpuinfo-aarch64.c | 14 ++++++-- .../include/aarch64/host/atomic512-ldst.h.inc | 36 +++++++++++++++++++ meson.build | 8 +++++ 5 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 host/include/aarch64/host/atomic512-ldst.h.inc diff --git a/host/include/aarch64/host/cpuinfo.h b/host/include/aarch64/host/cpuinfo.h index fe671534e4..ac3a224fc3 100644 --- a/host/include/aarch64/host/cpuinfo.h +++ b/host/include/aarch64/host/cpuinfo.h @@ -12,6 +12,7 @@ #define CPUINFO_AES (1u << 3) #define CPUINFO_PMULL (1u << 4) #define CPUINFO_BTI (1u << 5) +#define CPUINFO_LS64 (1u << 6) /* Initialized with a constructor. */ extern unsigned cpuinfo; diff --git a/include/qemu/value64.h b/include/qemu/value64.h index 7de287a13d..b74316bf82 100644 --- a/include/qemu/value64.h +++ b/include/qemu/value64.h @@ -3,12 +3,19 @@ #ifndef QEMU_VALUE64_H #define QEMU_VALUE64_H +#ifdef __aarch64__ +#include <arm_acle.h> +#endif + /* * An stream of 64 bytes; no endianness implied. * The members are perforce host byte ordering. */ typedef union { uint64_t l[8]; +#ifdef __aarch64__ + data512_t arm; +#endif } Value64; #endif /* QEMU_VALUE64_H */ diff --git a/util/cpuinfo-aarch64.c b/util/cpuinfo-aarch64.c index 288074c08f..0a01050626 100644 --- a/util/cpuinfo-aarch64.c +++ b/util/cpuinfo-aarch64.c @@ -13,9 +13,6 @@ # include <asm/hwcap.h> # include "elf.h" # endif -# ifndef HWCAP2_BTI -# define HWCAP2_BTI 0 /* added in glibc 2.32 */ -# endif #endif #ifdef CONFIG_ELF_AUX_INFO #include <sys/auxv.h> @@ -29,6 +26,13 @@ # include <sys/sysctl.h> #endif +#ifndef HWCAP2_BTI +# define HWCAP2_BTI 0 /* added in glibc 2.32 */ +#endif +#ifndef HWCAP3_LS64 +# define HWCAP3_LS64 0 /* added in glibc 2.44 */ +#endif + unsigned cpuinfo; #ifdef CONFIG_DARWIN @@ -72,6 +76,9 @@ unsigned __attribute__((constructor)) cpuinfo_init(void) unsigned long hwcap2 = qemu_getauxval(AT_HWCAP2); info |= (hwcap2 & HWCAP2_BTI ? CPUINFO_BTI : 0); + + unsigned long hwcap3 = qemu_getauxval(AT_HWCAP3); + info |= (hwcap3 & HWCAP3_LS64 ? CPUINFO_LS64 : 0); #endif #ifdef CONFIG_DARWIN info |= sysctl_for_bool("hw.optional.arm.FEAT_LSE") * CPUINFO_LSE; @@ -79,6 +86,7 @@ unsigned __attribute__((constructor)) cpuinfo_init(void) info |= sysctl_for_bool("hw.optional.arm.FEAT_AES") * CPUINFO_AES; info |= sysctl_for_bool("hw.optional.arm.FEAT_PMULL") * CPUINFO_PMULL; info |= sysctl_for_bool("hw.optional.arm.FEAT_BTI") * CPUINFO_BTI; + info |= sysctl_for_bool("hw.optional.arm.FEAT_LS64") * CPUINFO_LS64; #endif #if defined(__OpenBSD__) && !defined(CONFIG_ELF_AUX_INFO) int mib[2]; diff --git a/host/include/aarch64/host/atomic512-ldst.h.inc b/host/include/aarch64/host/atomic512-ldst.h.inc new file mode 100644 index 0000000000..a254560be7 --- /dev/null +++ b/host/include/aarch64/host/atomic512-ldst.h.inc @@ -0,0 +1,36 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * Load/store for 512-bit atomic operations, AArch64 version. + */ + +#ifndef HOST_ATOMIC512_LDST_H +#define HOST_ATOMIC512_LDST_H + +#ifdef CONFIG_ARM_LS64_BUILTIN +#include "host/cpuinfo.h" +#include <arm_acle.h> + +#ifdef __ARM_FEATURE_LS64 +# define HAVE_ATOMIC512_LD true +# define ATTR_LS64_ACCEL +#else +# define HAVE_ATOMIC512_LD likely(cpuinfo & CPUINFO_LS64) +# define ATTR_LS64_ACCEL __attribute__((target("+ls64"))) +#endif +#define HAVE_ATOMIC512_ST HAVE_ATOMIC512_LD + +static inline Value64 ATTR_LS64_ACCEL atomic64_read(const void *s) +{ + return (Value64){ .arm = __arm_ld64b(s) }; +} + +static inline void ATTR_LS64_ACCEL atomic64_set(void *d, const Value64 *v) +{ + __arm_st64b(d, v->arm); +} + +#else +#include "host/include/generic/host/atomic512-ldst.h.inc" +#endif + +#endif /* HOST_ATOMIC512_LDST_H */ diff --git a/meson.build b/meson.build index 164328ded8..5afeda83fd 100644 --- a/meson.build +++ b/meson.build @@ -3106,6 +3106,14 @@ config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles(''' void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); } ''')) +config_host_data.set('CONFIG_ARM_LS64_BUILTIN', cc.compiles(''' + #include <arm_acle.h> + #ifndef __ARM_FEATURE_LS64 + __attribute__((target("+ls64"))) + #endif + void foo(void *p, void *q) { __arm_st64b(q, __arm_ld64b(p)); } + ''')) + if get_option('membarrier').disabled() have_membarrier = false elif host_os == 'windows' -- 2.43.0