perf_regs.c 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include <linux/errno.h>
  2. #include <linux/kernel.h>
  3. #include <linux/perf_event.h>
  4. #include <linux/bug.h>
  5. #include <asm/compat.h>
  6. #include <asm/perf_regs.h>
  7. #include <asm/ptrace.h>
  8. u64 perf_reg_value(struct pt_regs *regs, int idx)
  9. {
  10. if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
  11. return 0;
  12. /*
  13. * Compat (i.e. 32 bit) mode:
  14. * - PC has been set in the pt_regs struct in kernel_entry,
  15. * - Handle SP and LR here.
  16. */
  17. if (compat_user_mode(regs)) {
  18. if ((u32)idx == PERF_REG_ARM64_SP)
  19. return regs->compat_sp;
  20. if ((u32)idx == PERF_REG_ARM64_LR)
  21. return regs->compat_lr;
  22. }
  23. if ((u32)idx == PERF_REG_ARM64_SP)
  24. return regs->sp;
  25. if ((u32)idx == PERF_REG_ARM64_PC)
  26. return regs->pc;
  27. return regs->regs[idx];
  28. }
  29. #define REG_RESERVED (~((1ULL << PERF_REG_ARM64_MAX) - 1))
  30. int perf_reg_validate(u64 mask)
  31. {
  32. if (!mask || mask & REG_RESERVED)
  33. return -EINVAL;
  34. return 0;
  35. }
  36. u64 perf_reg_abi(struct task_struct *task)
  37. {
  38. if (is_compat_thread(task_thread_info(task)))
  39. return PERF_SAMPLE_REGS_ABI_32;
  40. else
  41. return PERF_SAMPLE_REGS_ABI_64;
  42. }
  43. void perf_get_regs_user(struct perf_regs *regs_user,
  44. struct pt_regs *regs,
  45. struct pt_regs *regs_user_copy)
  46. {
  47. regs_user->regs = task_pt_regs(current);
  48. regs_user->abi = perf_reg_abi(current);
  49. }