This is the same as syscall_exit_to_user_mode() but without calling exit_to_user_mode(). This is useful if a syscall has to be restarted without leaving to user space.
Signed-off-by: Sven Schnelle <sv...@linux.ibm.com> --- include/linux/entry-common.h | 9 +++++++++ kernel/entry/common.c | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h index 112007525f50..bdf6b005bbfb 100644 --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h @@ -312,6 +312,15 @@ static inline void arch_syscall_exit_tracehook(struct pt_regs *regs, bool step) */ void syscall_exit_to_user_mode(struct pt_regs *regs); +/** + * syscall_exit_to_user_mode_work - Handle work before returning to user mode + * @regs: Pointer to currents pt_regs + * + * Same as syscall_exit_to_user_mode() but without calling exit_to_user_mode() + * to perform the final transition to user mode. + */ +void syscall_exit_to_user_mode_work(struct pt_regs *regs); + /** * irqentry_enter_from_user_mode - Establish state before invoking the irq handler * @regs: Pointer to currents pt_regs diff --git a/kernel/entry/common.c b/kernel/entry/common.c index e696f6912642..c3c4ba21824a 100644 --- a/kernel/entry/common.c +++ b/kernel/entry/common.c @@ -246,12 +246,22 @@ static void syscall_exit_to_user_mode_prepare(struct pt_regs *regs) syscall_exit_work(regs, cached_flags); } -__visible noinstr void syscall_exit_to_user_mode(struct pt_regs *regs) +static __always_inline void __syscall_exit_to_user_mode_work(struct pt_regs *regs) { - instrumentation_begin(); syscall_exit_to_user_mode_prepare(regs); local_irq_disable_exit_to_user(); exit_to_user_mode_prepare(regs); +} + +void syscall_exit_to_user_mode_work(struct pt_regs *regs) +{ + __syscall_exit_to_user_mode_work(regs); +} + +__visible noinstr void syscall_exit_to_user_mode(struct pt_regs *regs) +{ + instrumentation_begin(); + __syscall_exit_to_user_mode_work(regs); instrumentation_end(); __exit_to_user_mode(); } -- 2.17.1