Commit 2153b2e8 authored by Ludwig Rydberg's avatar Ludwig Rydberg Committed by Andreas Larsson
Browse files

sparc: Add architecture support for clone3

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 value convention for clone3 follows the regular kernel return
value convention (in contrast to the original clone/fork on SPARC).

Closes: https://github.com/sparclinux/issues/issues/10


Signed-off-by: default avatarLudwig Rydberg <ludwig.rydberg@gaisler.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Reviewed-by: default avatarAndreas Larsson <andreas@gaisler.com>
Tested-by: default avatarAndreas Larsson <andreas@gaisler.com>
Tested-by: default avatarJohn Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Link: https://lore.kernel.org/r/20260119144753.27945-3-ludwig.rydberg@gaisler.com


Signed-off-by: default avatarAndreas Larsson <andreas@gaisler.com>
parent e38eba3b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);

#endif /* _SPARC64_SYSCALLS_H */
+0 −2
Original line number Diff line number Diff line
@@ -49,8 +49,6 @@
#define __ARCH_WANT_COMPAT_STAT
#endif

#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
+15 −0
Original line number Diff line number Diff line
@@ -907,6 +907,21 @@ flush_patch_four:
	jmpl	%l1 + %lo(sparc_vfork), %g0
	 add	%sp, STACKFRAME_SZ, %o0

	.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
+1 −0
Original line number Diff line number Diff line
@@ -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);

#ifdef CONFIG_SPARC64
/* setup_64.c */
+14 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/sched/task.h>
#include <linux/sched/task_stack.h>
#include <linux/signal.h>
#include <linux/syscalls.h>

#include "kernel.h"

@@ -118,3 +119,16 @@ asmlinkage long sparc_clone(struct pt_regs *regs)

	return ret;
}

asmlinkage long sparc_clone3(struct pt_regs *regs)
{
	unsigned long sz;
	struct clone_args __user *cl_args;

	synchronize_user_stack();

	cl_args = (struct clone_args __user *)regs->u_regs[UREG_I0];
	sz = regs->u_regs[UREG_I1];

	return sys_clone3(cl_args, sz);
}
Loading