2
0
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:
Adrian Reber
2020-01-16 16:41:40 +01:00
committed by Andrei Vagin
parent 4c4f67a56b
commit cbadd201cb
2 changed files with 37 additions and 7 deletions

View File

@@ -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

View File

@@ -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;