clone.S 2.1 KB

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