From d4274171388ee9594d5ec74451e3de4ac83d9682 Mon Sep 17 00:00:00 2001
From: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
Date: Fri, 24 Dec 2021 22:56:56 +0300
Subject: [PATCH 10/10] zdtm fixup: fix rseq test when linking with fresh glibc
Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
---
test/zdtm/static/rseq.c | 58 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 51 insertions(+), 7 deletions(-)
diff --git a/test/zdtm/static/rseq.c b/test/zdtm/static/rseq.c
index f2fccb8f4..a679ebd7a 100644
--- a/test/zdtm/static/rseq.c
+++ b/test/zdtm/static/rseq.c
@@ -19,6 +19,32 @@
#include "zdtmtst.h"
+#if defined(__x86_64__) && (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 34)
+#include <sys/rseq.h>
+#endif
+
+#if defined(__x86_64__) && defined(RSEQ_SIG)
+static inline void *
+thread_pointer (void)
+{
+ void *result;
+ asm ("mov %%fs:0, %0" : "=r" (result));
+ return result;
+}
+
+static inline void
+unregister_rseq_asdf (void)
+{
+ /* unregister rseq */
+ syscall(__NR_rseq, (void *)((char *) thread_pointer () + __rseq_offset), __rseq_size, 1, RSEQ_SIG);
+}
+#else
+static inline void
+unregister_rseq_asdf (void)
+{
+}
+#endif
+
#if defined(__x86_64__)
const char *test_doc = "Check that rseq() basic C/R works";
@@ -26,6 +52,8 @@ const char *test_author = "Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozz
/* 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 +65,22 @@ 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 */
+#define RSEQ_TLS_ALLOC 0
+
+static volatile struct rseq *rseq_ptr;
+#if RSEQ_TLS_ALLOC
static __thread volatile struct rseq __rseq_abi;
+#endif
-#define RSEQ_SIG 0x53053053
#define TESTRSEQ 1
#ifdef TESTRSEQ
static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, int flags, uint32_t sig)
@@ -55,7 +91,8 @@ 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_rseq_asdf();
+ rc = sys_rseq(rseq_ptr, sizeof(struct rseq), 0, RSEQ_SIG);
if (rc) {
fail("Failed to register rseq");
exit(1);
@@ -65,7 +102,7 @@ static void register_thread(void)
static void unregister_thread(void)
{
int rc;
- rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
+ rc = sys_rseq(rseq_ptr, sizeof(struct rseq), RSEQ_FLAG_UNREGISTER, RSEQ_SIG);
if (rc) {
fail("Failed to unregister rseq");
exit(1);
@@ -75,7 +112,7 @@ static void unregister_thread(void)
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);
@@ -112,8 +149,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)
@@ -135,6 +172,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));
@@ -151,7 +195,7 @@ int main(int argc, char *argv[])
#ifdef TESTRSEQ
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.34.1