diff --git a/criu/include/util.h b/criu/include/util.h index 2077f44e3..20684ccf9 100644 --- a/criu/include/util.h +++ b/criu/include/util.h @@ -61,6 +61,9 @@ extern int open_pid_proc(pid_t pid); extern int close_pid_proc(void); extern int set_proc_fd(int fd); +extern pid_t sys_clone_unified(unsigned long flags, void *child_stack, void *parent_tid, + void *child_tid, unsigned long newtls); + /* * Values for pid argument of the proc opening routines below. * SELF would open file under /proc/self diff --git a/criu/util.c b/criu/util.c index 201ba096f..28fc80488 100644 --- a/criu/util.c +++ b/criu/util.c @@ -1476,20 +1476,25 @@ int getpid() return syscall(__NR_getpid); } +pid_t sys_clone_unified(unsigned long flags, void *child_stack, void *parent_tid, + void *child_tid, unsigned long newtls) +{ +#ifdef __x86_64__ + return (pid_t)syscall(__NR_clone, flags, child_stack, parent_tid, child_tid, newtls); +#elif (__i386__ || __arm__ || __aarch64__ || __powerpc64__) + return (pid_t)syscall(__NR_clone, flags, child_stack, parent_tid, newtls, child_tid); +#elif __s390x__ + return (pid_t)syscall(__NR_clone, child_stack, flags, parent_tid, child_tid, newtls); +#else +#error "Unsupported architecture" +#endif +} + /* * In glibc 2.24, fork() may fail when parent and child are * from different pid namespaces and have the same pid. */ pid_t fork() { - /* - * Two last arguments are swapped on different archs, - * but we don't care as they are zero anyway. - */ -#ifdef __s390x__ - /* See kernel/fork.c: CONFIG_CLONE_BACKWARDS2 */ - return (pid_t)syscall(__NR_clone, 0, SIGCHLD, NULL, 0, NULL); -#else - return (pid_t)syscall(__NR_clone, SIGCHLD, 0, 0, 0, 0); -#endif + return sys_clone_unified(SIGCHLD, 0, NULL, NULL, 0); } diff --git a/test/zdtm/lib/test.c b/test/zdtm/lib/test.c index fc4c82630..6dce027f0 100644 --- a/test/zdtm/lib/test.c +++ b/test/zdtm/lib/test.c @@ -297,18 +297,23 @@ void test_waitsig(void) futex_wait_while(&sig_received, 0); } +pid_t sys_clone_unified(unsigned long flags, void *child_stack, void *parent_tid, + void *child_tid, unsigned long newtls) +{ +#ifdef __x86_64__ + return (pid_t)syscall(__NR_clone, flags, child_stack, parent_tid, child_tid, newtls); +#elif (__i386__ || __arm__ || __aarch64__ ||__powerpc64__) + return (pid_t)syscall(__NR_clone, flags, child_stack, parent_tid, newtls, child_tid); +#elif __s390x__ + return (pid_t)syscall(__NR_clone, child_stack, flags, parent_tid, child_tid, newtls); +#else +#error "Unsupported architecture" +#endif +} + pid_t fork() { - /* - * Two last arguments are swapped on different archs, - * but we don't care as they are zero anyway. - */ -#ifdef __s390x__ - /* See kernel/fork.c: CONFIG_CLONE_BACKWARDS2 */ - return (pid_t)syscall(__NR_clone, 0, SIGCHLD, NULL, 0, NULL); -#else - return (pid_t)syscall(__NR_clone, SIGCHLD, 0, 0, 0, 0); -#endif + return sys_clone_unified(SIGCHLD, NULL, NULL, NULL, 0); } int getpid()