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
path: root/test
diff options
context:
space:
mode:
authorAlexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>2022-02-23 23:20:29 +0300
committerAndrei Vagin <avagin@gmail.com>2022-04-29 03:53:52 +0300
commitdb9ec13616625f98db95b00438a370f8a660bfee (patch)
treef19c89d56209d5eaeeaee49361767c611a6f0ff8 /test
parent1e0bed3d692b4a368924a21aa4555a27cc9ab9d6 (diff)
zdtm: add rseq02 transition test with NO_RESTART CS flag
Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
Diffstat (limited to 'test')
-rw-r--r--test/zdtm/transition/Makefile2
-rw-r--r--test/zdtm/transition/rseq01.c47
l---------test/zdtm/transition/rseq02.c1
l---------test/zdtm/transition/rseq02.desc1
4 files changed, 51 insertions, 0 deletions
diff --git a/test/zdtm/transition/Makefile b/test/zdtm/transition/Makefile
index fae4e27b3..98440f4e2 100644
--- a/test/zdtm/transition/Makefile
+++ b/test/zdtm/transition/Makefile
@@ -24,6 +24,7 @@ TST_NOFILE = \
pid_reuse \
pidfd_store_sk \
rseq01 \
+ rseq02 \
TST_FILE = \
@@ -82,6 +83,7 @@ ptrace: LDFLAGS += -pthread
fork2: CFLAGS += -D FORK2
thread-bomb.o: CFLAGS += -pthread
thread-bomb: LDFLAGS += -pthread
+rseq02: CFLAGS += -D NORESTART
%: %.sh
cp $< $@
diff --git a/test/zdtm/transition/rseq01.c b/test/zdtm/transition/rseq01.c
index 7a22854a3..b6d470785 100644
--- a/test/zdtm/transition/rseq01.c
+++ b/test/zdtm/transition/rseq01.c
@@ -58,6 +58,18 @@ enum rseq_flags {
RSEQ_FLAG_UNREGISTER = (1 << 0),
};
+enum rseq_cs_flags_bit {
+ RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT = 0,
+ RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT = 1,
+ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT = 2,
+};
+
+enum rseq_cs_flags {
+ RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT = (1U << RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT_BIT),
+ RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = (1U << RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT),
+ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = (1U << RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT),
+};
+
struct rseq {
uint32_t cpu_id_start;
uint32_t cpu_id;
@@ -111,6 +123,7 @@ static int rseq_addv(intptr_t *v, intptr_t count, int cpu)
{
double a = 10000000000000000.0;
double b = -1;
+ uint64_t rseq_cs1 = 0, rseq_cs2 = 0;
/* clang-format off */
__asm__ __volatile__ goto(
@@ -134,6 +147,9 @@ static int rseq_addv(intptr_t *v, intptr_t count, int cpu)
"fsqrt\n\t" /* heavy instruction */
"dec %%rcx\n\t"
"jnz 5b\n\t"
+ "movq %%rax, %[rseq_cs_check2]\n\t"
+ "movq %[rseq_cs], %%rax\n\t"
+ "movq %%rax, %[rseq_cs_check1]\n\t"
"fstpl %[y]\n\t"
"2:\n\t"
".pushsection __rseq_failure, \"ax\"\n\t"
@@ -149,6 +165,8 @@ static int rseq_addv(intptr_t *v, intptr_t count, int cpu)
: [cpu_id] "r" (cpu),
[current_cpu_id] "m" (rseq_ptr->cpu_id),
[rseq_cs] "m" (rseq_ptr->rseq_cs),
+ [rseq_cs_check1] "m" (rseq_cs1),
+ [rseq_cs_check2] "m" (rseq_cs2),
/* final store input */
[v] "m" (*v),
[count] "er" (count),
@@ -159,9 +177,22 @@ static int rseq_addv(intptr_t *v, intptr_t count, int cpu)
);
/* clang-format on */
rseq_after_asm_goto();
+ test_msg("exit %lx %lx %f %f\n", rseq_cs1, rseq_cs2, a, b);
+ if (rseq_cs1 != rseq_cs2) {
+ /*
+ * It means that we finished critical section
+ * *normally* (haven't jumped to abort) but the kernel had cleaned up
+ * rseq_ptr->rseq_cs before we left critical section
+ * and CRIU didn't restore it correctly.
+ * That's a bug picture.
+ */
+ return -1;
+ }
+
return 0;
abort:
rseq_after_asm_goto();
+ test_msg("abort %lx %lx %f %f\n", rseq_cs1, rseq_cs2, a, b);
return -1;
}
@@ -183,16 +214,32 @@ int main(int argc, char *argv[])
fail("calloc");
exit(EXIT_FAILURE);
}
+
register_thread();
+ /*
+ * We want to test that RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL
+ * is handled properly by CRIU, but that flag can be used
+ * only with all another flags set.
+ * Please, refer to
+ * https://github.com/torvalds/linux/blob/ce522ba9/kernel/rseq.c#L192
+ */
+#ifdef NORESTART
+ rseq_ptr->flags = RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT | RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL |
+ RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE;
+#endif
+
test_daemon();
while (test_go()) {
cpu = RSEQ_ACCESS_ONCE(rseq_ptr->cpu_id_start);
ret = rseq_addv(&cpu_data[cpu], 2, cpu);
+/* NORESTART is NOT set */
+#ifndef NORESTART
/* just ignore abort */
ret = 0;
+#endif
if (ret)
break;
diff --git a/test/zdtm/transition/rseq02.c b/test/zdtm/transition/rseq02.c
new file mode 120000
index 000000000..d56491719
--- /dev/null
+++ b/test/zdtm/transition/rseq02.c
@@ -0,0 +1 @@
+rseq01.c \ No newline at end of file
diff --git a/test/zdtm/transition/rseq02.desc b/test/zdtm/transition/rseq02.desc
new file mode 120000
index 000000000..b888f0da7
--- /dev/null
+++ b/test/zdtm/transition/rseq02.desc
@@ -0,0 +1 @@
+rseq01.desc \ No newline at end of file