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