From 4f4d5acc34046954aea9e8ea10b5f71ff5f0fbd5 Mon Sep 17 00:00:00 2001 From: bb-cat Date: Wed, 2 Mar 2022 15:01:34 +0800 Subject: [PATCH 11/16] zdtm/static/rseq00: fix rseq test when linking with a fresh Glibc Fresh Glibc does rseq() register by default. We need to unregister rseq before registering our own. Signed-off-by: Alexander Mikhalitsyn --- test/zdtm/static/rseq00.c | 76 ++++++++++++++++++++------- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/test/zdtm/static/rseq00.c b/test/zdtm/static/rseq00.c index 26f41a2..87053b8 100644 --- a/test/zdtm/static/rseq00.c +++ b/test/zdtm/static/rseq00.c @@ -19,13 +19,48 @@ #include "zdtmtst.h" -#if defined(__x86_64__) +#ifdef __has_include +#if __has_include("sys/rseq.h") +#include +#endif +#endif + +#if defined(__i386__) || defined(__x86_64__) + +#if defined(RSEQ_SIG) +static inline void *__criu_thread_pointer(void) +{ +#if __GNUC_PREREQ(11, 1) + return __builtin_thread_pointer(); +#else + void *__result; +#ifdef __x86_64__ + __asm__("mov %%fs:0, %0" : "=r"(__result)); +#else + __asm__("mov %%gs:0, %0" : "=r"(__result)); +#endif + return __result; +#endif /* !GCC 11 */ +} + +static inline void unregister_glibc_rseq(void) +{ + /* unregister rseq */ + syscall(__NR_rseq, (void *)((char *)__criu_thread_pointer() + __rseq_offset), __rseq_size, 1, RSEQ_SIG); +} +#else +static inline void unregister_glibc_rseq(void) +{ +} +#endif const char *test_doc = "Check that rseq() basic C/R works"; const char *test_author = "Alexander Mikhalitsyn "; /* parts of code borrowed from https://www.efficios.com/blog/2019/02/08/linux-restartable-sequences/ */ /* some useful definitions from kernel uapi */ +#ifndef RSEQ_SIG + enum rseq_flags { RSEQ_FLAG_UNREGISTER = (1 << 0), }; @@ -37,14 +72,21 @@ struct rseq { uint32_t flags; } __attribute__((aligned(4 * sizeof(uint64_t)))); +#define RSEQ_SIG 0x53053053 + +#endif + #ifndef __NR_rseq #define __NR_rseq 334 #endif /* EOF */ -static __thread volatile struct rseq __rseq_abi; +#define RSEQ_TLS_ALLOC 0 -#define RSEQ_SIG 0x53053053 +static volatile struct rseq *rseq_ptr; +#if RSEQ_TLS_ALLOC +static __thread volatile struct rseq __rseq_abi; +#endif static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, int flags, uint32_t sig) { @@ -54,27 +96,18 @@ static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, int flags static void register_thread(void) { int rc; - rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 0, RSEQ_SIG); + unregister_glibc_rseq(); + rc = sys_rseq(rseq_ptr, sizeof(struct rseq), 0, RSEQ_SIG); if (rc) { fail("Failed to register rseq"); exit(1); } } -static void unregister_thread(void) -{ - int rc; - rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG); - if (rc) { - fail("Failed to unregister rseq"); - exit(1); - } -} - static void check_thread(void) { int rc; - rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 0, RSEQ_SIG); + rc = sys_rseq(rseq_ptr, sizeof(struct rseq), 0, RSEQ_SIG); if (!(rc && errno == EBUSY)) { fail("Failed to check rseq %d", rc); exit(1); @@ -111,8 +144,8 @@ static int rseq_addv(intptr_t *v, intptr_t count, int cpu) ".popsection\n\t" : /* gcc asm goto does not allow outputs */ : [cpu_id] "r" (cpu), - [current_cpu_id] "m" (__rseq_abi.cpu_id), - [rseq_cs] "m" (__rseq_abi.rseq_cs), + [current_cpu_id] "m" (rseq_ptr->cpu_id), + [rseq_cs] "m" (rseq_ptr->rseq_cs), /* final store input */ [v] "m" (*v), [count] "er" (count) @@ -132,6 +165,13 @@ int main(int argc, char *argv[]) intptr_t *cpu_data; long nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); +#if RSEQ_TLS_ALLOC + rseq_ptr = &__rseq_abi; +#else + //rseq_ptr = malloc(sizeof(struct rseq)); + rseq_ptr = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0); +#endif + test_init(argc, argv); cpu_data = calloc(nr_cpus, sizeof(*cpu_data)); @@ -147,7 +187,7 @@ int main(int argc, char *argv[]) check_thread(); - cpu = RSEQ_ACCESS_ONCE(__rseq_abi.cpu_id_start); + cpu = RSEQ_ACCESS_ONCE(rseq_ptr->cpu_id_start); ret = rseq_addv(&cpu_data[cpu], 2, cpu); if (ret) fail("Failed to increment per-cpu counter"); -- 2.30.0