arch-x86,sim-se: Add clone3 syscall

This also expands the syscall table for x86 to 450.

The clone3 version of the syscall puts the parameters in a struct. This
pulls out the parameters that gem5 uses and updates a couple of other
places with new flags and structs.

Reference:
https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_64.tbl

This is part of the reason for the failing Nightly tests:
https://jenkins.gem5.org/job/nightly/392/, triggered by updating the
tests to use Ubuntu 22.04

Change-Id: Ia934d54c391c6bd4f655bf65538d85371b6dbfb9
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64931
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh
index 7f71b5f..0c34d09 100644
--- a/src/arch/x86/linux/linux.hh
+++ b/src/arch/x86/linux/linux.hh
@@ -242,6 +242,21 @@
         uint64_t mem_unit;  /* Memory unit size in bytes */
     };
 
+    struct tgt_clone_args
+    {
+        uint64_t flags;
+        uint64_t pidfd;
+        uint64_t child_tid;
+        uint64_t parent_tid;
+        uint64_t exit_signal;
+        uint64_t stack;
+        uint64_t stack_size;
+        uint64_t tls;
+        uint64_t set_tid;
+        uint64_t set_tid_size;
+        uint64_t cgroup;
+    };
+
 };
 
 class X86Linux32 : public X86Linux, public OpenFlagTable<X86Linux32>
diff --git a/src/arch/x86/linux/syscall_tbl64.cc b/src/arch/x86/linux/syscall_tbl64.cc
index 1f5638d..1e7274c 100644
--- a/src/arch/x86/linux/syscall_tbl64.cc
+++ b/src/arch/x86/linux/syscall_tbl64.cc
@@ -377,7 +377,34 @@
     { 331, "pkey_free" },
     { 332, "statx" },
     { 333, "io_pgetevents" },
-    { 334, "rseq", ignoreFunc }
+    { 334, "rseq", ignoreFunc },
+    { 424, "pidfd_send_signal" },
+    { 425, "io_uring_setup" },
+    { 426, "io_uring_enter" },
+    { 427, "io_uring_register" },
+    { 428, "open_tree" },
+    { 429, "move_mount" },
+    { 430, "fsopen" },
+    { 431, "fsconfig" },
+    { 432, "fsmount" },
+    { 433, "fspick" },
+    { 434, "pidfd_open" },
+    { 435, "clone3", clone3Func<X86Linux64> },
+    { 436, "close_range" },
+    { 437, "openat2" },
+    { 438, "pidfd_getfd" },
+    { 439, "faccessat2" },
+    { 440, "process_madvise" },
+    { 441, "epoll_pwait2" },
+    { 442, "mount_setattr" },
+    { 443, "quotactl_fd" },
+    { 444, "landlock_create_ruleset" },
+    { 445, "landlock_add_rule" },
+    { 446, "landlock_restrict_self" },
+    { 447, "memfd_secret" },
+    { 448, "process_mrelease" },
+    { 449, "futex_waitv" },
+    { 450, "set_mempolicy_home_node" }
 };
 
 } // namespace X86ISA
diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh
index 73b0404..5b7a20f 100644
--- a/src/kern/linux/linux.hh
+++ b/src/kern/linux/linux.hh
@@ -309,6 +309,7 @@
     static const unsigned TGT_CLONE_FS              = 0x00000200;
     static const unsigned TGT_CLONE_FILES           = 0x00000400;
     static const unsigned TGT_CLONE_SIGHAND         = 0x00000800;
+    static const unsigned TGT_CLONE_PIDFD           = 0x00001000;
     static const unsigned TGT_CLONE_PTRACE          = 0x00002000;
     static const unsigned TGT_CLONE_VFORK           = 0x00004000;
     static const unsigned TGT_CLONE_PARENT          = 0x00008000;
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 1e04900..b4550dd 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -1601,9 +1601,12 @@
 
 template <class OS>
 SyscallReturn
-cloneFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack,
+doClone(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack,
           VPtr<> ptidPtr, VPtr<> ctidPtr, VPtr<> tlsPtr)
 {
+    DPRINTF(SyscallVerbose, "Doing clone. pid: %#llx, ctid: %#llx, tls: %#llx"
+                            " flags: %#llx, stack: %#llx\n",
+            ptidPtr.addr(), ctidPtr.addr(), tlsPtr.addr(), flags, newStack);
     auto p = tc->getProcessPtr();
 
     if (((flags & OS::TGT_CLONE_SIGHAND)&& !(flags & OS::TGT_CLONE_VM)) ||
@@ -1715,6 +1718,30 @@
 
 template <class OS>
 SyscallReturn
+clone3Func(SyscallDesc *desc, ThreadContext *tc,
+           VPtr<typename OS::tgt_clone_args> cl_args, RegVal size)
+{
+    VPtr<uint64_t> ptidPtr((Addr)cl_args->parent_tid, tc);
+    VPtr<uint64_t> ctidPtr((Addr)cl_args->child_tid, tc);
+    VPtr<uint64_t> tlsPtr((Addr)cl_args->tls, tc);
+    // Clone3 gives the stack as the *lowest* address, but clone/__clone2
+    // expects the stack parameter to be the actual stack pointer
+    uint64_t new_stack = cl_args->stack + cl_args->stack_size;
+    uint64_t flags = cl_args->flags;
+
+    return doClone<OS>(desc, tc, flags, new_stack, ptidPtr, ctidPtr, tlsPtr);
+}
+
+template <class OS>
+SyscallReturn
+cloneFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags, RegVal newStack,
+          VPtr<> ptidPtr, VPtr<> ctidPtr, VPtr<> tlsPtr)
+{
+    return doClone<OS>(desc, tc, flags, newStack, ptidPtr, ctidPtr, tlsPtr);
+}
+
+template <class OS>
+SyscallReturn
 cloneBackwardsFunc(SyscallDesc *desc, ThreadContext *tc, RegVal flags,
                    RegVal newStack, VPtr<> ptidPtr, VPtr<> tlsPtr,
                    VPtr<> ctidPtr)