resume_user_mode.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. #ifndef LINUX_RESUME_USER_MODE_H
  3. #define LINUX_RESUME_USER_MODE_H
  4. #include <linux/sched.h>
  5. #include <linux/task_work.h>
  6. #include <linux/memcontrol.h>
  7. #include <linux/blk-cgroup.h>
  8. /**
  9. * set_notify_resume - cause resume_user_mode_work() to be called
  10. * @task: task that will call resume_user_mode_work()
  11. *
  12. * Calling this arranges that @task will call resume_user_mode_work()
  13. * before returning to user mode. If it's already running in user mode,
  14. * it will enter the kernel and call resume_user_mode_work() soon.
  15. * If it's blocked, it will not be woken.
  16. */
  17. static inline void set_notify_resume(struct task_struct *task)
  18. {
  19. if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME))
  20. kick_process(task);
  21. }
  22. /**
  23. * resume_user_mode_work - Perform work before returning to user mode
  24. * @regs: user-mode registers of @current task
  25. *
  26. * This is called when %TIF_NOTIFY_RESUME has been set. Now we are
  27. * about to return to user mode, and the user state in @regs can be
  28. * inspected or adjusted. The caller in arch code has cleared
  29. * %TIF_NOTIFY_RESUME before the call. If the flag gets set again
  30. * asynchronously, this will be called again before we return to
  31. * user mode.
  32. *
  33. * Called without locks.
  34. */
  35. static inline void resume_user_mode_work(struct pt_regs *regs)
  36. {
  37. clear_thread_flag(TIF_NOTIFY_RESUME);
  38. /*
  39. * This barrier pairs with task_work_add()->set_notify_resume() after
  40. * hlist_add_head(task->task_works);
  41. */
  42. smp_mb__after_atomic();
  43. if (unlikely(task_work_pending(current)))
  44. task_work_run();
  45. #ifdef CONFIG_KEYS_REQUEST_CACHE
  46. if (unlikely(current->cached_requested_key)) {
  47. key_put(current->cached_requested_key);
  48. current->cached_requested_key = NULL;
  49. }
  50. #endif
  51. mem_cgroup_handle_over_high(GFP_KERNEL);
  52. blkcg_maybe_throttle_current();
  53. rseq_handle_notify_resume(NULL, regs);
  54. }
  55. #endif /* LINUX_RESUME_USER_MODE_H */