see https://github.com/checkpoint-restore/criu/issues/1696 and https://github.com/checkpoint-restore/criu/pull/1706
159 lines
4.3 KiB
Diff
159 lines
4.3 KiB
Diff
From 4f4d5acc34046954aea9e8ea10b5f71ff5f0fbd5 Mon Sep 17 00:00:00 2001
|
|
From: bb-cat <ningyu9@huawei.com>
|
|
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 <alexander.mikhalitsyn@virtuozzo.com>
|
|
---
|
|
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 <sys/rseq.h>
|
|
+#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 <alexander.mikhalitsyn@virtuozzo.com>";
|
|
/* 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
|
|
|