Skip to content

Commit c97481a

Browse files
committed
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
2 parents daa3de2 + 411c1cf commit c97481a

3 files changed

Lines changed: 24 additions & 34 deletions

File tree

arch/arm64/kernel/entry-common.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ static void noinstr arm64_exit_to_kernel_mode(struct pt_regs *regs,
6262
irqentry_exit_to_kernel_mode_after_preempt(regs, state);
6363
}
6464

65+
static __always_inline void arm64_syscall_enter_from_user_mode(struct pt_regs *regs)
66+
{
67+
enter_from_user_mode(regs);
68+
mte_disable_tco_entry(current);
69+
sme_enter_from_user_mode();
70+
}
71+
6572
/*
6673
* Handle IRQ/context state management when entering from user mode.
6774
* 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,
7077
static __always_inline void arm64_enter_from_user_mode(struct pt_regs *regs)
7178
{
7279
enter_from_user_mode(regs);
80+
rseq_note_user_irq_entry();
7381
mte_disable_tco_entry(current);
7482
sme_enter_from_user_mode();
7583
}
7684

85+
static __always_inline void arm64_syscall_exit_to_user_mode(struct pt_regs *regs)
86+
{
87+
local_irq_disable();
88+
syscall_exit_to_user_mode_prepare(regs);
89+
local_daif_mask();
90+
sme_exit_to_user_mode();
91+
mte_check_tfsr_exit();
92+
exit_to_user_mode();
93+
}
94+
7795
/*
7896
* Handle IRQ/context state management when exiting to user mode.
7997
* After this function returns it is not safe to call regular kernel code,
8098
* instrumentable code, or any code which may trigger an exception.
8199
*/
82-
83100
static __always_inline void arm64_exit_to_user_mode(struct pt_regs *regs)
84101
{
85102
local_irq_disable();
86-
exit_to_user_mode_prepare_legacy(regs);
103+
irqentry_exit_to_user_mode_prepare(regs);
87104
local_daif_mask();
88105
sme_exit_to_user_mode();
89106
mte_check_tfsr_exit();
@@ -92,7 +109,7 @@ static __always_inline void arm64_exit_to_user_mode(struct pt_regs *regs)
92109

93110
asmlinkage void noinstr asm_exit_to_user_mode(struct pt_regs *regs)
94111
{
95-
arm64_exit_to_user_mode(regs);
112+
arm64_syscall_exit_to_user_mode(regs);
96113
}
97114

98115
/*
@@ -716,12 +733,12 @@ static void noinstr el0_brk64(struct pt_regs *regs, unsigned long esr)
716733

717734
static void noinstr el0_svc(struct pt_regs *regs)
718735
{
719-
arm64_enter_from_user_mode(regs);
736+
arm64_syscall_enter_from_user_mode(regs);
720737
cortex_a76_erratum_1463225_svc_handler();
721738
fpsimd_syscall_enter();
722739
local_daif_restore(DAIF_PROCCTX);
723740
do_el0_svc(regs);
724-
arm64_exit_to_user_mode(regs);
741+
arm64_syscall_exit_to_user_mode(regs);
725742
fpsimd_syscall_exit();
726743
}
727744

@@ -868,11 +885,11 @@ static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr)
868885

869886
static void noinstr el0_svc_compat(struct pt_regs *regs)
870887
{
871-
arm64_enter_from_user_mode(regs);
888+
arm64_syscall_enter_from_user_mode(regs);
872889
cortex_a76_erratum_1463225_svc_handler();
873890
local_daif_restore(DAIF_PROCCTX);
874891
do_el0_svc_compat(regs);
875-
arm64_exit_to_user_mode(regs);
892+
arm64_syscall_exit_to_user_mode(regs);
876893
}
877894

878895
static void noinstr el0_bkpt32(struct pt_regs *regs, unsigned long esr)

include/linux/irq-entry-common.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,14 +218,6 @@ static __always_inline void __exit_to_user_mode_validate(void)
218218
lockdep_sys_exit();
219219
}
220220

221-
/* Temporary workaround to keep ARM64 alive */
222-
static __always_inline void exit_to_user_mode_prepare_legacy(struct pt_regs *regs)
223-
{
224-
__exit_to_user_mode_prepare(regs, EXIT_TO_USER_MODE_WORK);
225-
rseq_exit_to_user_mode_legacy();
226-
__exit_to_user_mode_validate();
227-
}
228-
229221
/**
230222
* syscall_exit_to_user_mode_prepare - call exit_to_user_mode_loop() if required
231223
* @regs: Pointer to pt_regs on entry stack

include/linux/rseq_entry.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -749,24 +749,6 @@ static __always_inline void rseq_irqentry_exit_to_user_mode(void)
749749
ev->events = 0;
750750
}
751751

752-
/* Required to keep ARM64 working */
753-
static __always_inline void rseq_exit_to_user_mode_legacy(void)
754-
{
755-
struct rseq_event *ev = &current->rseq.event;
756-
757-
rseq_stat_inc(rseq_stats.exit);
758-
759-
if (static_branch_unlikely(&rseq_debug_enabled))
760-
WARN_ON_ONCE(ev->sched_switch);
761-
762-
/*
763-
* Ensure that event (especially user_irq) is cleared when the
764-
* interrupt did not result in a schedule and therefore the
765-
* rseq processing did not clear it.
766-
*/
767-
ev->events = 0;
768-
}
769-
770752
void __rseq_debug_syscall_return(struct pt_regs *regs);
771753

772754
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
782764
}
783765
static inline void rseq_syscall_exit_to_user_mode(void) { }
784766
static inline void rseq_irqentry_exit_to_user_mode(void) { }
785-
static inline void rseq_exit_to_user_mode_legacy(void) { }
786767
static inline void rseq_debug_syscall_return(struct pt_regs *regs) { }
787768
static inline bool rseq_grant_slice_extension(unsigned long ti_work, unsigned long mask) { return false; }
788769
#endif /* !CONFIG_RSEQ */

0 commit comments

Comments
 (0)