s390/mm: Reimplement lazy ASCE handling
authorHeiko Carstens <hca@linux.ibm.com>
Wed, 9 Apr 2025 13:01:50 +0000 (15:01 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Mon, 14 Apr 2025 09:23:21 +0000 (11:23 +0200)
commit8b72f5a97b82185806ff085582ece86ce5b9811e
treee2ecd858e50238919a93df97debb9b19f1496ff9
parent8ffd015db85fea3e15a77027fda6c02ced4d2444
s390/mm: Reimplement lazy ASCE handling

Reduce system call overhead time (round trip time for invoking a
non-existent system call) by 25%.

With the removal of set_fs() [1] lazy control register handling was removed
in order to keep kernel entry and exit simple. However this made system
calls slower.

With the conversion to generic entry [2] and numerous follow up changes
which simplified the entry code significantly, adding support for lazy asce
handling doesn't add much complexity to the entry code anymore.

In particular this means:

- On kernel entry the primary asce is not modified and contains the user
  asce

- Kernel accesses which require secondary-space mode (for example futex
  operations) are surrounded by enable_sacf_uaccess() and
  disable_sacf_uaccess() calls. enable_sacf_uaccess() sets the primary asce
  to kernel asce so that the sacf instruction can be used to switch to
  secondary-space mode. The primary asce is changed back to user asce with
  disable_sacf_uaccess().

The state of the control register which contains the primary asce is
reflected with a new TIF_ASCE_PRIMARY bit. This is required on context
switch so that the correct asce is restored for the scheduled in process.

In result address spaces are now setup like this:

CPU running in               | %cr1 ASCE | %cr7 ASCE | %cr13 ASCE
-----------------------------|-----------|-----------|-----------
user space                   |  user     |  user     |  kernel
kernel (no sacf)             |  user     |  user     |  kernel
kernel (during sacf uaccess) |  kernel   |  user     |  kernel
kernel (kvm guest execution) |  guest    |  user     |  kernel

In result cr1 control register content is not changed except for:
- futex system calls
- legacy s390 PCI system calls
- the kvm specific cmpxchg_user_key() uaccess helper

This leads to faster system call execution.

[1] 87d598634521 ("s390/mm: remove set_fs / rework address space handling")
[2] 56e62a737028 ("s390: convert to generic entry")

Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
12 files changed:
arch/s390/include/asm/asce.h [new file with mode: 0644]
arch/s390/include/asm/futex.h
arch/s390/include/asm/mmu_context.h
arch/s390/include/asm/ptrace.h
arch/s390/include/asm/thread_info.h
arch/s390/include/asm/uaccess.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/entry.S
arch/s390/kernel/smp.c
arch/s390/lib/uaccess.c
arch/s390/mm/pgalloc.c
arch/s390/pci/pci_mmio.c