Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>2021-12-24 22:56:56 +0300
committerAndrei Vagin <avagin@gmail.com>2022-04-29 03:53:52 +0300
commit441310c2600e9f95e53a140a321981801c9941fd (patch)
treee6a6c039d436c7cb630ce49f4bd5b019ca2eab93
parentf70ddab24eeb99fcbab0015c8338b673d002d5e6 (diff)
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>
-rw-r--r--test/zdtm/static/rseq00.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/test/zdtm/static/rseq00.c b/test/zdtm/static/rseq00.c
index b73b1b258..471ad6a43 100644
--- a/test/zdtm/static/rseq00.c
+++ b/test/zdtm/static/rseq00.c
@@ -19,12 +19,52 @@
#include "zdtmtst.h"
+#ifdef __has_include
+#if __has_include("sys/rseq.h")
+#include <sys/rseq.h>
+#endif
+#endif
+
#if 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 /* __x86_64__ */
+ return __result;
+#endif /* !GCC 11 */
+}
+
+static inline void unregister_glibc_rseq(void)
+{
+ struct rseq *rseq = (struct rseq *)((char *)__criu_thread_pointer() + __rseq_offset);
+
+ /* hack: mark glibc rseq structure as failed to register */
+ rseq->cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
+
+ /* unregister rseq */
+ syscall(__NR_rseq, (void *)rseq, __rseq_size, 1, RSEQ_SIG);
+}
+#else
+static inline void unregister_glibc_rseq(void)
+{
+}
+#endif /* defined(RSEQ_SIG) */
+
const char *test_doc = "Check that rseq() basic C/R works";
const char *test_author = "Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>";
/* some useful definitions from kernel uapi */
+#ifndef RSEQ_SIG
+
enum rseq_flags {
RSEQ_FLAG_UNREGISTER = (1 << 0),
};
@@ -36,6 +76,10 @@ struct rseq {
uint32_t flags;
} __attribute__((aligned(4 * sizeof(uint64_t))));
+#define RSEQ_SIG 0x53053053
+
+#endif /* RSEQ_SIG */
+
#ifndef __NR_rseq
#define __NR_rseq 334
#endif
@@ -43,8 +87,6 @@ struct rseq {
static __thread volatile struct rseq __rseq_abi;
-#define RSEQ_SIG 0x53053053
-
static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, int flags, uint32_t sig)
{
return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig);
@@ -53,6 +95,7 @@ static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, int flags
static void register_thread(void)
{
int rc;
+ unregister_glibc_rseq();
rc = sys_rseq(&__rseq_abi, sizeof(struct rseq), 0, RSEQ_SIG);
if (rc) {
fail("Failed to register rseq");
@@ -60,16 +103,6 @@ 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);
- if (rc) {
- fail("Failed to unregister rseq");
- exit(1);
- }
-}
-
static void check_thread(void)
{
int rc;