12ee0d7fdSJean Pihet #include <linux/errno.h> 22ee0d7fdSJean Pihet #include <linux/kernel.h> 32ee0d7fdSJean Pihet #include <linux/perf_event.h> 42ee0d7fdSJean Pihet #include <linux/bug.h> 5*ff268ff7SMark Salter 6*ff268ff7SMark Salter #include <asm/compat.h> 72ee0d7fdSJean Pihet #include <asm/perf_regs.h> 82ee0d7fdSJean Pihet #include <asm/ptrace.h> 92ee0d7fdSJean Pihet 102ee0d7fdSJean Pihet u64 perf_reg_value(struct pt_regs *regs, int idx) 112ee0d7fdSJean Pihet { 122ee0d7fdSJean Pihet if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX)) 132ee0d7fdSJean Pihet return 0; 142ee0d7fdSJean Pihet 152ee0d7fdSJean Pihet /* 162ee0d7fdSJean Pihet * Compat (i.e. 32 bit) mode: 172ee0d7fdSJean Pihet * - PC has been set in the pt_regs struct in kernel_entry, 182ee0d7fdSJean Pihet * - Handle SP and LR here. 192ee0d7fdSJean Pihet */ 202ee0d7fdSJean Pihet if (compat_user_mode(regs)) { 212ee0d7fdSJean Pihet if ((u32)idx == PERF_REG_ARM64_SP) 222ee0d7fdSJean Pihet return regs->compat_sp; 232ee0d7fdSJean Pihet if ((u32)idx == PERF_REG_ARM64_LR) 242ee0d7fdSJean Pihet return regs->compat_lr; 252ee0d7fdSJean Pihet } 262ee0d7fdSJean Pihet 272ee0d7fdSJean Pihet return regs->regs[idx]; 282ee0d7fdSJean Pihet } 292ee0d7fdSJean Pihet 302ee0d7fdSJean Pihet #define REG_RESERVED (~((1ULL << PERF_REG_ARM64_MAX) - 1)) 312ee0d7fdSJean Pihet 322ee0d7fdSJean Pihet int perf_reg_validate(u64 mask) 332ee0d7fdSJean Pihet { 342ee0d7fdSJean Pihet if (!mask || mask & REG_RESERVED) 352ee0d7fdSJean Pihet return -EINVAL; 362ee0d7fdSJean Pihet 372ee0d7fdSJean Pihet return 0; 382ee0d7fdSJean Pihet } 392ee0d7fdSJean Pihet 402ee0d7fdSJean Pihet u64 perf_reg_abi(struct task_struct *task) 412ee0d7fdSJean Pihet { 422ee0d7fdSJean Pihet if (is_compat_thread(task_thread_info(task))) 432ee0d7fdSJean Pihet return PERF_SAMPLE_REGS_ABI_32; 442ee0d7fdSJean Pihet else 452ee0d7fdSJean Pihet return PERF_SAMPLE_REGS_ABI_64; 462ee0d7fdSJean Pihet } 47