1 Star 0 Fork 35

WangTsing-Yan/criu

forked from src-openEuler/criu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0007-zdtm-add-simple-test-for-rseq-C-R-Signed-off-by-Alex.patch 5.16 KB
一键复制 编辑 原始数据 按行查看 历史
river 提交于 2022-04-13 15:05 . criu: backport kinds of features/bugfix
From dc83ed27d305237298b8754d1159f2e7f5c926ae Mon Sep 17 00:00:00 2001
From: bb-cat <ningyu9@huawei.com>
Date: Wed, 2 Mar 2022 14:54:28 +0800
Subject: [PATCH 07/72] zdtm: add simple test for rseq C/R Signed-off-by:
Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
---
test/zdtm/static/Makefile | 1 +
test/zdtm/static/rseq00.c | 174 +++++++++++++++++++++++++++++++++++
test/zdtm/static/rseq00.desc | 1 +
3 files changed, 176 insertions(+)
create mode 100644 test/zdtm/static/rseq00.c
create mode 100644 test/zdtm/static/rseq00.desc
diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
index 70123cf..563d947 100644
--- a/test/zdtm/static/Makefile
+++ b/test/zdtm/static/Makefile
@@ -61,6 +61,7 @@ TST_NOFILE := \
pthread02 \
pthread_timers \
pthread_timers_h \
+ rseq00 \
vdso00 \
vdso01 \
vdso02 \
diff --git a/test/zdtm/static/rseq00.c b/test/zdtm/static/rseq00.c
new file mode 100644
index 0000000..26f41a2
--- /dev/null
+++ b/test/zdtm/static/rseq00.c
@@ -0,0 +1,174 @@
+/*
+ * test for rseq() syscall
+ * See also https://www.efficios.com/blog/2019/02/08/linux-restartable-sequences/
+ * https://github.com/torvalds/linux/commit/d7822b1e24f2df5df98c76f0e94a5416349ff759
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <syscall.h>
+
+#include "zdtmtst.h"
+
+#if defined(__x86_64__)
+
+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 */
+enum rseq_flags {
+ RSEQ_FLAG_UNREGISTER = (1 << 0),
+};
+
+struct rseq {
+ uint32_t cpu_id_start;
+ uint32_t cpu_id;
+ uint64_t rseq_cs;
+ uint32_t flags;
+} __attribute__((aligned(4 * sizeof(uint64_t))));
+
+#ifndef __NR_rseq
+#define __NR_rseq 334
+#endif
+/* EOF */
+
+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);
+}
+
+static void register_thread(void)
+{
+ int rc;
+ rc = sys_rseq(&__rseq_abi, 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);
+ if (!(rc && errno == EBUSY)) {
+ fail("Failed to check rseq %d", rc);
+ exit(1);
+ }
+}
+
+#define RSEQ_ACCESS_ONCE(x) (*(__volatile__ __typeof__(x) *)&(x))
+
+static int rseq_addv(intptr_t *v, intptr_t count, int cpu)
+{
+ /* clang-format off */
+ __asm__ __volatile__ goto(
+ ".pushsection __rseq_table, \"aw\"\n\t"
+ ".balign 32\n\t"
+ "cs_obj:\n\t"
+ /* version, flags */
+ ".long 0, 0\n\t"
+ /* start_ip, post_commit_ip, abort_ip */
+ ".quad 1f, (2f-1f), 4f\n\t"
+ ".popsection\n\t"
+ "1:\n\t"
+ "leaq cs_obj(%%rip), %%rax\n\t"
+ "movq %%rax, %[rseq_cs]\n\t"
+ "cmpl %[cpu_id], %[current_cpu_id]\n\t"
+ "jnz 4f\n\t"
+ "addq %[count], %[v]\n\t" /* final store */
+ "2:\n\t"
+ ".pushsection __rseq_failure, \"ax\"\n\t"
+ /* Disassembler-friendly signature: nopl <sig>(%rip). */
+ ".byte 0x0f, 0x1f, 0x05\n\t"
+ ".long 0x53053053\n\t" /* RSEQ_FLAGS */
+ "4:\n\t"
+ "jmp abort\n\t"
+ ".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),
+ /* final store input */
+ [v] "m" (*v),
+ [count] "er" (count)
+ : "memory", "cc", "rax"
+ : abort
+ );
+ /* clang-format on */
+
+ return 0;
+abort:
+ return -1;
+}
+
+int main(int argc, char *argv[])
+{
+ int cpu, ret;
+ intptr_t *cpu_data;
+ long nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+
+ test_init(argc, argv);
+
+ cpu_data = calloc(nr_cpus, sizeof(*cpu_data));
+ if (!cpu_data) {
+ fail("calloc");
+ exit(EXIT_FAILURE);
+ }
+
+ register_thread();
+
+ test_daemon();
+ test_waitsig();
+
+ check_thread();
+
+ cpu = RSEQ_ACCESS_ONCE(__rseq_abi.cpu_id_start);
+ ret = rseq_addv(&cpu_data[cpu], 2, cpu);
+ if (ret)
+ fail("Failed to increment per-cpu counter");
+ else
+ test_msg("cpu_data[%d] == %ld\n", cpu, (long int)cpu_data[cpu]);
+
+ if (cpu_data[cpu] == 2)
+ pass();
+ else
+ fail();
+
+ return 0;
+}
+
+#else
+
+int main(int argc, char *argv[])
+{
+ test_init(argc, argv);
+ skip("Unsupported arch");
+ return 0;
+}
+
+#endif
\ No newline at end of file
diff --git a/test/zdtm/static/rseq00.desc b/test/zdtm/static/rseq00.desc
new file mode 100644
index 0000000..0324fa3
--- /dev/null
+++ b/test/zdtm/static/rseq00.desc
@@ -0,0 +1 @@
+{'flavor': 'h', 'arch': 'x86_64', 'feature': 'get_rseq_conf'}
--
2.34.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/WangTsing-Yan/criu.git
git@gitee.com:WangTsing-Yan/criu.git
WangTsing-Yan
criu
criu
master

搜索帮助