diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/entry/common.c | 26 | ||||
| -rw-r--r-- | kernel/rseq.c | 8 |
2 files changed, 25 insertions, 9 deletions
diff --git a/kernel/entry/common.c b/kernel/entry/common.c index 70a16db4cc0a..523a3e758af4 100644 --- a/kernel/entry/common.c +++ b/kernel/entry/common.c @@ -11,13 +11,8 @@ /* Workaround to allow gradual conversion of architecture code */ void __weak arch_do_signal_or_restart(struct pt_regs *regs) { } -/** - * exit_to_user_mode_loop - do any pending work before leaving to user space - * @regs: Pointer to pt_regs on entry stack - * @ti_work: TIF work flags as read by the caller - */ -__always_inline unsigned long exit_to_user_mode_loop(struct pt_regs *regs, - unsigned long ti_work) +static __always_inline unsigned long __exit_to_user_mode_loop(struct pt_regs *regs, + unsigned long ti_work) { /* * Before returning to user space ensure that all pending work @@ -62,6 +57,23 @@ __always_inline unsigned long exit_to_user_mode_loop(struct pt_regs *regs, return ti_work; } +/** + * exit_to_user_mode_loop - do any pending work before leaving to user space + * @regs: Pointer to pt_regs on entry stack + * @ti_work: TIF work flags as read by the caller + */ +__always_inline unsigned long exit_to_user_mode_loop(struct pt_regs *regs, + unsigned long ti_work) +{ + for (;;) { + ti_work = __exit_to_user_mode_loop(regs, ti_work); + + if (likely(!rseq_exit_to_user_mode_restart(regs))) + return ti_work; + ti_work = read_thread_flags(); + } +} + noinstr irqentry_state_t irqentry_enter(struct pt_regs *regs) { irqentry_state_t ret = { diff --git a/kernel/rseq.c b/kernel/rseq.c index c5d6336c6956..395d8b002350 100644 --- a/kernel/rseq.c +++ b/kernel/rseq.c @@ -237,7 +237,11 @@ efault: static void rseq_slowpath_update_usr(struct pt_regs *regs) { - /* Preserve rseq state and user_irq state for exit to user */ + /* + * Preserve rseq state and user_irq state. The generic entry code + * clears user_irq on the way out, the non-generic entry + * architectures are not having user_irq. + */ const struct rseq_event evt_mask = { .has_rseq = true, .user_irq = true, }; struct task_struct *t = current; struct rseq_ids ids; @@ -289,7 +293,7 @@ static void rseq_slowpath_update_usr(struct pt_regs *regs) } } -void __rseq_handle_notify_resume(struct pt_regs *regs) +void __rseq_handle_slowpath(struct pt_regs *regs) { /* * If invoked from hypervisors before entering the guest via |
