Hi all,
This series adds support for the clone3 system call to the SPARC{32|64}
architectures and also adds a related patch for clone/fork/vfork that fix an
issue previously reported[1] that could result in -EFAULT for no good reason.
Without this patch, the clone3 system call would need the same mitigation as
introduced in glibc[2] for the clone system call.
About "sparc: Synchronize user stack on fork and clone"
---------------------------------------------------------
The clone3 implementation is developed on top of a fix for an issue reported
by Adrian Glaubitz[1], where a clone call could return -EFAULT. This problem
has since been mitigated in glibc[2] by synchronizing the user stack before
calling clone.
The root cause analysis of the kernel side when running the program in [1]
shows that the window spill handler routine on both SPARC{32|64} is unable to
flush a user window to the stack (due to MMU related faults) when flushing all
windows before handling the syscall. This then results in a -EFAULT when
copy_thread() fails to clone the uncommited stackframe of the parent.
For SPARC32:
Prior to calling the syscall wrappers for clone/fork/vork all windows are
flushed by a macro (FLUSH_ALL_KERNEL_WINDOWS).
In the window spill trap handler, MMU fault-handling is temporarily
disabled while storing the window. If the window can't be stored
(which normally would have triggered a fault trap) the routine
backups the user window and increments a thread counter (wsaved).
For SPARC64:
Prior to calling the syscall wrappers for clone/fork/vork all windows are
flushed by issuing the flushw instruction.
In the window spill trap handler, if an exception triggers, then the user
window is added to the thread's user window buffer (in kernel memory) and
a thread counter (wsaved) counter is incremented.
Both SPARC{32|64}:
Eventually copy_thread will be called, which then will fail to clone the parent
stackframe to the child as the user window has not been flushed to the stack.
Fixed by adding a call to synchronize_user_stack() prior to calling
kernel_clone(). The patch has been tested both with and without the mitigation
in glibc by running the program mentioned in [1].
SPARC32:
- Tested in QEMU emulating sun4m using Buildroot 2025.02
(qemu_sparc_ss10_defconfig).
- Tested on LEON using a GR-CPCI-GR740 development board from
Frontgrade Gaisler.
SPARC64:
- Tested in QEMU emulating sun4u using Buildroot 2025.02
(qemu_sparc64_sun4u_defconfig).
About the clone3 implementation:
--------------------------------
The implementation in the architectural port follows the same pattern as for the
original clone syscall. But instead of explicitly calling kernel_clone (as in
sparc_clone) the clone3 handler calls the generic sys_clone3 handler
(in kernel/fork). To get this to work without a user provided stack,
the copy_thread functions had to be updated to handle cl_args.stack == NULL.
In this case the stack of the parent is re-used.
When applying the patch series on top of v6.19-rc1 the relevant clone3 tests of
kselftest pass:
# /usr/lib/kselftests/run_kselftest.sh -c clone3 -s
kselftest: Running tests in clone3
TAP version 13
1..4
# selftests: clone3: clone3
ok 1 selftests: clone3: clone3
# selftests: clone3: clone3_clear_sighand
ok 2 selftests: clone3: clone3_clear_sighand
# selftests: clone3: clone3_set_tid
ok 3 selftests: clone3: clone3_set_tid
# selftests: clone3: clone3_cap_checkpoint_restore
ok 4 selftests: clone3: clone3_cap_checkpoint_restore
Note that the clone3_cap_checkpoint test failed in the same way as mentioned in
[3] (due to incompatibility with the libcap version on my system).
When applying the patch from [4] or by downgrading libcap to 2.59 the test pass.
SPARC32:
- Tested in QEMU emulating sun4m using Buildroot 2025.02
(qemu_sparc_ss10_defconfig).
- Tested on LEON using a GR-CPCI-GR740 development board from
Frontgrade Gaisler.
SPARC64:
- Tested in QEMU emulating sun4u using Buildroot 2025.02
(qemu_sparc64_sun4u_defconfig).
- Tested on UltraSparc T4
[1]:
https://lore.kernel.org/sparclinux/3ae4130c-c5aa-428e-b819-44cf2daf2...@mkarcher.dialup.fu-berlin.de/
[2]: https://sourceware.org/bugzilla/show_bug.cgi?id=31394
[3]:
https://lore.kernel.org/all/20250901-nios2-implement-clone3-v2-0-53fcf5577...@siemens-energy.com/
[4]:
https://lore.kernel.org/all/[email protected]/
Andreas Larsson (1):
sparc: Synchronize user stack on fork and clone
Ludwig Rydberg (2):
sparc: Add architecture support for clone3
selftests/clone3: Add sys_clone3 wrapper for SPARC
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 | 63 ++++++++++++----
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 +-
.../selftests/clone3/clone3_selftests.h | 75 +++++++++++++++++++
10 files changed, 150 insertions(+), 19 deletions(-)
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
--
2.35.3