mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
zdtm: add basic static/rseq00 test for rseq C/R
Here we just want to check that if rseq was registered before C/R it remains registered after it. Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
This commit is contained in:
parent
c5162cef52
commit
51e0d3e29f
3 changed files with 112 additions and 0 deletions
|
|
@ -61,6 +61,7 @@ TST_NOFILE := \
|
|||
pthread02 \
|
||||
pthread_timers \
|
||||
pthread_timers_h \
|
||||
rseq00 \
|
||||
vdso00 \
|
||||
vdso01 \
|
||||
vdso02 \
|
||||
|
|
|
|||
110
test/zdtm/static/rseq00.c
Normal file
110
test/zdtm/static/rseq00.c
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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>";
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
test_init(argc, argv);
|
||||
|
||||
register_thread();
|
||||
|
||||
test_daemon();
|
||||
test_waitsig();
|
||||
|
||||
check_thread();
|
||||
|
||||
pass();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* #if defined(__x86_64__) */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
test_init(argc, argv);
|
||||
skip("Unsupported arch");
|
||||
test_daemon();
|
||||
test_waitsig();
|
||||
pass();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* #if defined(__x86_64__) */
|
||||
1
test/zdtm/static/rseq00.desc
Normal file
1
test/zdtm/static/rseq00.desc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{'flavor': 'h', 'arch': 'x86_64', 'feature': 'get_rseq_conf'}
|
||||
Loading…
Add table
Add a link
Reference in a new issue