utils.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <asm/insn.h>
  3. #include <linux/mm.h>
  4. #include "perf_event.h"
  5. static int decode_branch_type(struct insn *insn)
  6. {
  7. int ext;
  8. if (insn_get_opcode(insn))
  9. return X86_BR_ABORT;
  10. switch (insn->opcode.bytes[0]) {
  11. case 0xf:
  12. switch (insn->opcode.bytes[1]) {
  13. case 0x05: /* syscall */
  14. case 0x34: /* sysenter */
  15. return X86_BR_SYSCALL;
  16. case 0x07: /* sysret */
  17. case 0x35: /* sysexit */
  18. return X86_BR_SYSRET;
  19. case 0x80 ... 0x8f: /* conditional */
  20. return X86_BR_JCC;
  21. }
  22. return X86_BR_NONE;
  23. case 0x70 ... 0x7f: /* conditional */
  24. return X86_BR_JCC;
  25. case 0xc2: /* near ret */
  26. case 0xc3: /* near ret */
  27. case 0xca: /* far ret */
  28. case 0xcb: /* far ret */
  29. return X86_BR_RET;
  30. case 0xcf: /* iret */
  31. return X86_BR_IRET;
  32. case 0xcc ... 0xce: /* int */
  33. return X86_BR_INT;
  34. case 0xe8: /* call near rel */
  35. if (insn_get_immediate(insn) || insn->immediate1.value == 0) {
  36. /* zero length call */
  37. return X86_BR_ZERO_CALL;
  38. }
  39. fallthrough;
  40. case 0x9a: /* call far absolute */
  41. return X86_BR_CALL;
  42. case 0xe0 ... 0xe3: /* loop jmp */
  43. return X86_BR_JCC;
  44. case 0xe9 ... 0xeb: /* jmp */
  45. return X86_BR_JMP;
  46. case 0xff: /* call near absolute, call far absolute ind */
  47. if (insn_get_modrm(insn))
  48. return X86_BR_ABORT;
  49. ext = (insn->modrm.bytes[0] >> 3) & 0x7;
  50. switch (ext) {
  51. case 2: /* near ind call */
  52. case 3: /* far ind call */
  53. return X86_BR_IND_CALL;
  54. case 4:
  55. case 5:
  56. return X86_BR_IND_JMP;
  57. }
  58. return X86_BR_NONE;
  59. }
  60. return X86_BR_NONE;
  61. }
  62. /*
  63. * return the type of control flow change at address "from"
  64. * instruction is not necessarily a branch (in case of interrupt).
  65. *
  66. * The branch type returned also includes the priv level of the
  67. * target of the control flow change (X86_BR_USER, X86_BR_KERNEL).
  68. *
  69. * If a branch type is unknown OR the instruction cannot be
  70. * decoded (e.g., text page not present), then X86_BR_NONE is
  71. * returned.
  72. *
  73. * While recording branches, some processors can report the "from"
  74. * address to be that of an instruction preceding the actual branch
  75. * when instruction fusion occurs. If fusion is expected, attempt to
  76. * find the type of the first branch instruction within the next
  77. * MAX_INSN_SIZE bytes and if found, provide the offset between the
  78. * reported "from" address and the actual branch instruction address.
  79. */
  80. static int get_branch_type(unsigned long from, unsigned long to, int abort,
  81. bool fused, int *offset)
  82. {
  83. struct insn insn;
  84. void *addr;
  85. int bytes_read, bytes_left, insn_offset;
  86. int ret = X86_BR_NONE;
  87. int to_plm, from_plm;
  88. u8 buf[MAX_INSN_SIZE];
  89. int is64 = 0;
  90. /* make sure we initialize offset */
  91. if (offset)
  92. *offset = 0;
  93. to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
  94. from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
  95. /*
  96. * maybe zero if lbr did not fill up after a reset by the time
  97. * we get a PMU interrupt
  98. */
  99. if (from == 0 || to == 0)
  100. return X86_BR_NONE;
  101. if (abort)
  102. return X86_BR_ABORT | to_plm;
  103. if (from_plm == X86_BR_USER) {
  104. /*
  105. * can happen if measuring at the user level only
  106. * and we interrupt in a kernel thread, e.g., idle.
  107. */
  108. if (!current->mm)
  109. return X86_BR_NONE;
  110. /* may fail if text not present */
  111. bytes_left = copy_from_user_nmi(buf, (void __user *)from,
  112. MAX_INSN_SIZE);
  113. bytes_read = MAX_INSN_SIZE - bytes_left;
  114. if (!bytes_read)
  115. return X86_BR_NONE;
  116. addr = buf;
  117. } else {
  118. /*
  119. * The LBR logs any address in the IP, even if the IP just
  120. * faulted. This means userspace can control the from address.
  121. * Ensure we don't blindly read any address by validating it is
  122. * a known text address and not a vsyscall address.
  123. */
  124. if (kernel_text_address(from) && !in_gate_area_no_mm(from)) {
  125. addr = (void *)from;
  126. /*
  127. * Assume we can get the maximum possible size
  128. * when grabbing kernel data. This is not
  129. * _strictly_ true since we could possibly be
  130. * executing up next to a memory hole, but
  131. * it is very unlikely to be a problem.
  132. */
  133. bytes_read = MAX_INSN_SIZE;
  134. } else {
  135. return X86_BR_NONE;
  136. }
  137. }
  138. /*
  139. * decoder needs to know the ABI especially
  140. * on 64-bit systems running 32-bit apps
  141. */
  142. #ifdef CONFIG_X86_64
  143. is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs());
  144. #endif
  145. insn_init(&insn, addr, bytes_read, is64);
  146. ret = decode_branch_type(&insn);
  147. insn_offset = 0;
  148. /* Check for the possibility of branch fusion */
  149. while (fused && ret == X86_BR_NONE) {
  150. /* Check for decoding errors */
  151. if (insn_get_length(&insn) || !insn.length)
  152. break;
  153. insn_offset += insn.length;
  154. bytes_read -= insn.length;
  155. if (bytes_read < 0)
  156. break;
  157. insn_init(&insn, addr + insn_offset, bytes_read, is64);
  158. ret = decode_branch_type(&insn);
  159. }
  160. if (offset)
  161. *offset = insn_offset;
  162. /*
  163. * interrupts, traps, faults (and thus ring transition) may
  164. * occur on any instructions. Thus, to classify them correctly,
  165. * we need to first look at the from and to priv levels. If they
  166. * are different and to is in the kernel, then it indicates
  167. * a ring transition. If the from instruction is not a ring
  168. * transition instr (syscall, systenter, int), then it means
  169. * it was a irq, trap or fault.
  170. *
  171. * we have no way of detecting kernel to kernel faults.
  172. */
  173. if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL
  174. && ret != X86_BR_SYSCALL && ret != X86_BR_INT)
  175. ret = X86_BR_IRQ;
  176. /*
  177. * branch priv level determined by target as
  178. * is done by HW when LBR_SELECT is implemented
  179. */
  180. if (ret != X86_BR_NONE)
  181. ret |= to_plm;
  182. return ret;
  183. }
  184. int branch_type(unsigned long from, unsigned long to, int abort)
  185. {
  186. return get_branch_type(from, to, abort, false, NULL);
  187. }
  188. int branch_type_fused(unsigned long from, unsigned long to, int abort,
  189. int *offset)
  190. {
  191. return get_branch_type(from, to, abort, true, offset);
  192. }
  193. #define X86_BR_TYPE_MAP_MAX 16
  194. static int branch_map[X86_BR_TYPE_MAP_MAX] = {
  195. PERF_BR_CALL, /* X86_BR_CALL */
  196. PERF_BR_RET, /* X86_BR_RET */
  197. PERF_BR_SYSCALL, /* X86_BR_SYSCALL */
  198. PERF_BR_SYSRET, /* X86_BR_SYSRET */
  199. PERF_BR_UNKNOWN, /* X86_BR_INT */
  200. PERF_BR_ERET, /* X86_BR_IRET */
  201. PERF_BR_COND, /* X86_BR_JCC */
  202. PERF_BR_UNCOND, /* X86_BR_JMP */
  203. PERF_BR_IRQ, /* X86_BR_IRQ */
  204. PERF_BR_IND_CALL, /* X86_BR_IND_CALL */
  205. PERF_BR_UNKNOWN, /* X86_BR_ABORT */
  206. PERF_BR_UNKNOWN, /* X86_BR_IN_TX */
  207. PERF_BR_NO_TX, /* X86_BR_NO_TX */
  208. PERF_BR_CALL, /* X86_BR_ZERO_CALL */
  209. PERF_BR_UNKNOWN, /* X86_BR_CALL_STACK */
  210. PERF_BR_IND, /* X86_BR_IND_JMP */
  211. };
  212. int common_branch_type(int type)
  213. {
  214. int i;
  215. type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */
  216. if (type) {
  217. i = __ffs(type);
  218. if (i < X86_BR_TYPE_MAP_MAX)
  219. return branch_map[i];
  220. }
  221. return PERF_BR_UNKNOWN;
  222. }