^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/perf_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #ifdef CONFIG_X86_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define PERF_REG_X86_MAX PERF_REG_X86_32_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define PERF_REG_X86_MAX PERF_REG_X86_64_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define PT_REGS_OFFSET(id, r) [id] = offsetof(struct pt_regs, r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static unsigned int pt_regs_offset[PERF_REG_X86_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) PT_REGS_OFFSET(PERF_REG_X86_AX, ax),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) PT_REGS_OFFSET(PERF_REG_X86_BX, bx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) PT_REGS_OFFSET(PERF_REG_X86_CX, cx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) PT_REGS_OFFSET(PERF_REG_X86_DX, dx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) PT_REGS_OFFSET(PERF_REG_X86_SI, si),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) PT_REGS_OFFSET(PERF_REG_X86_DI, di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) PT_REGS_OFFSET(PERF_REG_X86_BP, bp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) PT_REGS_OFFSET(PERF_REG_X86_SP, sp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) PT_REGS_OFFSET(PERF_REG_X86_IP, ip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) PT_REGS_OFFSET(PERF_REG_X86_FLAGS, flags),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) PT_REGS_OFFSET(PERF_REG_X86_CS, cs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) PT_REGS_OFFSET(PERF_REG_X86_SS, ss),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #ifdef CONFIG_X86_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) PT_REGS_OFFSET(PERF_REG_X86_DS, ds),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) PT_REGS_OFFSET(PERF_REG_X86_ES, es),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) PT_REGS_OFFSET(PERF_REG_X86_FS, fs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) PT_REGS_OFFSET(PERF_REG_X86_GS, gs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * The pt_regs struct does not store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * ds, es, fs, gs in 64 bit mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) (unsigned int) -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) (unsigned int) -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) (unsigned int) -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) (unsigned int) -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) PT_REGS_OFFSET(PERF_REG_X86_R8, r8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) PT_REGS_OFFSET(PERF_REG_X86_R9, r9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) PT_REGS_OFFSET(PERF_REG_X86_R10, r10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) PT_REGS_OFFSET(PERF_REG_X86_R11, r11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) PT_REGS_OFFSET(PERF_REG_X86_R12, r12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) PT_REGS_OFFSET(PERF_REG_X86_R13, r13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) PT_REGS_OFFSET(PERF_REG_X86_R14, r14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) PT_REGS_OFFSET(PERF_REG_X86_R15, r15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u64 perf_reg_value(struct pt_regs *regs, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct x86_perf_regs *perf_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (idx >= PERF_REG_X86_XMM0 && idx < PERF_REG_X86_XMM_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) perf_regs = container_of(regs, struct x86_perf_regs, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (!perf_regs->xmm_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return perf_regs->xmm_regs[idx - PERF_REG_X86_XMM0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (WARN_ON_ONCE(idx >= ARRAY_SIZE(pt_regs_offset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return regs_get_register(regs, pt_regs_offset[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define PERF_REG_X86_RESERVED (((1ULL << PERF_REG_X86_XMM0) - 1) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ~((1ULL << PERF_REG_X86_MAX) - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #ifdef CONFIG_X86_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_R8) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) (1ULL << PERF_REG_X86_R9) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) (1ULL << PERF_REG_X86_R10) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) (1ULL << PERF_REG_X86_R11) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) (1ULL << PERF_REG_X86_R12) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) (1ULL << PERF_REG_X86_R13) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) (1ULL << PERF_REG_X86_R14) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) (1ULL << PERF_REG_X86_R15))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int perf_reg_validate(u64 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!mask || (mask & (REG_NOSUPPORT | PERF_REG_X86_RESERVED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u64 perf_reg_abi(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return PERF_SAMPLE_REGS_ABI_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void perf_get_regs_user(struct perf_regs *regs_user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) regs_user->regs = task_pt_regs(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) regs_user->abi = perf_reg_abi(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #else /* CONFIG_X86_64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) (1ULL << PERF_REG_X86_ES) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) (1ULL << PERF_REG_X86_FS) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) (1ULL << PERF_REG_X86_GS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int perf_reg_validate(u64 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (!mask || (mask & (REG_NOSUPPORT | PERF_REG_X86_RESERVED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u64 perf_reg_abi(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (test_tsk_thread_flag(task, TIF_IA32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return PERF_SAMPLE_REGS_ABI_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return PERF_SAMPLE_REGS_ABI_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static DEFINE_PER_CPU(struct pt_regs, nmi_user_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) void perf_get_regs_user(struct perf_regs *regs_user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct pt_regs *regs_user_copy = this_cpu_ptr(&nmi_user_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct pt_regs *user_regs = task_pt_regs(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (!in_nmi()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) regs_user->regs = user_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) regs_user->abi = perf_reg_abi(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * If we're in an NMI that interrupted task_pt_regs setup, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * we can't sample user regs at all. This check isn't really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * sufficient, though, as we could be in an NMI inside an interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * that happened during task_pt_regs setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (regs->sp > (unsigned long)&user_regs->r11 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) regs->sp <= (unsigned long)(user_regs + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) regs_user->regs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * These registers are always saved on 64-bit syscall entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * On 32-bit entry points, they are saved too except r8..r11.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) regs_user_copy->ip = user_regs->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) regs_user_copy->ax = user_regs->ax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) regs_user_copy->cx = user_regs->cx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) regs_user_copy->dx = user_regs->dx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) regs_user_copy->si = user_regs->si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) regs_user_copy->di = user_regs->di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) regs_user_copy->r8 = user_regs->r8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) regs_user_copy->r9 = user_regs->r9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) regs_user_copy->r10 = user_regs->r10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) regs_user_copy->r11 = user_regs->r11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) regs_user_copy->orig_ax = user_regs->orig_ax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) regs_user_copy->flags = user_regs->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) regs_user_copy->sp = user_regs->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) regs_user_copy->cs = user_regs->cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) regs_user_copy->ss = user_regs->ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * Store user space frame-pointer value on sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * to facilitate stack unwinding for cases when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * user space executable code has such support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * enabled at compile time:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) regs_user_copy->bp = user_regs->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) regs_user_copy->bx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) regs_user_copy->r12 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) regs_user_copy->r13 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) regs_user_copy->r14 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) regs_user_copy->r15 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * For this to be at all useful, we need a reasonable guess for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * the ABI. Be careful: we're in NMI context, and we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * considering current to be the current task, so we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * be careful not to look at any other percpu variables that might
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * change during context switches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) regs_user->abi = user_64bit_mode(user_regs) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) PERF_SAMPLE_REGS_ABI_64 : PERF_SAMPLE_REGS_ABI_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) regs_user->regs = regs_user_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #endif /* CONFIG_X86_32 */