mbox series

[00/23] powerpc: Syscall wrapper and register clearing

Message ID 20220916053300.786330-1-rmclure@linux.ibm.com (mailing list archive)
Headers show
Series powerpc: Syscall wrapper and register clearing | expand

Message

Rohan McLure Sept. 16, 2022, 5:32 a.m. UTC
V4 available here:

Link: https://lore.kernel.org/all/20220824020548.62625-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
parameter 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 zeroized 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.

The clearing of general purpose registers on interrupts other than
syscalls is enabled by default only on Book3E 64-bit systems (where the
mitigation is inexpensive), but available to other 64-bit systems via
the INTERRUPT_SANITIZE_REGISTERS Kconfig option. This mitigation is
optional, as the speculation influence of interrupts is likely less than
that of syscalls.

Patch Changelog:

 - Format orig_r3 handling as its own patch rather than just a revert.
 - Provide asm-generic BE implementation of long-long munging syscall
   compatiblity arguments.
 - Syscall #82 now refers to generic sys_old_select or
   comptat_sys_old_select.
 - Drop 'inline' on static helper functions for mmap, personality.
 - Remove arch-specific sys fallocate implementation that was meant to
   have been removed in V2.
 - Remove references to syscall wrapper until it is introduced.
 - Rearrange patch series so the last five patches are syscall wrapper >
   syscall register clears > interrupt register clears.
 - Whether non-syscall interrupts should clear registers is now
   configurable by INTERRUPT_SANITIZE_REGISTERS.

Rohan McLure (23):
  powerpc: Remove asmlinkage from syscall handler definitions
  powerpc: Save caller r3 prior to system_call_exception
  powerpc: Add ZEROIZE_GPRS macros for register clears
  powerpc/64s: Use {ZEROIZE,SAVE,REST}_GPRS macros in sc, scv 0 handlers
  powerpc/32: Clarify interrupt restores with REST_GPR macro in
    entry_32.S
  powerpc/64e: Clarify register saves and clears with
    {SAVE,ZEROIZE}_GPRS
  powerpc/64s: Fix comment on interrupt handler prologue
  powerpc: Fix fallocate and fadvise64_64 compat parameter combination
  asm-generic: compat: Support BE for long long args in 32-bit ABIs
  powerpc: Use generic fallocate compatibility syscall
  powerpc/32: Remove powerpc select specialisation
  powerpc: Remove direct call to personality syscall handler
  powerpc: Remove direct call to mmap2 syscall handlers
  powerpc: Provide do_ppc64_personality helper
  powerpc: Adopt SYSCALL_DEFINE for arch-specific syscall handlers
  powerpc: Include all arch-specific syscall prototypes
  powerpc: Enable compile-time check for syscall handlers
  powerpc: Use common syscall handler type
  powerpc: Provide syscall wrapper
  powerpc/64s: Clear/restore caller gprs in syscall interrupt/return
  powerpc/64: Add INTERRUPT_SANITIZE_REGISTERS Kconfig
  powerpc/64s: Clear gprs on interrupt routine entry in Book3S
  powerpc/64e: Clear gprs on interrupt routine entry on Book3E

 arch/powerpc/Kconfig                         |  10 ++
 arch/powerpc/include/asm/interrupt.h         |   3 +-
 arch/powerpc/include/asm/ppc_asm.h           |  22 +++
 arch/powerpc/include/asm/syscall.h           |  11 +-
 arch/powerpc/include/asm/syscall_wrapper.h   |  84 ++++++++++
 arch/powerpc/include/asm/syscalls.h          | 148 +++++++++++++----
 .../ppc32.h => include/asm/syscalls_32.h}    |   0
 arch/powerpc/include/asm/unistd.h            |   1 +
 arch/powerpc/kernel/entry_32.S               |  40 ++---
 arch/powerpc/kernel/exceptions-64e.S         |  35 ++--
 arch/powerpc/kernel/exceptions-64s.S         |  41 ++++-
 arch/powerpc/kernel/interrupt_64.S           |  92 +++++-----
 arch/powerpc/kernel/signal_32.c              |   2 +-
 arch/powerpc/kernel/sys_ppc32.c              |  66 +++-----
 arch/powerpc/kernel/syscall.c                |  32 ++--
 arch/powerpc/kernel/syscalls.c               |  61 ++++---
 arch/powerpc/kernel/syscalls/syscall.tbl     |  24 +--
 arch/powerpc/kernel/{systbl.S => systbl.c}   |  30 ++--
 arch/powerpc/kernel/vdso.c                   |   6 +-
 arch/powerpc/perf/callchain_32.c             |   2 +-
 arch/powerpc/platforms/cell/spu_callbacks.c  |   6 +-
 include/asm-generic/compat.h                 |   9 +-
 .../arch/powerpc/entry/syscalls/syscall.tbl  |  24 +--
 23 files changed, 491 insertions(+), 258 deletions(-)
 create mode 100644 arch/powerpc/include/asm/syscall_wrapper.h
 rename arch/powerpc/{kernel/ppc32.h => include/asm/syscalls_32.h} (100%)
 rename arch/powerpc/kernel/{systbl.S => systbl.c} (55%)

Comments

Rohan McLure Sept. 16, 2022, 5:58 a.m. UTC | #1
> On 16 Sep 2022, at 3:32 pm, Rohan McLure <rmclure@linux.ibm.com> wrote:
> 
> V4 available here:
> 
> Link: https://lore.kernel.org/all/20220824020548.62625-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
> parameter 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 zeroized 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.
> 
> The clearing of general purpose registers on interrupts other than
> syscalls is enabled by default only on Book3E 64-bit systems (where the
> mitigation is inexpensive), but available to other 64-bit systems via
> the INTERRUPT_SANITIZE_REGISTERS Kconfig option. This mitigation is
> optional, as the speculation influence of interrupts is likely less than
> that of syscalls.
> 
> Patch Changelog:
> 
> - Format orig_r3 handling as its own patch rather than just a revert.
> - Provide asm-generic BE implementation of long-long munging syscall
>   compatiblity arguments.
> - Syscall #82 now refers to generic sys_old_select or
>   comptat_sys_old_select.
> - Drop 'inline' on static helper functions for mmap, personality.
> - Remove arch-specific sys fallocate implementation that was meant to
>   have been removed in V2.
> - Remove references to syscall wrapper until it is introduced.
> - Rearrange patch series so the last five patches are syscall wrapper >
>   syscall register clears > interrupt register clears.
> - Whether non-syscall interrupts should clear registers is now
>   configurable by INTERRUPT_SANITIZE_REGISTERS.
> 
> Rohan McLure (23):
>  powerpc: Remove asmlinkage from syscall handler definitions
>  powerpc: Save caller r3 prior to system_call_exception
>  powerpc: Add ZEROIZE_GPRS macros for register clears
>  powerpc/64s: Use {ZEROIZE,SAVE,REST}_GPRS macros in sc, scv 0 handlers
>  powerpc/32: Clarify interrupt restores with REST_GPR macro in
>    entry_32.S
>  powerpc/64e: Clarify register saves and clears with
>    {SAVE,ZEROIZE}_GPRS
>  powerpc/64s: Fix comment on interrupt handler prologue
>  powerpc: Fix fallocate and fadvise64_64 compat parameter combination
>  asm-generic: compat: Support BE for long long args in 32-bit ABIs
>  powerpc: Use generic fallocate compatibility syscall
>  powerpc/32: Remove powerpc select specialisation
>  powerpc: Remove direct call to personality syscall handler
>  powerpc: Remove direct call to mmap2 syscall handlers
>  powerpc: Provide do_ppc64_personality helper
>  powerpc: Adopt SYSCALL_DEFINE for arch-specific syscall handlers
>  powerpc: Include all arch-specific syscall prototypes
>  powerpc: Enable compile-time check for syscall handlers
>  powerpc: Use common syscall handler type
>  powerpc: Provide syscall wrapper
>  powerpc/64s: Clear/restore caller gprs in syscall interrupt/return
>  powerpc/64: Add INTERRUPT_SANITIZE_REGISTERS Kconfig
>  powerpc/64s: Clear gprs on interrupt routine entry in Book3S
>  powerpc/64e: Clear gprs on interrupt routine entry on Book3E
> 
> arch/powerpc/Kconfig                         |  10 ++
> arch/powerpc/include/asm/interrupt.h         |   3 +-
> arch/powerpc/include/asm/ppc_asm.h           |  22 +++
> arch/powerpc/include/asm/syscall.h           |  11 +-
> arch/powerpc/include/asm/syscall_wrapper.h   |  84 ++++++++++
> arch/powerpc/include/asm/syscalls.h          | 148 +++++++++++++----
> .../ppc32.h => include/asm/syscalls_32.h}    |   0
> arch/powerpc/include/asm/unistd.h            |   1 +
> arch/powerpc/kernel/entry_32.S               |  40 ++---
> arch/powerpc/kernel/exceptions-64e.S         |  35 ++--
> arch/powerpc/kernel/exceptions-64s.S         |  41 ++++-
> arch/powerpc/kernel/interrupt_64.S           |  92 +++++-----
> arch/powerpc/kernel/signal_32.c              |   2 +-
> arch/powerpc/kernel/sys_ppc32.c              |  66 +++-----
> arch/powerpc/kernel/syscall.c                |  32 ++--
> arch/powerpc/kernel/syscalls.c               |  61 ++++---
> arch/powerpc/kernel/syscalls/syscall.tbl     |  24 +--
> arch/powerpc/kernel/{systbl.S => systbl.c}   |  30 ++--
> arch/powerpc/kernel/vdso.c                   |   6 +-
> arch/powerpc/perf/callchain_32.c             |   2 +-
> arch/powerpc/platforms/cell/spu_callbacks.c  |   6 +-
> include/asm-generic/compat.h                 |   9 +-
> .../arch/powerpc/entry/syscalls/syscall.tbl  |  24 +--
> 23 files changed, 491 insertions(+), 258 deletions(-)
> create mode 100644 arch/powerpc/include/asm/syscall_wrapper.h
> rename arch/powerpc/{kernel/ppc32.h => include/asm/syscalls_32.h} (100%)
> rename arch/powerpc/kernel/{systbl.S => systbl.c} (55%)
> 
> -- 
> 2.34.1
> 

Apologies. This is in fact V5. I can resend if anyone needs me to.

Rohan