2020-11-21 11:14:56 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef ARCH_S390_ENTRY_COMMON_H
|
|
|
|
#define ARCH_S390_ENTRY_COMMON_H
|
|
|
|
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/audit.h>
|
2021-04-29 11:14:51 +02:00
|
|
|
#include <linux/randomize_kstack.h>
|
2020-11-21 11:14:56 +01:00
|
|
|
#include <linux/processor.h>
|
|
|
|
#include <linux/uaccess.h>
|
2021-04-29 11:14:51 +02:00
|
|
|
#include <asm/timex.h>
|
2024-02-03 11:45:02 +01:00
|
|
|
#include <asm/fpu.h>
|
2022-05-04 08:23:51 +02:00
|
|
|
#include <asm/pai.h>
|
2020-11-21 11:14:56 +01:00
|
|
|
|
|
|
|
#define ARCH_EXIT_TO_USER_MODE_WORK (_TIF_GUARDED_STORAGE | _TIF_PER_TRAP)
|
|
|
|
|
|
|
|
void do_per_trap(struct pt_regs *regs);
|
|
|
|
|
2022-05-04 08:23:50 +02:00
|
|
|
static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs)
|
2020-11-21 11:14:56 +01:00
|
|
|
{
|
2022-05-04 08:23:51 +02:00
|
|
|
if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
|
|
|
|
debug_user_asce(0);
|
|
|
|
|
|
|
|
pai_kernel_enter(regs);
|
2020-11-21 11:14:56 +01:00
|
|
|
}
|
|
|
|
|
2022-05-04 08:23:50 +02:00
|
|
|
#define arch_enter_from_user_mode arch_enter_from_user_mode
|
2020-11-21 11:14:56 +01:00
|
|
|
|
|
|
|
static __always_inline void arch_exit_to_user_mode_work(struct pt_regs *regs,
|
|
|
|
unsigned long ti_work)
|
|
|
|
{
|
|
|
|
if (ti_work & _TIF_PER_TRAP) {
|
|
|
|
clear_thread_flag(TIF_PER_TRAP);
|
|
|
|
do_per_trap(regs);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ti_work & _TIF_GUARDED_STORAGE)
|
|
|
|
gs_load_bc_cb(regs);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define arch_exit_to_user_mode_work arch_exit_to_user_mode_work
|
|
|
|
|
|
|
|
static __always_inline void arch_exit_to_user_mode(void)
|
|
|
|
{
|
2024-02-03 11:45:18 +01:00
|
|
|
load_user_fpu_regs();
|
2020-11-21 11:14:56 +01:00
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
|
|
|
|
debug_user_asce(1);
|
2022-05-04 08:23:51 +02:00
|
|
|
|
|
|
|
pai_kernel_exit(current_pt_regs());
|
2020-11-21 11:14:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#define arch_exit_to_user_mode arch_exit_to_user_mode
|
|
|
|
|
2021-04-29 11:14:51 +02:00
|
|
|
static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
|
|
|
|
unsigned long ti_work)
|
|
|
|
{
|
randomize_kstack: Remove non-functional per-arch entropy filtering
An unintended consequence of commit 9c573cd31343 ("randomize_kstack:
Improve entropy diffusion") was that the per-architecture entropy size
filtering reduced how many bits were being added to the mix, rather than
how many bits were being used during the offsetting. All architectures
fell back to the existing default of 0x3FF (10 bits), which will consume
at most 1KiB of stack space. It seems that this is working just fine,
so let's avoid the confusion and update everything to use the default.
The prior intent of the per-architecture limits were:
arm64: capped at 0x1FF (9 bits), 5 bits effective
powerpc: uncapped (10 bits), 6 or 7 bits effective
riscv: uncapped (10 bits), 6 bits effective
x86: capped at 0xFF (8 bits), 5 (x86_64) or 6 (ia32) bits effective
s390: capped at 0xFF (8 bits), undocumented effective entropy
Current discussion has led to just dropping the original per-architecture
filters. The additional entropy appears to be safe for arm64, x86,
and s390. Quoting Arnd, "There is no point pretending that 15.75KB is
somehow safe to use while 15.00KB is not."
Co-developed-by: Yuntao Liu <liuyuntao12@huawei.com>
Signed-off-by: Yuntao Liu <liuyuntao12@huawei.com>
Fixes: 9c573cd31343 ("randomize_kstack: Improve entropy diffusion")
Link: https://lore.kernel.org/r/20240617133721.377540-1-liuyuntao12@huawei.com
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com> # s390
Link: https://lore.kernel.org/r/20240619214711.work.953-kees@kernel.org
Signed-off-by: Kees Cook <kees@kernel.org>
2024-06-19 14:47:15 -07:00
|
|
|
choose_random_kstack_offset(get_tod_clock_fast());
|
2021-04-29 11:14:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
|
|
|
|
|
KVM: s390: Rework guest entry logic
In __vcpu_run() and do_vsie_run(), we enter an RCU extended quiescent
state (EQS) by calling guest_enter_irqoff(), which lasts until
__vcpu_run() calls guest_exit_irqoff(). However, between the two we
enable interrupts and may handle interrupts during the EQS. As the IRQ
entry code will not wake RCU in this case, we may run the core IRQ code
and IRQ handler without RCU watching, leading to various potential
problems.
It is necessary to unmask (host) interrupts around entering the guest,
as entering the guest via SIE will not automatically unmask these. When
a host interrupt is taken from a guest, it is taken via its regular
host IRQ handler rather than being treated as a direct exit from SIE.
Due to this, we cannot simply mask interrupts around guest entry, and
must handle interrupts during this window, waking RCU as required.
Additionally, between guest_enter_irqoff() and guest_exit_irqoff(), we
use local_irq_enable() and local_irq_disable() to unmask interrupts,
violating the ordering requirements for RCU/lockdep/tracing around
entry/exit sequences. Further, since this occurs in an instrumentable
function, it's possible that instrumented code runs during this window,
with potential usage of RCU, etc.
To fix the RCU wakeup problem, an s390 implementation of
arch_in_rcu_eqs() is added which checks for PF_VCPU in current->flags.
PF_VCPU is set/cleared by guest_timing_{enter,exit}_irqoff(), which
surround the actual guest entry.
To fix the remaining issues, the lower-level guest entry logic is moved
into a shared noinstr helper function using the
guest_state_{enter,exit}_irqoff() helpers. These perform all the
lockdep/RCU/tracing manipulation necessary, but as sie64a() does not
enable/disable interrupts, we must do this explicitly with the
non-instrumented arch_local_irq_{enable,disable}() helpers:
guest_state_enter_irqoff()
arch_local_irq_enable();
sie64a(...);
arch_local_irq_disable();
guest_state_exit_irqoff();
[ajd@linux.ibm.com: rebase, fix commit message]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Janosch Frank <frankja@linux.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Andrew Donnellan <ajd@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Link: https://lore.kernel.org/r/20250708092742.104309-3-ajd@linux.ibm.com
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Message-ID: <20250708092742.104309-3-ajd@linux.ibm.com>
2025-07-08 19:27:42 +10:00
|
|
|
static __always_inline bool arch_in_rcu_eqs(void)
|
|
|
|
{
|
|
|
|
if (IS_ENABLED(CONFIG_KVM))
|
|
|
|
return current->flags & PF_VCPU;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define arch_in_rcu_eqs arch_in_rcu_eqs
|
|
|
|
|
2020-11-21 11:14:56 +01:00
|
|
|
#endif
|