mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 00:29:35 +08:00
Merge tag 'sched-urgent-2026-05-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull scheduler fix from Ingo Molnar: - Fix ARM64-specific rseq regressions (Mark Rutland) * tag 'sched-urgent-2026-05-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: arm64/entry: Fix arm64-specific rseq brokenness
This commit is contained in:
@@ -62,6 +62,13 @@ static void noinstr arm64_exit_to_kernel_mode(struct pt_regs *regs,
|
||||
irqentry_exit_to_kernel_mode_after_preempt(regs, state);
|
||||
}
|
||||
|
||||
static __always_inline void arm64_syscall_enter_from_user_mode(struct pt_regs *regs)
|
||||
{
|
||||
enter_from_user_mode(regs);
|
||||
mte_disable_tco_entry(current);
|
||||
sme_enter_from_user_mode();
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle IRQ/context state management when entering from user mode.
|
||||
* Before this function is called it is not safe to call regular kernel code,
|
||||
@@ -70,20 +77,30 @@ static void noinstr arm64_exit_to_kernel_mode(struct pt_regs *regs,
|
||||
static __always_inline void arm64_enter_from_user_mode(struct pt_regs *regs)
|
||||
{
|
||||
enter_from_user_mode(regs);
|
||||
rseq_note_user_irq_entry();
|
||||
mte_disable_tco_entry(current);
|
||||
sme_enter_from_user_mode();
|
||||
}
|
||||
|
||||
static __always_inline void arm64_syscall_exit_to_user_mode(struct pt_regs *regs)
|
||||
{
|
||||
local_irq_disable();
|
||||
syscall_exit_to_user_mode_prepare(regs);
|
||||
local_daif_mask();
|
||||
sme_exit_to_user_mode();
|
||||
mte_check_tfsr_exit();
|
||||
exit_to_user_mode();
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle IRQ/context state management when exiting to user mode.
|
||||
* After this function returns it is not safe to call regular kernel code,
|
||||
* instrumentable code, or any code which may trigger an exception.
|
||||
*/
|
||||
|
||||
static __always_inline void arm64_exit_to_user_mode(struct pt_regs *regs)
|
||||
{
|
||||
local_irq_disable();
|
||||
exit_to_user_mode_prepare_legacy(regs);
|
||||
irqentry_exit_to_user_mode_prepare(regs);
|
||||
local_daif_mask();
|
||||
sme_exit_to_user_mode();
|
||||
mte_check_tfsr_exit();
|
||||
@@ -92,7 +109,7 @@ static __always_inline void arm64_exit_to_user_mode(struct pt_regs *regs)
|
||||
|
||||
asmlinkage void noinstr asm_exit_to_user_mode(struct pt_regs *regs)
|
||||
{
|
||||
arm64_exit_to_user_mode(regs);
|
||||
arm64_syscall_exit_to_user_mode(regs);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -716,12 +733,12 @@ static void noinstr el0_brk64(struct pt_regs *regs, unsigned long esr)
|
||||
|
||||
static void noinstr el0_svc(struct pt_regs *regs)
|
||||
{
|
||||
arm64_enter_from_user_mode(regs);
|
||||
arm64_syscall_enter_from_user_mode(regs);
|
||||
cortex_a76_erratum_1463225_svc_handler();
|
||||
fpsimd_syscall_enter();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_el0_svc(regs);
|
||||
arm64_exit_to_user_mode(regs);
|
||||
arm64_syscall_exit_to_user_mode(regs);
|
||||
fpsimd_syscall_exit();
|
||||
}
|
||||
|
||||
@@ -868,11 +885,11 @@ static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr)
|
||||
|
||||
static void noinstr el0_svc_compat(struct pt_regs *regs)
|
||||
{
|
||||
arm64_enter_from_user_mode(regs);
|
||||
arm64_syscall_enter_from_user_mode(regs);
|
||||
cortex_a76_erratum_1463225_svc_handler();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_el0_svc_compat(regs);
|
||||
arm64_exit_to_user_mode(regs);
|
||||
arm64_syscall_exit_to_user_mode(regs);
|
||||
}
|
||||
|
||||
static void noinstr el0_bkpt32(struct pt_regs *regs, unsigned long esr)
|
||||
|
||||
@@ -218,14 +218,6 @@ static __always_inline void __exit_to_user_mode_validate(void)
|
||||
lockdep_sys_exit();
|
||||
}
|
||||
|
||||
/* Temporary workaround to keep ARM64 alive */
|
||||
static __always_inline void exit_to_user_mode_prepare_legacy(struct pt_regs *regs)
|
||||
{
|
||||
__exit_to_user_mode_prepare(regs, EXIT_TO_USER_MODE_WORK);
|
||||
rseq_exit_to_user_mode_legacy();
|
||||
__exit_to_user_mode_validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* syscall_exit_to_user_mode_prepare - call exit_to_user_mode_loop() if required
|
||||
* @regs: Pointer to pt_regs on entry stack
|
||||
|
||||
@@ -749,24 +749,6 @@ static __always_inline void rseq_irqentry_exit_to_user_mode(void)
|
||||
ev->events = 0;
|
||||
}
|
||||
|
||||
/* Required to keep ARM64 working */
|
||||
static __always_inline void rseq_exit_to_user_mode_legacy(void)
|
||||
{
|
||||
struct rseq_event *ev = ¤t->rseq.event;
|
||||
|
||||
rseq_stat_inc(rseq_stats.exit);
|
||||
|
||||
if (static_branch_unlikely(&rseq_debug_enabled))
|
||||
WARN_ON_ONCE(ev->sched_switch);
|
||||
|
||||
/*
|
||||
* Ensure that event (especially user_irq) is cleared when the
|
||||
* interrupt did not result in a schedule and therefore the
|
||||
* rseq processing did not clear it.
|
||||
*/
|
||||
ev->events = 0;
|
||||
}
|
||||
|
||||
void __rseq_debug_syscall_return(struct pt_regs *regs);
|
||||
|
||||
static __always_inline void rseq_debug_syscall_return(struct pt_regs *regs)
|
||||
@@ -782,7 +764,6 @@ static inline bool rseq_exit_to_user_mode_restart(struct pt_regs *regs, unsigned
|
||||
}
|
||||
static inline void rseq_syscall_exit_to_user_mode(void) { }
|
||||
static inline void rseq_irqentry_exit_to_user_mode(void) { }
|
||||
static inline void rseq_exit_to_user_mode_legacy(void) { }
|
||||
static inline void rseq_debug_syscall_return(struct pt_regs *regs) { }
|
||||
static inline bool rseq_grant_slice_extension(unsigned long ti_work, unsigned long mask) { return false; }
|
||||
#endif /* !CONFIG_RSEQ */
|
||||
|
||||
Reference in New Issue
Block a user