Hi, Rich

I found the clone3_stack_valid() in latest kernel,  the condition of  (kargs->stack_size == 0) is still valid,

so the __clone() (within __NR_clone3 syscall ) is still fail.

we still implement __clone() within __NR_clone3 syscall in LoongArch ?


diff --git a/src/thread/loongarch64/clone.s b/src/thread/loongarch64/clone.s
new file mode 100644
index 00000000..86e69cfa
--- /dev/null
+++ b/src/thread/loongarch64/clone.s
@@ -0,0 +1,47 @@
+#__clone(func, stack, flags, arg, ptid, tls, ctid)
+#         a0,    a1,   a2,    a3,  a4,  a5,   a6
+# sys_clone3(struct clone_args *cl_args, size_t size)
+#                                 a0             a1
+
+.global    __clone
+.hidden __clone
+.type    __clone,@function
+__clone:
+    # Save function pointer and argument pointer on new thread stack
+    addi.d    $a1, $a1, -16
+    st.d    $a0, $a1, 0    # save function pointer
+    st.d    $a3, $a1, 8    # save argument pointer
+
+    li.d    $t0, ~0x004000ff  # mask CSIGNAL and CLONE_DETACHED
+    and    $t1, $a2, $t0     # cl_args.flags
+    li.d    $t0, 0x000000ff   # CSIGNAL
+    and    $t2, $a2, $t0     # cl_args.exit_signal
+
+    bstrins.d $sp, $zero, 3, 0  # align stack to 16 bytes
+    addi.d    $sp, $sp, -88   # struct clone_args
+    st.d    $t1, $sp, 0     # flags
+    st.d    $a4, $sp, 8     # pidfd
+    st.d    $a6, $sp, 16    # child_tid
+    st.d    $a4, $sp, 24    # parent_tid
+    st.d    $t2, $sp, 32    # exit_signal
+    st.d    $a1, $sp, 40    # stack
+    st.d    $zero, $sp, 48  # stack_size
+    st.d    $a5, $sp, 56    # tls
+    st.d    $zero, $sp, 64  # set_tid
+    st.d    $zero, $sp, 72  # set_tid_size
+    st.d    $zero, $sp, 80  # cgroup
+
+    move    $a0, $sp
+    li.d    $a1, 88
+    li.d    $a7, 435    # __NR_clone3
+    syscall 0        # call clone3
+
+    beqz    $a0, 1f        # whether child process
+    addi.d    $sp, $sp, 88
+    jr    $ra            # parent process return
+1:
+    ld.d    $t8, $sp, 0     # function pointer
+    ld.d    $a0, $sp, 8     # argument pointer
+    jirl    $ra, $t8, 0     # call the user's function
+    li.d    $a7, 93
+    syscall    0        # child process exit

Do we still want to implement clone functionality entirely with clone3, given the
previous conclusion of keeping clone(2) for existing sandboxes to continue to work?