[PATCH v2 00/14] powerpc: Syscall wrapper and register clearing
Rohan McLure
rmclure at linux.ibm.com
Mon Jul 25 16:20:25 AEST 2022
V1 available here:
Link: https://lore.kernel.org/all/20220601054850.250287-1-rmclure@linux.ibm.com/
Implement a syscall wrapper, causing arguments to handlers to be passed
via a struct pt_regs on the stack. The syscall wrapper is implemented
for all platforms other than the Cell processor, from which SPUs expect
the ability to directly call syscall handler symbols with the regular
in-register calling convention.
Adopting syscall wrappers requires redefinition of architecture-specific
syscalls and compatibility syscalls to use the SYSCALL_DEFINE and
COMPAT_SYSCALL_DEFINE macros, as well as removal of direct-references to
the emitted syscall-handler symbols from within the kernel. This work
lead to the following modernisations of powerpc's syscall handlers:
- Replace syscall 82 semantics with sys_old_select and remove
ppc_select handler, which features direct call to both sys_old_select
and sys_select.
- Use a generic fallocate compatibility syscall
Replace asm implementation of syscall table with C implementation for
more compile-time checks.
Many compatibility syscalls are candidates to be removed in favour of
generically defined handlers, but exhibit different parameter orderings
and numberings due to 32-bit ABI support for 64-bit parameters. The
paramater reorderings are however consistent with arm. A future patch
series will serve to modernise syscalls by providing generic
implementations featuring these reorderings.
The design of this syscall is very similar to the s390, x86 and arm64
implementations. See also Commit 4378a7d4be30 (arm64: implement syscall wrappers).
The motivation for this change is that it allows for the clearing of
register state when entering the kernel via through interrupt handlers
on 64-bit servers. This serves to reduce the influence of values in
registers carried over from the interrupted process, e.g. syscall
parameters from user space, or user state at the site of a pagefault.
All values in registers are saved and nullified (assigned to zero) at
the entry to an interrupt handler and restored afterward. While this may
sound like a heavy-weight mitigation, many gprs are already saved and
restored on handling of an interrupt, and the mmap_bench benchmark on
Power 9 guest, repeatedly invoking the pagefault handler suggests at most
~0.8% regression in performance. Realistic workloads are not constantly
producing interrupts, and so this does not indicate realistic slowdown.
Using wrapped syscalls yields to a performance improvement of ~5.6% on
the null_syscall benchmark on pseries guests, by removing the need for
system_call_exception to allocate its own stack frame. This amortises
the additional costs of saving and restoring non-volatile registers
(register clearing is cheap on super scalar platforms), and so the
final mitigation actually yields a net performance improvement of ~0.6%
on the null_syscall benchmark.
Patch Changelog:
- Explicitly specify that register saving/clearing/restoring effects
only 64bit server platforms (Book 3s/64s)
- Wrap all syscall definitions in one of SYSCALL_DEFINE or
COMPAT_SYSCALL_DEFINE
- Emit prototypes for wrapped syscall handlers
- Convert systbl.S to a C file
- Use generic implementation of fallocate compatibility syscall
- Assign generic old_select semantics to syscall #82
- Move ppc32.h header to include/asm/
- Include benchmark results for both DSI and null syscalls
Rohan McLure (14):
powerpc: Adopt SYSCALL_DEFINE for arch-specific syscall handlers
powerpc: Remove direct call to personality syscall handler
powerpc: Remove direct call to mmap2 syscall handlers
powerpc/32: Remove powerpc select specialisation
powerpc: Use generic fallocate compatibility syscall
powerpc: Include all arch-specific syscall prototypes
powerpc: Enable compile-time check for syscall handlers
powerpc: Use common syscall handler type
powerpc: Add NULLIFY_GPRS macros for register clears
powerpc: Provide syscall wrapper
powerpc/64s: Clear/restore caller gprs in syscall interrupt/return
powerpc/64s: Use {NULLIFY,SAVE,REST}_GPRS macros in sc, scv 0 handlers
powerpc/64s: Fix comment on interrupt handler prologue
powerpc/64s: Clear gprs on interrupt routine entry
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/compat.h | 5 +
arch/powerpc/include/asm/interrupt.h | 3 +-
arch/powerpc/{kernel => include/asm}/ppc32.h | 0
arch/powerpc/include/asm/ppc_asm.h | 22 +++
arch/powerpc/include/asm/syscall.h | 11 +-
arch/powerpc/include/asm/syscall_wrapper.h | 94 ++++++++++++
arch/powerpc/include/asm/syscalls.h | 128 +++++++++++++----
arch/powerpc/include/asm/unistd.h | 1 +
arch/powerpc/kernel/asm-offsets.c | 1 +
arch/powerpc/kernel/entry_32.S | 6 +-
arch/powerpc/kernel/exceptions-64s.S | 23 ++-
arch/powerpc/kernel/interrupt.c | 33 ++---
arch/powerpc/kernel/interrupt_64.S | 90 +++++-------
arch/powerpc/kernel/signal_32.c | 2 +-
arch/powerpc/kernel/sys_ppc32.c | 54 ++++---
arch/powerpc/kernel/syscalls.c | 50 ++++---
arch/powerpc/kernel/syscalls/syscall.tbl | 24 ++--
arch/powerpc/kernel/{systbl.S => systbl.c} | 29 ++--
arch/powerpc/kernel/vdso.c | 6 +-
arch/powerpc/perf/callchain_32.c | 2 +-
arch/powerpc/platforms/cell/spu_callbacks.c | 8 +-
tools/perf/arch/powerpc/entry/syscalls/syscall.tbl | 24 ++--
23 files changed, 397 insertions(+), 220 deletions(-)
rename arch/powerpc/{kernel => include/asm}/ppc32.h (100%)
create mode 100644 arch/powerpc/include/asm/syscall_wrapper.h
rename arch/powerpc/kernel/{systbl.S => systbl.c} (55%)
--
2.34.1
More information about the Linuxppc-dev
mailing list