perf_regs.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include <linux/errno.h>
  2. #include <linux/kernel.h>
  3. #include <linux/bug.h>
  4. #include <linux/stddef.h>
  5. #include <asm/perf_regs.h>
  6. #include <asm/ptrace.h>
  7. #ifdef CONFIG_X86_32
  8. #define PERF_REG_X86_MAX PERF_REG_X86_32_MAX
  9. #else
  10. #define PERF_REG_X86_MAX PERF_REG_X86_64_MAX
  11. #endif
  12. #define PT_REGS_OFFSET(id, r) [id] = offsetof(struct pt_regs, r)
  13. static unsigned int pt_regs_offset[PERF_REG_X86_MAX] = {
  14. PT_REGS_OFFSET(PERF_REG_X86_AX, ax),
  15. PT_REGS_OFFSET(PERF_REG_X86_BX, bx),
  16. PT_REGS_OFFSET(PERF_REG_X86_CX, cx),
  17. PT_REGS_OFFSET(PERF_REG_X86_DX, dx),
  18. PT_REGS_OFFSET(PERF_REG_X86_SI, si),
  19. PT_REGS_OFFSET(PERF_REG_X86_DI, di),
  20. PT_REGS_OFFSET(PERF_REG_X86_BP, bp),
  21. PT_REGS_OFFSET(PERF_REG_X86_SP, sp),
  22. PT_REGS_OFFSET(PERF_REG_X86_IP, ip),
  23. PT_REGS_OFFSET(PERF_REG_X86_FLAGS, flags),
  24. PT_REGS_OFFSET(PERF_REG_X86_CS, cs),
  25. PT_REGS_OFFSET(PERF_REG_X86_SS, ss),
  26. #ifdef CONFIG_X86_32
  27. PT_REGS_OFFSET(PERF_REG_X86_DS, ds),
  28. PT_REGS_OFFSET(PERF_REG_X86_ES, es),
  29. PT_REGS_OFFSET(PERF_REG_X86_FS, fs),
  30. PT_REGS_OFFSET(PERF_REG_X86_GS, gs),
  31. #else
  32. /*
  33. * The pt_regs struct does not store
  34. * ds, es, fs, gs in 64 bit mode.
  35. */
  36. (unsigned int) -1,
  37. (unsigned int) -1,
  38. (unsigned int) -1,
  39. (unsigned int) -1,
  40. #endif
  41. #ifdef CONFIG_X86_64
  42. PT_REGS_OFFSET(PERF_REG_X86_R8, r8),
  43. PT_REGS_OFFSET(PERF_REG_X86_R9, r9),
  44. PT_REGS_OFFSET(PERF_REG_X86_R10, r10),
  45. PT_REGS_OFFSET(PERF_REG_X86_R11, r11),
  46. PT_REGS_OFFSET(PERF_REG_X86_R12, r12),
  47. PT_REGS_OFFSET(PERF_REG_X86_R13, r13),
  48. PT_REGS_OFFSET(PERF_REG_X86_R14, r14),
  49. PT_REGS_OFFSET(PERF_REG_X86_R15, r15),
  50. #endif
  51. };
  52. u64 perf_reg_value(struct pt_regs *regs, int idx)
  53. {
  54. if (WARN_ON_ONCE(idx > ARRAY_SIZE(pt_regs_offset)))
  55. return 0;
  56. return regs_get_register(regs, pt_regs_offset[idx]);
  57. }
  58. #define REG_RESERVED (~((1ULL << PERF_REG_X86_MAX) - 1ULL))
  59. #ifdef CONFIG_X86_32
  60. int perf_reg_validate(u64 mask)
  61. {
  62. if (!mask || mask & REG_RESERVED)
  63. return -EINVAL;
  64. return 0;
  65. }
  66. #else /* CONFIG_X86_64 */
  67. #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
  68. (1ULL << PERF_REG_X86_ES) | \
  69. (1ULL << PERF_REG_X86_FS) | \
  70. (1ULL << PERF_REG_X86_GS))
  71. int perf_reg_validate(u64 mask)
  72. {
  73. if (!mask || mask & REG_RESERVED)
  74. return -EINVAL;
  75. if (mask & REG_NOSUPPORT)
  76. return -EINVAL;
  77. return 0;
  78. }
  79. #endif /* CONFIG_X86_32 */