1/*
2 * This file is subject to the terms and conditions of the LGPL V2.1
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2018 Kalray Inc.
7 */
8
9#include <sysdep.h>
10#define _ERRNO_H	1
11#include <bits/errno.h>
12
13/**
14 * Clone system call implementation for kvx
15 * int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg,
16 *             pid_t *ptid, struct user_desc *tls, pid_t *ctid);
17 * $r0 = fn
18 * $r1 = child_stack
19 * $r2 = flags
20 * $r3 = args
21 * $r4 = ptid
22 * $r5 = tls
23 * $r6 = ctid
24 *
25 * The kernel expects to find its arguments in the following order:
26 * sys_clone(unsigned long clone_flags, unsigned long newsp,
27 *		 int __user * parent_tidptr,
28 *		 int __user * child_tidptr,
29 *		 unsigned long tls)
30 *
31 * So we have to make a few modifications before calling
32 *
33 */
34
35ENTRY (__clone)
36	/* Check fn and stack to be non-null */
37	cb.deqz $r1? L(clone_einval_error)
38	/* Align child stack first */
39	andd $r1 = $r1, -32
40	;;
41	cb.deqz $r0? L(clone_einval_error)
42	/* Prepare space for child arguments on stack and stay aligned */
43	addd $r1 = $r1, -32
44	;;
45	/* Save fn ($r0) on child stack */
46	sd 0[$r1] = $r0
47	/* Set clone_flags */
48	copyd $r0 = $r2
49	;;
50	/* Save args ($r3) on child stack */
51	sd 8[$r1] = $r3
52	/* Set parent_tidptr */
53	copyd $r2 = $r4
54	/* Set child_tidptr */
55	copyd $r3 = $r6
56	/* Set tls */
57	copyd $r4 = $r5
58	;;
59	scall SYS_ify(clone)
60	;;
61	/* If 0, then we are the child */
62	cb.deqz $r0? L(child_start)
63	;;
64	/* Else we are the parent, and we need to check for errors */
65	cb.dltz $r0? L(clone_error)
66	;;
67	/* No error ! Yeepa ! */
68	ret
69	;;
70L(child_start):
71	/* get fn from stack */
72	ld $r1 = 0[$sp]
73	;;
74	/* Get args from stack */
75	ld $r0 = 8[$sp]
76	addd $sp = $sp, 32
77	;;
78	icall $r1
79	;;
80	scall SYS_ify(exit)
81	;;
82	/* We should never ever get here ! */
83	errop
84	;;
85L(clone_einval_error):
86	make $r0 = -EINVAL
87	;;
88L(clone_error):
89	/* goto __syscall_error but do not use call or $ra will be
90	 * destroyed */
91	goto __syscall_error
92	;;
93	/* We will not return here but to clone caller
94	 * (stored in $ra) */
95	errop
96	;;
97END(__clone)
98
99libc_hidden_def (__clone)
100weak_alias (__clone,clone)
101