18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#ifndef _CLONE3_SELFTESTS_H 48c2ecf20Sopenharmony_ci#define _CLONE3_SELFTESTS_H 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#define _GNU_SOURCE 78c2ecf20Sopenharmony_ci#include <sched.h> 88c2ecf20Sopenharmony_ci#include <linux/sched.h> 98c2ecf20Sopenharmony_ci#include <linux/types.h> 108c2ecf20Sopenharmony_ci#include <stdint.h> 118c2ecf20Sopenharmony_ci#include <syscall.h> 128c2ecf20Sopenharmony_ci#include <sys/wait.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include "../kselftest.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr))) 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#ifndef CLONE_INTO_CGROUP 198c2ecf20Sopenharmony_ci#define CLONE_INTO_CGROUP 0x200000000ULL /* Clone into a specific cgroup given the right permissions. */ 208c2ecf20Sopenharmony_ci#endif 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#ifndef __NR_clone3 238c2ecf20Sopenharmony_ci#define __NR_clone3 -1 248c2ecf20Sopenharmony_ci#endif 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistruct __clone_args { 278c2ecf20Sopenharmony_ci __aligned_u64 flags; 288c2ecf20Sopenharmony_ci __aligned_u64 pidfd; 298c2ecf20Sopenharmony_ci __aligned_u64 child_tid; 308c2ecf20Sopenharmony_ci __aligned_u64 parent_tid; 318c2ecf20Sopenharmony_ci __aligned_u64 exit_signal; 328c2ecf20Sopenharmony_ci __aligned_u64 stack; 338c2ecf20Sopenharmony_ci __aligned_u64 stack_size; 348c2ecf20Sopenharmony_ci __aligned_u64 tls; 358c2ecf20Sopenharmony_ci#ifndef CLONE_ARGS_SIZE_VER0 368c2ecf20Sopenharmony_ci#define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */ 378c2ecf20Sopenharmony_ci#endif 388c2ecf20Sopenharmony_ci __aligned_u64 set_tid; 398c2ecf20Sopenharmony_ci __aligned_u64 set_tid_size; 408c2ecf20Sopenharmony_ci#ifndef CLONE_ARGS_SIZE_VER1 418c2ecf20Sopenharmony_ci#define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */ 428c2ecf20Sopenharmony_ci#endif 438c2ecf20Sopenharmony_ci __aligned_u64 cgroup; 448c2ecf20Sopenharmony_ci#ifndef CLONE_ARGS_SIZE_VER2 458c2ecf20Sopenharmony_ci#define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */ 468c2ecf20Sopenharmony_ci#endif 478c2ecf20Sopenharmony_ci}; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic pid_t sys_clone3(struct __clone_args *args, size_t size) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci fflush(stdout); 528c2ecf20Sopenharmony_ci fflush(stderr); 538c2ecf20Sopenharmony_ci return syscall(__NR_clone3, args, size); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic inline void test_clone3_supported(void) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci pid_t pid; 598c2ecf20Sopenharmony_ci struct __clone_args args = {}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci if (__NR_clone3 < 0) 628c2ecf20Sopenharmony_ci ksft_exit_skip("clone3() syscall is not supported\n"); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci /* Set to something that will always cause EINVAL. */ 658c2ecf20Sopenharmony_ci args.exit_signal = -1; 668c2ecf20Sopenharmony_ci pid = sys_clone3(&args, sizeof(args)); 678c2ecf20Sopenharmony_ci if (!pid) 688c2ecf20Sopenharmony_ci exit(EXIT_SUCCESS); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci if (pid > 0) { 718c2ecf20Sopenharmony_ci wait(NULL); 728c2ecf20Sopenharmony_ci ksft_exit_fail_msg( 738c2ecf20Sopenharmony_ci "Managed to create child process with invalid exit_signal\n"); 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci if (errno == ENOSYS) 778c2ecf20Sopenharmony_ci ksft_exit_skip("clone3() syscall is not supported\n"); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci ksft_print_msg("clone3() syscall supported\n"); 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#endif /* _CLONE3_SELFTESTS_H */ 83