unwind.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_X86_UNWIND_H
  3. #define _ASM_X86_UNWIND_H
  4. #include <linux/sched.h>
  5. #include <linux/ftrace.h>
  6. #include <linux/rethook.h>
  7. #include <asm/ptrace.h>
  8. #include <asm/stacktrace.h>
  9. #define IRET_FRAME_OFFSET (offsetof(struct pt_regs, ip))
  10. #define IRET_FRAME_SIZE (sizeof(struct pt_regs) - IRET_FRAME_OFFSET)
  11. struct unwind_state {
  12. struct stack_info stack_info;
  13. unsigned long stack_mask;
  14. struct task_struct *task;
  15. int graph_idx;
  16. #if defined(CONFIG_RETHOOK)
  17. struct llist_node *kr_cur;
  18. #endif
  19. bool error;
  20. #if defined(CONFIG_UNWINDER_ORC)
  21. bool signal, full_regs;
  22. unsigned long sp, bp, ip;
  23. struct pt_regs *regs, *prev_regs;
  24. #elif defined(CONFIG_UNWINDER_FRAME_POINTER)
  25. bool got_irq;
  26. unsigned long *bp, *orig_sp, ip;
  27. /*
  28. * If non-NULL: The current frame is incomplete and doesn't contain a
  29. * valid BP. When looking for the next frame, use this instead of the
  30. * non-existent saved BP.
  31. */
  32. unsigned long *next_bp;
  33. struct pt_regs *regs;
  34. #else
  35. unsigned long *sp;
  36. #endif
  37. };
  38. void __unwind_start(struct unwind_state *state, struct task_struct *task,
  39. struct pt_regs *regs, unsigned long *first_frame);
  40. bool unwind_next_frame(struct unwind_state *state);
  41. unsigned long unwind_get_return_address(struct unwind_state *state);
  42. unsigned long *unwind_get_return_address_ptr(struct unwind_state *state);
  43. static inline bool unwind_done(struct unwind_state *state)
  44. {
  45. return state->stack_info.type == STACK_TYPE_UNKNOWN;
  46. }
  47. static inline bool unwind_error(struct unwind_state *state)
  48. {
  49. return state->error;
  50. }
  51. static inline
  52. void unwind_start(struct unwind_state *state, struct task_struct *task,
  53. struct pt_regs *regs, unsigned long *first_frame)
  54. {
  55. first_frame = first_frame ? : get_stack_pointer(task, regs);
  56. __unwind_start(state, task, regs, first_frame);
  57. }
  58. #if defined(CONFIG_UNWINDER_ORC) || defined(CONFIG_UNWINDER_FRAME_POINTER)
  59. /*
  60. * If 'partial' returns true, only the iret frame registers are valid.
  61. */
  62. static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state,
  63. bool *partial)
  64. {
  65. if (unwind_done(state))
  66. return NULL;
  67. if (partial) {
  68. #ifdef CONFIG_UNWINDER_ORC
  69. *partial = !state->full_regs;
  70. #else
  71. *partial = false;
  72. #endif
  73. }
  74. return state->regs;
  75. }
  76. #else
  77. static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state,
  78. bool *partial)
  79. {
  80. return NULL;
  81. }
  82. #endif
  83. #ifdef CONFIG_UNWINDER_ORC
  84. void unwind_init(void);
  85. void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size,
  86. void *orc, size_t orc_size);
  87. #else
  88. static inline void unwind_init(void) {}
  89. static inline
  90. void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size,
  91. void *orc, size_t orc_size) {}
  92. #endif
  93. static inline
  94. unsigned long unwind_recover_rethook(struct unwind_state *state,
  95. unsigned long addr, unsigned long *addr_p)
  96. {
  97. #ifdef CONFIG_RETHOOK
  98. if (is_rethook_trampoline(addr))
  99. return rethook_find_ret_addr(state->task, (unsigned long)addr_p,
  100. &state->kr_cur);
  101. #endif
  102. return addr;
  103. }
  104. /* Recover the return address modified by rethook and ftrace_graph. */
  105. static inline
  106. unsigned long unwind_recover_ret_addr(struct unwind_state *state,
  107. unsigned long addr, unsigned long *addr_p)
  108. {
  109. unsigned long ret;
  110. ret = ftrace_graph_ret_addr(state->task, &state->graph_idx,
  111. addr, addr_p);
  112. return unwind_recover_rethook(state, ret, addr_p);
  113. }
  114. /*
  115. * This disables KASAN checking when reading a value from another task's stack,
  116. * since the other task could be running on another CPU and could have poisoned
  117. * the stack in the meantime.
  118. */
  119. #define READ_ONCE_TASK_STACK(task, x) \
  120. ({ \
  121. unsigned long val; \
  122. if (task == current) \
  123. val = READ_ONCE(x); \
  124. else \
  125. val = READ_ONCE_NOCHECK(x); \
  126. val; \
  127. })
  128. static inline bool task_on_another_cpu(struct task_struct *task)
  129. {
  130. #ifdef CONFIG_SMP
  131. return task != current && task->on_cpu;
  132. #else
  133. return false;
  134. #endif
  135. }
  136. #endif /* _ASM_X86_UNWIND_H */