···1414#include <linux/kmsan.h>15151616#include <asm/entry-common.h>1717+#include <asm/syscall.h>17181819/*1920 * Define dummy _TIF work flags if not defined by the architecture or for···368367}369368370369/**370370+ * syscall_exit_work - Handle work before returning to user mode371371+ * @regs: Pointer to current pt_regs372372+ * @work: Current thread syscall work373373+ *374374+ * Do one-time syscall specific work.375375+ */376376+void syscall_exit_work(struct pt_regs *regs, unsigned long work);377377+378378+/**371379 * syscall_exit_to_user_mode_work - Handle work before returning to user mode372380 * @regs: Pointer to currents pt_regs373381 *···389379 * make the final state transitions. Interrupts must stay disabled between390380 * return from this function and the invocation of exit_to_user_mode().391381 */392392-void syscall_exit_to_user_mode_work(struct pt_regs *regs);382382+static __always_inline void syscall_exit_to_user_mode_work(struct pt_regs *regs)383383+{384384+ unsigned long work = READ_ONCE(current_thread_info()->syscall_work);385385+ unsigned long nr = syscall_get_nr(current, regs);386386+387387+ CT_WARN_ON(ct_state() != CT_STATE_KERNEL);388388+389389+ if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {390390+ if (WARN(irqs_disabled(), "syscall %lu left IRQs disabled", nr))391391+ local_irq_enable();392392+ }393393+394394+ rseq_syscall(regs);395395+396396+ /*397397+ * Do one-time syscall specific work. If these work items are398398+ * enabled, we want to run them exactly once per syscall exit with399399+ * interrupts enabled.400400+ */401401+ if (unlikely(work & SYSCALL_WORK_EXIT))402402+ syscall_exit_work(regs, work);403403+ local_irq_disable_exit_to_user();404404+ exit_to_user_mode_prepare(regs);405405+}393406394407/**395408 * syscall_exit_to_user_mode - Handle work before returning to user mode···443410 * exit_to_user_mode(). This function is preferred unless there is a444411 * compelling architectural reason to use the separate functions.445412 */446446-void syscall_exit_to_user_mode(struct pt_regs *regs);413413+static __always_inline void syscall_exit_to_user_mode(struct pt_regs *regs)414414+{415415+ instrumentation_begin();416416+ syscall_exit_to_user_mode_work(regs);417417+ instrumentation_end();418418+ exit_to_user_mode();419419+}447420448421/**449422 * irqentry_enter_from_user_mode - Establish state before invoking the irq handler
+1-48
kernel/entry/common.c
···146146 return work & SYSCALL_WORK_SYSCALL_EXIT_TRAP;147147}148148149149-static void syscall_exit_work(struct pt_regs *regs, unsigned long work)149149+void syscall_exit_work(struct pt_regs *regs, unsigned long work)150150{151151 bool step;152152···171171 step = report_single_step(work);172172 if (step || work & SYSCALL_WORK_SYSCALL_TRACE)173173 ptrace_report_syscall_exit(regs, step);174174-}175175-176176-/*177177- * Syscall specific exit to user mode preparation. Runs with interrupts178178- * enabled.179179- */180180-static void syscall_exit_to_user_mode_prepare(struct pt_regs *regs)181181-{182182- unsigned long work = READ_ONCE(current_thread_info()->syscall_work);183183- unsigned long nr = syscall_get_nr(current, regs);184184-185185- CT_WARN_ON(ct_state() != CT_STATE_KERNEL);186186-187187- if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {188188- if (WARN(irqs_disabled(), "syscall %lu left IRQs disabled", nr))189189- local_irq_enable();190190- }191191-192192- rseq_syscall(regs);193193-194194- /*195195- * Do one-time syscall specific work. If these work items are196196- * enabled, we want to run them exactly once per syscall exit with197197- * interrupts enabled.198198- */199199- if (unlikely(work & SYSCALL_WORK_EXIT))200200- syscall_exit_work(regs, work);201201-}202202-203203-static __always_inline void __syscall_exit_to_user_mode_work(struct pt_regs *regs)204204-{205205- syscall_exit_to_user_mode_prepare(regs);206206- local_irq_disable_exit_to_user();207207- exit_to_user_mode_prepare(regs);208208-}209209-210210-void syscall_exit_to_user_mode_work(struct pt_regs *regs)211211-{212212- __syscall_exit_to_user_mode_work(regs);213213-}214214-215215-__visible noinstr void syscall_exit_to_user_mode(struct pt_regs *regs)216216-{217217- instrumentation_begin();218218- __syscall_exit_to_user_mode_work(regs);219219- instrumentation_end();220220- exit_to_user_mode();221174}222175223176noinstr void irqentry_enter_from_user_mode(struct pt_regs *regs)