1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 #ifndef _CLONE3_SELFTESTS_H 4 #define _CLONE3_SELFTESTS_H 5 6 #define _GNU_SOURCE 7 #include <sched.h> 8 #include <stdint.h> 9 #include <syscall.h> 10 #include <linux/types.h> 11 12 #define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr))) 13 14 #ifndef __NR_clone3 15 #define __NR_clone3 -1 16 struct clone_args { 17 __aligned_u64 flags; 18 __aligned_u64 pidfd; 19 __aligned_u64 child_tid; 20 __aligned_u64 parent_tid; 21 __aligned_u64 exit_signal; 22 __aligned_u64 stack; 23 __aligned_u64 stack_size; 24 __aligned_u64 tls; 25 __aligned_u64 set_tid; 26 __aligned_u64 set_tid_size; 27 }; 28 #endif 29 30 static pid_t sys_clone3(struct clone_args *args, size_t size) 31 { 32 fflush(stdout); 33 fflush(stderr); 34 return syscall(__NR_clone3, args, size); 35 } 36 37 static inline void test_clone3_supported(void) 38 { 39 pid_t pid; 40 struct clone_args args = {}; 41 42 if (__NR_clone3 < 0) 43 ksft_exit_skip("clone3() syscall is not supported\n"); 44 45 /* Set to something that will always cause EINVAL. */ 46 args.exit_signal = -1; 47 pid = sys_clone3(&args, sizeof(args)); 48 if (!pid) 49 exit(EXIT_SUCCESS); 50 51 if (pid > 0) { 52 wait(NULL); 53 ksft_exit_fail_msg( 54 "Managed to create child process with invalid exit_signal\n"); 55 } 56 57 if (errno == ENOSYS) 58 ksft_exit_skip("clone3() syscall is not supported\n"); 59 60 ksft_print_msg("clone3() syscall supported\n"); 61 } 62 63 #endif /* _CLONE3_SELFTESTS_H */ 64