mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 22:35:33 +00:00
s390x: use clone3() if possible
This adds the parasite clone3() with set_tid wrapper for s390x. In contrast to the x86_64 implementation the thread start address and arguments are not put on the thread stack but passed via r4 and r5. As those registers are caller-saved they still contain the correct value (thread start address and arguments) after returning from the syscall. Tested on 5.5.0-rc6. Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
committed by
Andrei Vagin
parent
4c4f67a56b
commit
cbadd201cb
@@ -40,11 +40,41 @@
|
||||
: "0", "1", "2", "3", "4", "5", "6", "cc", "memory")
|
||||
|
||||
#define RUN_CLONE3_RESTORE_FN(ret, clone_args, size, args, \
|
||||
clone_restore_fn) do { \
|
||||
pr_err("This architecture does not support clone3() with set_tid, yet!\n"); \
|
||||
pr_err("Not creating a process with PID: %d\n", ((pid_t *)u64_to_ptr(clone_args.set_tid))[0]); \
|
||||
ret = -1; \
|
||||
} while (0)
|
||||
clone_restore_fn) \
|
||||
asm volatile( \
|
||||
/*
|
||||
* clone3 only needs two arguments (r2, r3), this means
|
||||
* we can use r4 and r5 for args and thread function.
|
||||
* r4 and r5 are callee-saved and are not overwritten.
|
||||
* No need to put these values on the child stack.
|
||||
*/ \
|
||||
"lgr %%r4,%4\n" /* Save args in %r4 */ \
|
||||
"lgr %%r5,%3\n" /* Save clone_restore_fn in %r5 */ \
|
||||
"lgr %%r2,%1\n" /* Parameter 1: clone_args */ \
|
||||
"lgr %%r3,%2\n" /* Parameter 2: size */ \
|
||||
/*
|
||||
* On s390x a syscall is done sc <syscall number>.
|
||||
* That only works for syscalls < 255. clone3 is 435,
|
||||
* therefore it is necessary to load the syscall number
|
||||
* into r1 and do 'svc 0'.
|
||||
*/ \
|
||||
"lghi %%r1,"__stringify(__NR_clone3)"\n" \
|
||||
"svc 0\n" \
|
||||
"ltgr %0,%%r2\n" /* Set and check "ret" */ \
|
||||
"jnz 0f\n" /* ret != 0: Continue caller */ \
|
||||
"lgr %%r2,%%r4\n" /* Thread arguments taken from r4. */ \
|
||||
"lgr %%r1,%%r5\n" /* Thread function taken from r5. */ \
|
||||
"aghi %%r15,-160\n" /* Prepare stack frame */ \
|
||||
"xc 0(8,%%r15),0(%%r15)\n" \
|
||||
"basr %%r14,%%r1\n" /* Jump to clone_restore_fn() */ \
|
||||
"j .+2\n" /* BUG(): Force PGM check */ \
|
||||
"0:\n" /* Continue caller */ \
|
||||
: "=d"(ret) \
|
||||
: "a"(&clone_args), \
|
||||
"d"(size), \
|
||||
"d"(clone_restore_fn), \
|
||||
"d"(args) \
|
||||
: "0", "1", "2", "3", "4", "5", "cc", "memory")
|
||||
|
||||
#define arch_map_vdso(map, compat) -1
|
||||
|
||||
|
@@ -992,10 +992,10 @@ static bool kerndat_has_clone3_set_tid(void)
|
||||
pid_t pid;
|
||||
struct _clone_args args = {};
|
||||
|
||||
#ifndef CONFIG_X86_64
|
||||
#if !defined(CONFIG_X86_64) && !defined(CONFIG_S390)
|
||||
/*
|
||||
* Currently the CRIU PIE assembler clone3() wrapper is
|
||||
* only implemented for X86_64.
|
||||
* only implemented for X86_64 and S390X.
|
||||
*/
|
||||
kdat.has_clone3_set_tid = false;
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user