From nobody Mon Feb 9 04:30:50 2026 Received: from smtp-out3.simply.com (smtp-out3.simply.com [94.231.106.210]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C5E833A03D; Fri, 16 Jan 2026 15:30:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=94.231.106.210 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768577462; cv=none; b=WWUL4ldfH92NPxwSwPXFwuvlxixnN3mavIRVpua8XI/8/qSgFPH38VazrWc1Ezn23nHGeaj2BuhILnNXe4ywDJcJTL9GBxIcNupXBtx2bQh20/pe3gmIhRWNbpXKHTjT7nHlxOuqA6gyatFVZOzr67VsRsMQxU0B2sOtEYt9kqw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768577462; c=relaxed/simple; bh=1/cJp3jdAnRxWvmnnysfcGjceKIDOlxgT5RX7NrIum0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IY8p39ONVblyvT6CYZXrg/3+3RuFN/7PjntAgZ37nkq2nkkMAVmMSQODcs4eNaqDxsu0qZeaqsS5kQNgq3N6kjc5nhsk5pFMl4smOXUSoihuzSU62hzGgPlLkJS7YYGxubmQRD/LoWVubvzKbc8j2aVSEblpFZ6bLt+S33bLZCI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gaisler.com; spf=pass smtp.mailfrom=gaisler.com; dkim=fail (0-bit key) header.d=gaisler.com header.i=@gaisler.com header.b=ZZ0Axy88 reason="key not found in DNS"; arc=none smtp.client-ip=94.231.106.210 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gaisler.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gaisler.com Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=gaisler.com header.i=@gaisler.com header.b="ZZ0Axy88" Received: from localhost (localhost [127.0.0.1]) by smtp.simply.com (Simply.com) with ESMTP id 4dt3hq62Cdz1DDRy; Fri, 16 Jan 2026 16:30:51 +0100 (CET) Received: from ludwig.got.gaisler.com (h-98-128-223-123.NA.cust.bahnhof.se [98.128.223.123]) by smtp.simply.com (Simply.com) with ESMTPA id 4dt3hq3P8Yz1FQVr; Fri, 16 Jan 2026 16:30:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gaisler.com; s=simplycom2; t=1768577451; bh=nBqBKlTx/0dURpHv7x+eHbZZ2AgnvEWZUZG5NBHn5zA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ZZ0Axy88HZsiouvbfnPkU+PJqBFwJzyD7eRN8z8pizFhYpxtqZlHcvzGSgcKKlMbs n0Q3YRYCJKE8Ij7eJzO55oj72Y1XcCMFe/6UGH789T7cYuCzUFZYAqsYsN2ON8S2jh k7wUWuip1AuFpYeK66FGZGOWnZiKtiTnqmF/Pgk4iYAswOT5rUIYNyT6npjlGoGZMM mIj7u1ZXjwZ4azzv2Mz/h22sbu71ZhSxs6pYl6zrY/kn3IDAPHhs9pScVWKacVm8dL vBggCJaVAO/iGxt55fo14WVgiF2S7bdxaNzIvBn3lpJPH/BM5gui5gy/Ns/uaV3ywc /CHjEtvoH+Idg== From: Ludwig Rydberg To: davem@davemloft.net, andreas@gaisler.com, brauner@kernel.org, shuah@kernel.org Cc: sparclinux@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, arnd@arndb.de, glaubitz@physik.fu-berlin.de, geert@linux-m68k.org, schuster.simon@siemens-energy.com, kernel@mkarcher.dialup.fu-berlin.de Subject: [PATCH 1/3] sparc: Synchronize user stack on fork and clone Date: Fri, 16 Jan 2026 16:30:49 +0100 Message-Id: <20260116153051.21678-2-ludwig.rydberg@gaisler.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20260116153051.21678-1-ludwig.rydberg@gaisler.com> References: <20260116153051.21678-1-ludwig.rydberg@gaisler.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Andreas Larsson Flush all uncommitted user windows before calling the generic syscall handlers for clone, fork, and vfork. Prior to entering the arch common handlers sparc_{clone|fork|vfork}, the arch-specific syscall wrappers for these syscalls will attempt to flush all windows (including user windows). In the window overflow trap handlers on both SPARC{32|64}, if the window can't be stored (i.e due to MMU related faults) the routine backups the user window and increments a thread counter (wsaved). By adding a synchronization point after the flush attempt, when fault handling is enabled, any uncommitted user windows will be flushed. Link: https://sourceware.org/bugzilla/show_bug.cgi?id=3D31394 Closes: https://lore.kernel.org/sparclinux/fe5cc47167430007560501aabb28ba15= 4985b661.camel@physik.fu-berlin.de/ Signed-off-by: Andreas Larsson Signed-off-by: Ludwig Rydberg Tested-by: John Paul Adrian Glaubitz --- arch/sparc/kernel/process.c | 38 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 0442ab00518d..7d69877511fa 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -17,14 +17,18 @@ =20 asmlinkage long sparc_fork(struct pt_regs *regs) { - unsigned long orig_i1 =3D regs->u_regs[UREG_I1]; + unsigned long orig_i1; long ret; struct kernel_clone_args args =3D { .exit_signal =3D SIGCHLD, - /* Reuse the parent's stack for the child. */ - .stack =3D regs->u_regs[UREG_FP], }; =20 + synchronize_user_stack(); + + orig_i1 =3D regs->u_regs[UREG_I1]; + /* Reuse the parent's stack for the child. */ + args.stack =3D regs->u_regs[UREG_FP]; + ret =3D kernel_clone(&args); =20 /* If we get an error and potentially restart the system @@ -40,16 +44,19 @@ asmlinkage long sparc_fork(struct pt_regs *regs) =20 asmlinkage long sparc_vfork(struct pt_regs *regs) { - unsigned long orig_i1 =3D regs->u_regs[UREG_I1]; + unsigned long orig_i1; long ret; - struct kernel_clone_args args =3D { .flags =3D CLONE_VFORK | CLONE_VM, .exit_signal =3D SIGCHLD, - /* Reuse the parent's stack for the child. */ - .stack =3D regs->u_regs[UREG_FP], }; =20 + synchronize_user_stack(); + + orig_i1 =3D regs->u_regs[UREG_I1]; + /* Reuse the parent's stack for the child. */ + args.stack =3D regs->u_regs[UREG_FP]; + ret =3D kernel_clone(&args); =20 /* If we get an error and potentially restart the system @@ -65,15 +72,18 @@ asmlinkage long sparc_vfork(struct pt_regs *regs) =20 asmlinkage long sparc_clone(struct pt_regs *regs) { - unsigned long orig_i1 =3D regs->u_regs[UREG_I1]; - unsigned int flags =3D lower_32_bits(regs->u_regs[UREG_I0]); + unsigned long orig_i1; + unsigned int flags; long ret; + struct kernel_clone_args args =3D {0}; =20 - struct kernel_clone_args args =3D { - .flags =3D (flags & ~CSIGNAL), - .exit_signal =3D (flags & CSIGNAL), - .tls =3D regs->u_regs[UREG_I3], - }; + synchronize_user_stack(); + + orig_i1 =3D regs->u_regs[UREG_I1]; + flags =3D lower_32_bits(regs->u_regs[UREG_I0]); + args.flags =3D (flags & ~CSIGNAL); + args.exit_signal =3D (flags & CSIGNAL); + args.tls =3D regs->u_regs[UREG_I3]; =20 #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { --=20 2.35.3 From nobody Mon Feb 9 04:30:50 2026 Received: from smtp-out3.simply.com (smtp-out3.simply.com [94.231.106.210]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5DA0833A03F; Fri, 16 Jan 2026 15:30:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=94.231.106.210 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768577461; cv=none; b=QA2ObTyIoTUh2tVHLTVSQfEesJfd1E3bUIb5Ed7TOg7udcZl1OfgUIXCN4+xtgftVwbBDNjJ2rhoRc8BumEySR0e4yHYXO3BrQuRg3VClQ+rUe09Bw5TVIVcpNa1zOMHp7e+ADuIven52umSNSnvtOPTCYlFByIlmDvkwm1k4KM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768577461; c=relaxed/simple; bh=IpZZ8A/8vRhXhWckaz1NwuJhiZ+fEaPg96F8nlsuS2g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oJ2d/hvx8/YLm/bT9AlFgCSZxZakFkTPJKDAL2MBj7/PyJ6GbQyHvRQiHOMLueCMc/Un1wSM/CRvGB25Kevzoel1pDsjB7TwagmA6IKeu2yqnqc2mIwGPmQ71Vcc4N3I3BRCJVNyAitTAO/jNheol7VW52MB3PfP/SVgB3SOMaQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gaisler.com; spf=pass smtp.mailfrom=gaisler.com; dkim=fail (0-bit key) header.d=gaisler.com header.i=@gaisler.com header.b=Qdj1nn/b reason="key not found in DNS"; arc=none smtp.client-ip=94.231.106.210 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gaisler.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gaisler.com Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=gaisler.com header.i=@gaisler.com header.b="Qdj1nn/b" Received: from localhost (localhost [127.0.0.1]) by smtp.simply.com (Simply.com) with ESMTP id 4dt3hr0nRHz1FQVr; Fri, 16 Jan 2026 16:30:52 +0100 (CET) Received: from ludwig.got.gaisler.com (h-98-128-223-123.NA.cust.bahnhof.se [98.128.223.123]) by smtp.simply.com (Simply.com) with ESMTPA id 4dt3hq5dslz1DDFM; Fri, 16 Jan 2026 16:30:51 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gaisler.com; s=simplycom2; t=1768577452; bh=4g2nxBOyYfkdzGSQ0inwR35X22JbYjY4qn7TdUVrjIU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Qdj1nn/b/Qi4pkVeDE3zMn/TjSMs/38o958jz6eojkiSlCGfLFeuCn9ql6XnzJ2SQ 9/89I6jOWkzv0igZaMK7bH8aruIToM4IOEMyRdcKYgmtO9UzVPEe2wf8HbIYpVAjkM 5fQRbuF0sGAYH6rzmzEFeZ3LGOC5WKLTM/HR20bnp0cpiyKx0P4+vN1UaVYKA6Cy/d sVHeEhv/RpgPPP+JnGKsuyWose8BguuRxBd4dVXJ6u4g3fr3icn1l82nIzT0Bx7Iom KHSXs0yDzYdIwHDegvFo2NcTQRNqOg6cw8L+jyP8y0LpxzYVFVPMzqCAssRYrk7lBL SCer2MFSJa7oQ== From: Ludwig Rydberg To: davem@davemloft.net, andreas@gaisler.com, brauner@kernel.org, shuah@kernel.org Cc: sparclinux@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, arnd@arndb.de, glaubitz@physik.fu-berlin.de, geert@linux-m68k.org, schuster.simon@siemens-energy.com Subject: [PATCH 2/3] sparc: Add architecture support for clone3 Date: Fri, 16 Jan 2026 16:30:50 +0100 Message-Id: <20260116153051.21678-3-ludwig.rydberg@gaisler.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20260116153051.21678-1-ludwig.rydberg@gaisler.com> References: <20260116153051.21678-1-ludwig.rydberg@gaisler.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for the clone3 system call to the SPARC architectures. The implementation follows the pattern of the original clone syscall. However, instead of explicitly calling kernel_clone, the clone3 handler calls the generic sys_clone3 handler in kernel/fork. In case no stack is provided, the parents stack is reused. The return call conventions for clone on SPARC are kept for clone3: Parent --> %o0 =3D=3D child's pid, %o1 =3D=3D 0 Child --> %o0 =3D=3D parent's pid, %o1 =3D=3D 1 Closes: https://github.com/sparclinux/issues/issues/10 Signed-off-by: Ludwig Rydberg Tested-by: John Paul Adrian Glaubitz --- arch/sparc/include/asm/syscalls.h | 1 + arch/sparc/include/asm/unistd.h | 2 -- arch/sparc/kernel/entry.S | 15 +++++++++++++++ arch/sparc/kernel/kernel.h | 1 + arch/sparc/kernel/process.c | 25 +++++++++++++++++++++++++ arch/sparc/kernel/process_32.c | 2 +- arch/sparc/kernel/process_64.c | 2 +- arch/sparc/kernel/syscalls.S | 6 ++++++ arch/sparc/kernel/syscalls/syscall.tbl | 2 +- 9 files changed, 51 insertions(+), 5 deletions(-) diff --git a/arch/sparc/include/asm/syscalls.h b/arch/sparc/include/asm/sys= calls.h index 35575fbfb9dc..282e62b66518 100644 --- a/arch/sparc/include/asm/syscalls.h +++ b/arch/sparc/include/asm/syscalls.h @@ -7,5 +7,6 @@ struct pt_regs; asmlinkage long sparc_fork(struct pt_regs *regs); asmlinkage long sparc_vfork(struct pt_regs *regs); asmlinkage long sparc_clone(struct pt_regs *regs); +asmlinkage long sparc_clone3(struct pt_regs *regs); =20 #endif /* _SPARC64_SYSCALLS_H */ diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unist= d.h index 3380411a4537..d6bc76706a7a 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h @@ -49,8 +49,6 @@ #define __ARCH_WANT_COMPAT_STAT #endif =20 -#define __ARCH_BROKEN_SYS_CLONE3 - #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, * it never had the plain ones and there is no value to adding those diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index a3fdee4cd6fa..ea51ef52c952 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -907,6 +907,21 @@ flush_patch_four: jmpl %l1 + %lo(sparc_vfork), %g0 add %sp, STACKFRAME_SZ, %o0 =20 + .globl __sys_clone3, flush_patch_five +__sys_clone3: + mov %o7, %l5 +flush_patch_five: + FLUSH_ALL_KERNEL_WINDOWS; + ld [%curptr + TI_TASK], %o4 + rd %psr, %g4 + WRITE_PAUSE + rd %wim, %g5 + WRITE_PAUSE + std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr] + add %sp, STACKFRAME_SZ, %o0 + call sparc_clone3 + mov %l5, %o7 + .align 4 linux_sparc_ni_syscall: sethi %hi(sys_ni_syscall), %l7 diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 8328a3b78a44..4ee85051521a 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -18,6 +18,7 @@ extern int ncpus_probed; asmlinkage long sparc_clone(struct pt_regs *regs); asmlinkage long sparc_fork(struct pt_regs *regs); asmlinkage long sparc_vfork(struct pt_regs *regs); +asmlinkage long sparc_clone3(struct pt_regs *regs); =20 #ifdef CONFIG_SPARC64 /* setup_64.c */ diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 7d69877511fa..b8e23295db69 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -12,6 +12,7 @@ #include #include #include +#include =20 #include "kernel.h" =20 @@ -118,3 +119,27 @@ asmlinkage long sparc_clone(struct pt_regs *regs) =20 return ret; } + +asmlinkage long sparc_clone3(struct pt_regs *regs) +{ + unsigned long sz; + long ret; + struct clone_args __user *cl_args; + + synchronize_user_stack(); + + cl_args =3D (struct clone_args __user *)regs->u_regs[UREG_I0]; + sz =3D regs->u_regs[UREG_I1]; + + ret =3D sys_clone3(cl_args, sz); + + /* If we get an error and potentially restart the system + * call, we're screwed because copy_thread() clobbered + * the parent's %o1. So detect that case and restore it + * here. + */ + if ((unsigned long)ret >=3D -ERESTART_RESTARTBLOCK) + regs->u_regs[UREG_I1] =3D sz; + + return ret; +} diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 5a28c0e91bf1..216c07971c81 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -261,11 +261,11 @@ extern void ret_from_kernel_thread(void); int copy_thread(struct task_struct *p, const struct kernel_clone_args *arg= s) { u64 clone_flags =3D args->flags; - unsigned long sp =3D args->stack; unsigned long tls =3D args->tls; struct thread_info *ti =3D task_thread_info(p); struct pt_regs *childregs, *regs =3D current_pt_regs(); char *new_stack; + unsigned long sp =3D args->stack ? args->stack : regs->u_regs[UREG_FP]; =20 #ifndef CONFIG_SMP if(last_task_used_math =3D=3D current) { diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 25781923788a..885d617ba29d 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -568,13 +568,13 @@ void fault_in_user_windows(struct pt_regs *regs) int copy_thread(struct task_struct *p, const struct kernel_clone_args *arg= s) { u64 clone_flags =3D args->flags; - unsigned long sp =3D args->stack; unsigned long tls =3D args->tls; struct thread_info *t =3D task_thread_info(p); struct pt_regs *regs =3D current_pt_regs(); struct sparc_stackf *parent_sf; unsigned long child_stack_sz; char *child_trap_frame; + unsigned long sp =3D args->stack ? args->stack : regs->u_regs[UREG_FP]; =20 /* Calculate offset to stack_frame & pt_regs */ child_stack_sz =3D (STACKFRAME_SZ + TRACEREG_SZ); diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 0e8ab0602c36..c8d374a37f98 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -103,6 +103,12 @@ sys_clone: ba,pt %xcc, sparc_clone add %sp, PTREGS_OFF, %o0 =20 + .align 32 +__sys_clone3: + flushw + ba,pt %xcc, sparc_clone3 + add %sp, PTREGS_OFF, %o0 + .globl ret_from_fork ret_from_fork: /* Clear current_thread_info()->new_child. */ diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/sys= calls/syscall.tbl index 39aa26b6a50b..c0307bb09892 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -480,7 +480,7 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open -# 435 reserved for clone3 +435 common clone3 __sys_clone3 436 common close_range sys_close_range 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd --=20 2.35.3 From nobody Mon Feb 9 04:30:50 2026 Received: from smtp-out3.simply.com (smtp-out3.simply.com [94.231.106.210]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5DAE733A6E7; Fri, 16 Jan 2026 15:30:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=94.231.106.210 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768577461; cv=none; b=MaxauZ9uql6A7obtGdTrbQ3S0+0eXNTIchwC5hwWZVFQwC9kUca67228Ug0dUXGwx3vkLXIVB73RVsbaWOp0UrLJKvtEuTkGam7q4sejhimW+xh7V+i4+BF/rxIs4l0L8lNpzc+Jdj5uG4/PFkYn+fKJ8xUbxLmN9FVFWS5sizs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768577461; c=relaxed/simple; bh=IcFthlrYeG+gbqvQankeIfNvmjsw7u81x1q7iHNerrI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZqbQhpM0TrX3nph+eB9PxkzYurVCagxUcDb42mFNma80kYN6wHR6UTix/YhX0iDsf4+52BybcFVPZtXnEuwdb9BcixSGnD8+BJT39tS2vUvc34pUNVhMJYcfpNyjNt2gNd2YbejoC+c9EH+zeWwKmoWIYQi84monsaIwStIiUZ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gaisler.com; spf=pass smtp.mailfrom=gaisler.com; dkim=fail (0-bit key) header.d=gaisler.com header.i=@gaisler.com header.b=L/t8fIRh reason="key not found in DNS"; arc=none smtp.client-ip=94.231.106.210 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gaisler.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gaisler.com Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=gaisler.com header.i=@gaisler.com header.b="L/t8fIRh" Received: from localhost (localhost [127.0.0.1]) by smtp.simply.com (Simply.com) with ESMTP id 4dt3hr2rmyz1Ffyx; Fri, 16 Jan 2026 16:30:52 +0100 (CET) Received: from ludwig.got.gaisler.com (h-98-128-223-123.NA.cust.bahnhof.se [98.128.223.123]) by smtp.simply.com (Simply.com) with ESMTPA id 4dt3hr0bSDz1DDTf; Fri, 16 Jan 2026 16:30:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gaisler.com; s=simplycom2; t=1768577452; bh=UnM2tQCR8mePF9ZCNVMq6/NyT3NCkF9jVAMSCvcGixI=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=L/t8fIRhdcXjLpV8y7LaSBkgpV+Xc0SJS8l7sihF7E+E/qaI1RHdG1uHNKdyrCMgq 4r9XZ1eejyiYajX60hapaqrbP/1B7u3Wpfeu6IvJG+1R9m58P0nD2hpd563+MMLcEI 06xCEGLCGNpsPApLy2oDATkdTbLdr7t0Exo023pLXesXjurRIEnU6idrXwJiCfR5LM IQ+HTLsCrHAJW3BXfuXjs3o/VnCWDFawvcTWtQZH487rFHBF/jkN6q3vUL4ImKlgNK MhCq5SOIX0d+H8cFJOFOeRGqN5VvbuQR+txGl093CBsBtU+yaHOXfjNYjHxHicflRy 71DDSvhMG1oFA== From: Ludwig Rydberg To: davem@davemloft.net, andreas@gaisler.com, brauner@kernel.org, shuah@kernel.org Cc: sparclinux@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, arnd@arndb.de, glaubitz@physik.fu-berlin.de, geert@linux-m68k.org, schuster.simon@siemens-energy.com Subject: [PATCH 3/3] selftests/clone3: Add sys_clone3 wrapper for SPARC Date: Fri, 16 Jan 2026 16:30:51 +0100 Message-Id: <20260116153051.21678-4-ludwig.rydberg@gaisler.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20260116153051.21678-1-ludwig.rydberg@gaisler.com> References: <20260116153051.21678-1-ludwig.rydberg@gaisler.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a sys_clone3 wrapper (based on the INLINE_CLONE_SYSCALL macro in glibc) for SPARC to handle its unique return call convention. The needed handling is described in arch/sparc/kernel/process_{32|64}.c: Parent --> %o0 =3D=3D child's pid, %o1 =3D=3D 0 Child --> %o0 =3D=3D parent's pid, %o1 =3D=3D 1 Signed-off-by: Ludwig Rydberg Tested-by: John Paul Adrian Glaubitz --- .../selftests/clone3/clone3_selftests.h | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/tools/testing/selftests/clone3/clone3_selftests.h b/tools/test= ing/selftests/clone3/clone3_selftests.h index a0593e8950f0..5fa33294227d 100644 --- a/tools/testing/selftests/clone3/clone3_selftests.h +++ b/tools/testing/selftests/clone3/clone3_selftests.h @@ -33,12 +33,87 @@ struct __clone_args { __aligned_u64 cgroup; }; =20 +#if defined(__sparc__) +#include + +#if defined(__arch64__) +#define __SYSCALL_STRING \ + "mov %[scn], %%g1;" \ + "ta 0x6d;" \ + "bcc,pt %%xcc, 1f;" \ + " nop;" \ + "sub %%g0, %%o0, %%o0;" \ + "1:" + +#define __SYSCALL_CLOBBERS \ + "g1", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \ + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \ + "cc", "memory" +#else +#define __SYSCALL_STRING \ + "mov %[scn], %%g1;" \ + "ta 0x10;" \ + "bcc 1f;" \ + " nop;" \ + "sub %%g0, %%o0, %%o0;" \ + "1:" + +#define __SYSCALL_CLOBBERS \ + "g1", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ + "cc", "memory" +#endif + +/* A special wrapper is required to handle the return call convention + * on SPARC and is based on the INLINE_CLONE_SYSCALL macro in glibc. + * + * Parent --> %o0 =3D=3D child's pid, %o1 =3D=3D 0 + * Child --> %o0 =3D=3D parent's pid, %o1 =3D=3D 1 + */ +static inline pid_t sparc_clone3(struct __clone_args *args, size_t size) +{ + long _cl_args =3D (long) (args); + long _size =3D (long) (size); + long _scn =3D __NR_clone3; + + register long o0 __asm__ ("o0") =3D _cl_args; + register long o1 __asm__ ("o1") =3D _size; + + asm volatile (__SYSCALL_STRING + : "=3Dr" (o0), "=3Dr" (o1) + : [scn] "r" (_scn), "0" (o0), "1" (o1) + : __SYSCALL_CLOBBERS); + + if ((unsigned long) (o0) > -4096UL) { + errno =3D -o0; + o0 =3D -1L; + } else { + o0 &=3D (o1 - 1); + } + + return o0; +} + +static pid_t sys_clone3(struct __clone_args *args, size_t size) +{ + fflush(stdout); + fflush(stderr); + return sparc_clone3(args, size); +} +#else static pid_t sys_clone3(struct __clone_args *args, size_t size) { fflush(stdout); fflush(stderr); return syscall(__NR_clone3, args, size); } +#endif =20 static inline void test_clone3_supported(void) { --=20 2.35.3