1 Star 0 Fork 35

cf-zhao/criu

forked from src-openEuler/criu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0011-zdtm-static-rseq00-fix-rseq-test-when-linking-with-a.patch 4.33 KB
一键复制 编辑 原始数据 按行查看 历史
river 提交于 2022-04-13 15:05 . criu: backport kinds of features/bugfix
From 7cc800d2cfbfb6fe686345a652472b194ca2b9cf 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/72] 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.34.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/cf-zhao/criu.git
git@gitee.com:cf-zhao/criu.git
cf-zhao
criu
criu
master

搜索帮助