123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- /*
- * This file is subject to the terms and conditions of the LGPL V2.1
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2018 Kalray Inc.
- */
- #include <sysdep.h>
- #define _ERRNO_H 1
- #include <bits/errno.h>
- /**
- * Clone system call implementation for kvx
- * int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg,
- * pid_t *ptid, struct user_desc *tls, pid_t *ctid);
- * $r0 = fn
- * $r1 = child_stack
- * $r2 = flags
- * $r3 = args
- * $r4 = ptid
- * $r5 = tls
- * $r6 = ctid
- *
- * The kernel expects to find its arguments in the following order:
- * sys_clone(unsigned long clone_flags, unsigned long newsp,
- * int __user * parent_tidptr,
- * int __user * child_tidptr,
- * unsigned long tls)
- *
- * So we have to make a few modifications before calling
- *
- */
- ENTRY (__clone)
- /* Check fn and stack to be non-null */
- cb.deqz $r1? L(clone_einval_error)
- /* Align child stack first */
- andd $r1 = $r1, -32
- ;;
- cb.deqz $r0? L(clone_einval_error)
- /* Prepare space for child arguments on stack and stay aligned */
- addd $r1 = $r1, -32
- ;;
- /* Save fn ($r0) on child stack */
- sd 0[$r1] = $r0
- /* Set clone_flags */
- copyd $r0 = $r2
- ;;
- /* Save args ($r3) on child stack */
- sd 8[$r1] = $r3
- /* Set parent_tidptr */
- copyd $r2 = $r4
- /* Set child_tidptr */
- copyd $r3 = $r6
- /* Set tls */
- copyd $r4 = $r5
- ;;
- scall SYS_ify(clone)
- ;;
- /* If 0, then we are the child */
- cb.deqz $r0? L(child_start)
- ;;
- /* Else we are the parent, and we need to check for errors */
- cb.dltz $r0? L(clone_error)
- ;;
- /* No error ! Yeepa ! */
- ret
- ;;
- L(child_start):
- /* get fn from stack */
- ld $r1 = 0[$sp]
- ;;
- /* Get args from stack */
- ld $r0 = 8[$sp]
- addd $sp = $sp, 32
- ;;
- icall $r1
- ;;
- scall SYS_ify(exit)
- ;;
- /* We should never ever get here ! */
- errop
- ;;
- L(clone_einval_error):
- make $r0 = -EINVAL
- ;;
- L(clone_error):
- /* goto __syscall_error but do not use call or $ra will be
- * destroyed */
- goto __syscall_error
- ;;
- /* We will not return here but to clone caller
- * (stored in $ra) */
- errop
- ;;
- END(__clone)
- libc_hidden_def (__clone)
- weak_alias (__clone,clone)
|