| 1 | // SPDX-License-Identifier: GPL-2.0 | 
|---|
| 2 | #include <asm/insn.h> | 
|---|
| 3 | #include <linux/mm.h> | 
|---|
| 4 |  | 
|---|
| 5 | #include <asm/msr.h> | 
|---|
| 6 | #include "perf_event.h" | 
|---|
| 7 |  | 
|---|
| 8 | static int decode_branch_type(struct insn *insn) | 
|---|
| 9 | { | 
|---|
| 10 | int ext; | 
|---|
| 11 |  | 
|---|
| 12 | if (insn_get_opcode(insn)) | 
|---|
| 13 | return X86_BR_ABORT; | 
|---|
| 14 |  | 
|---|
| 15 | switch (insn->opcode.bytes[0]) { | 
|---|
| 16 | case 0xf: | 
|---|
| 17 | switch (insn->opcode.bytes[1]) { | 
|---|
| 18 | case 0x05: /* syscall */ | 
|---|
| 19 | case 0x34: /* sysenter */ | 
|---|
| 20 | return X86_BR_SYSCALL; | 
|---|
| 21 | case 0x07: /* sysret */ | 
|---|
| 22 | case 0x35: /* sysexit */ | 
|---|
| 23 | return X86_BR_SYSRET; | 
|---|
| 24 | case 0x80 ... 0x8f: /* conditional */ | 
|---|
| 25 | return X86_BR_JCC; | 
|---|
| 26 | } | 
|---|
| 27 | return X86_BR_NONE; | 
|---|
| 28 | case 0x70 ... 0x7f: /* conditional */ | 
|---|
| 29 | return X86_BR_JCC; | 
|---|
| 30 | case 0xc2: /* near ret */ | 
|---|
| 31 | case 0xc3: /* near ret */ | 
|---|
| 32 | case 0xca: /* far ret */ | 
|---|
| 33 | case 0xcb: /* far ret */ | 
|---|
| 34 | return X86_BR_RET; | 
|---|
| 35 | case 0xcf: /* iret */ | 
|---|
| 36 | return X86_BR_IRET; | 
|---|
| 37 | case 0xcc ... 0xce: /* int */ | 
|---|
| 38 | return X86_BR_INT; | 
|---|
| 39 | case 0xe8: /* call near rel */ | 
|---|
| 40 | if (insn_get_immediate(insn) || insn->immediate1.value == 0) { | 
|---|
| 41 | /* zero length call */ | 
|---|
| 42 | return X86_BR_ZERO_CALL; | 
|---|
| 43 | } | 
|---|
| 44 | fallthrough; | 
|---|
| 45 | case 0x9a: /* call far absolute */ | 
|---|
| 46 | return X86_BR_CALL; | 
|---|
| 47 | case 0xe0 ... 0xe3: /* loop jmp */ | 
|---|
| 48 | return X86_BR_JCC; | 
|---|
| 49 | case 0xe9 ... 0xeb: /* jmp */ | 
|---|
| 50 | return X86_BR_JMP; | 
|---|
| 51 | case 0xff: /* call near absolute, call far absolute ind */ | 
|---|
| 52 | if (insn_get_modrm(insn)) | 
|---|
| 53 | return X86_BR_ABORT; | 
|---|
| 54 |  | 
|---|
| 55 | ext = (insn->modrm.bytes[0] >> 3) & 0x7; | 
|---|
| 56 | switch (ext) { | 
|---|
| 57 | case 2: /* near ind call */ | 
|---|
| 58 | case 3: /* far ind call */ | 
|---|
| 59 | return X86_BR_IND_CALL; | 
|---|
| 60 | case 4: | 
|---|
| 61 | case 5: | 
|---|
| 62 | return X86_BR_IND_JMP; | 
|---|
| 63 | } | 
|---|
| 64 | return X86_BR_NONE; | 
|---|
| 65 | } | 
|---|
| 66 |  | 
|---|
| 67 | return X86_BR_NONE; | 
|---|
| 68 | } | 
|---|
| 69 |  | 
|---|
| 70 | /* | 
|---|
| 71 | * return the type of control flow change at address "from" | 
|---|
| 72 | * instruction is not necessarily a branch (in case of interrupt). | 
|---|
| 73 | * | 
|---|
| 74 | * The branch type returned also includes the priv level of the | 
|---|
| 75 | * target of the control flow change (X86_BR_USER, X86_BR_KERNEL). | 
|---|
| 76 | * | 
|---|
| 77 | * If a branch type is unknown OR the instruction cannot be | 
|---|
| 78 | * decoded (e.g., text page not present), then X86_BR_NONE is | 
|---|
| 79 | * returned. | 
|---|
| 80 | * | 
|---|
| 81 | * While recording branches, some processors can report the "from" | 
|---|
| 82 | * address to be that of an instruction preceding the actual branch | 
|---|
| 83 | * when instruction fusion occurs. If fusion is expected, attempt to | 
|---|
| 84 | * find the type of the first branch instruction within the next | 
|---|
| 85 | * MAX_INSN_SIZE bytes and if found, provide the offset between the | 
|---|
| 86 | * reported "from" address and the actual branch instruction address. | 
|---|
| 87 | */ | 
|---|
| 88 | static int get_branch_type(unsigned long from, unsigned long to, int abort, | 
|---|
| 89 | bool fused, int *offset) | 
|---|
| 90 | { | 
|---|
| 91 | struct insn insn; | 
|---|
| 92 | void *addr; | 
|---|
| 93 | int bytes_read, bytes_left, insn_offset; | 
|---|
| 94 | int ret = X86_BR_NONE; | 
|---|
| 95 | int to_plm, from_plm; | 
|---|
| 96 | u8 buf[MAX_INSN_SIZE]; | 
|---|
| 97 | int is64 = 0; | 
|---|
| 98 |  | 
|---|
| 99 | /* make sure we initialize offset */ | 
|---|
| 100 | if (offset) | 
|---|
| 101 | *offset = 0; | 
|---|
| 102 |  | 
|---|
| 103 | to_plm = kernel_ip(ip: to) ? X86_BR_KERNEL : X86_BR_USER; | 
|---|
| 104 | from_plm = kernel_ip(ip: from) ? X86_BR_KERNEL : X86_BR_USER; | 
|---|
| 105 |  | 
|---|
| 106 | /* | 
|---|
| 107 | * maybe zero if lbr did not fill up after a reset by the time | 
|---|
| 108 | * we get a PMU interrupt | 
|---|
| 109 | */ | 
|---|
| 110 | if (from == 0 || to == 0) | 
|---|
| 111 | return X86_BR_NONE; | 
|---|
| 112 |  | 
|---|
| 113 | if (abort) | 
|---|
| 114 | return X86_BR_ABORT | to_plm; | 
|---|
| 115 |  | 
|---|
| 116 | if (from_plm == X86_BR_USER) { | 
|---|
| 117 | /* | 
|---|
| 118 | * can happen if measuring at the user level only | 
|---|
| 119 | * and we interrupt in a kernel thread, e.g., idle. | 
|---|
| 120 | */ | 
|---|
| 121 | if (!current->mm) | 
|---|
| 122 | return X86_BR_NONE; | 
|---|
| 123 |  | 
|---|
| 124 | /* may fail if text not present */ | 
|---|
| 125 | bytes_left = copy_from_user_nmi(to: buf, from: (void __user *)from, | 
|---|
| 126 | MAX_INSN_SIZE); | 
|---|
| 127 | bytes_read = MAX_INSN_SIZE - bytes_left; | 
|---|
| 128 | if (!bytes_read) | 
|---|
| 129 | return X86_BR_NONE; | 
|---|
| 130 |  | 
|---|
| 131 | addr = buf; | 
|---|
| 132 | } else { | 
|---|
| 133 | /* | 
|---|
| 134 | * The LBR logs any address in the IP, even if the IP just | 
|---|
| 135 | * faulted. This means userspace can control the from address. | 
|---|
| 136 | * Ensure we don't blindly read any address by validating it is | 
|---|
| 137 | * a known text address and not a vsyscall address. | 
|---|
| 138 | */ | 
|---|
| 139 | if (kernel_text_address(addr: from) && !in_gate_area_no_mm(addr: from)) { | 
|---|
| 140 | addr = (void *)from; | 
|---|
| 141 | /* | 
|---|
| 142 | * Assume we can get the maximum possible size | 
|---|
| 143 | * when grabbing kernel data.  This is not | 
|---|
| 144 | * _strictly_ true since we could possibly be | 
|---|
| 145 | * executing up next to a memory hole, but | 
|---|
| 146 | * it is very unlikely to be a problem. | 
|---|
| 147 | */ | 
|---|
| 148 | bytes_read = MAX_INSN_SIZE; | 
|---|
| 149 | } else { | 
|---|
| 150 | return X86_BR_NONE; | 
|---|
| 151 | } | 
|---|
| 152 | } | 
|---|
| 153 |  | 
|---|
| 154 | /* | 
|---|
| 155 | * decoder needs to know the ABI especially | 
|---|
| 156 | * on 64-bit systems running 32-bit apps | 
|---|
| 157 | */ | 
|---|
| 158 | #ifdef CONFIG_X86_64 | 
|---|
| 159 | is64 = kernel_ip(ip: (unsigned long)addr) || any_64bit_mode(current_pt_regs()); | 
|---|
| 160 | #endif | 
|---|
| 161 | insn_init(insn: &insn, kaddr: addr, buf_len: bytes_read, x86_64: is64); | 
|---|
| 162 | ret = decode_branch_type(insn: &insn); | 
|---|
| 163 | insn_offset = 0; | 
|---|
| 164 |  | 
|---|
| 165 | /* Check for the possibility of branch fusion */ | 
|---|
| 166 | while (fused && ret == X86_BR_NONE) { | 
|---|
| 167 | /* Check for decoding errors */ | 
|---|
| 168 | if (insn_get_length(insn: &insn) || !insn.length) | 
|---|
| 169 | break; | 
|---|
| 170 |  | 
|---|
| 171 | insn_offset += insn.length; | 
|---|
| 172 | bytes_read -= insn.length; | 
|---|
| 173 | if (bytes_read < 0) | 
|---|
| 174 | break; | 
|---|
| 175 |  | 
|---|
| 176 | insn_init(insn: &insn, kaddr: addr + insn_offset, buf_len: bytes_read, x86_64: is64); | 
|---|
| 177 | ret = decode_branch_type(insn: &insn); | 
|---|
| 178 | } | 
|---|
| 179 |  | 
|---|
| 180 | if (offset) | 
|---|
| 181 | *offset = insn_offset; | 
|---|
| 182 |  | 
|---|
| 183 | /* | 
|---|
| 184 | * interrupts, traps, faults (and thus ring transition) may | 
|---|
| 185 | * occur on any instructions. Thus, to classify them correctly, | 
|---|
| 186 | * we need to first look at the from and to priv levels. If they | 
|---|
| 187 | * are different and to is in the kernel, then it indicates | 
|---|
| 188 | * a ring transition. If the from instruction is not a ring | 
|---|
| 189 | * transition instr (syscall, systenter, int), then it means | 
|---|
| 190 | * it was a irq, trap or fault. | 
|---|
| 191 | * | 
|---|
| 192 | * we have no way of detecting kernel to kernel faults. | 
|---|
| 193 | */ | 
|---|
| 194 | if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL | 
|---|
| 195 | && ret != X86_BR_SYSCALL && ret != X86_BR_INT) | 
|---|
| 196 | ret = X86_BR_IRQ; | 
|---|
| 197 |  | 
|---|
| 198 | /* | 
|---|
| 199 | * branch priv level determined by target as | 
|---|
| 200 | * is done by HW when LBR_SELECT is implemented | 
|---|
| 201 | */ | 
|---|
| 202 | if (ret != X86_BR_NONE) | 
|---|
| 203 | ret |= to_plm; | 
|---|
| 204 |  | 
|---|
| 205 | return ret; | 
|---|
| 206 | } | 
|---|
| 207 |  | 
|---|
| 208 | int branch_type(unsigned long from, unsigned long to, int abort) | 
|---|
| 209 | { | 
|---|
| 210 | return get_branch_type(from, to, abort, fused: false, NULL); | 
|---|
| 211 | } | 
|---|
| 212 |  | 
|---|
| 213 | int branch_type_fused(unsigned long from, unsigned long to, int abort, | 
|---|
| 214 | int *offset) | 
|---|
| 215 | { | 
|---|
| 216 | return get_branch_type(from, to, abort, fused: true, offset); | 
|---|
| 217 | } | 
|---|
| 218 |  | 
|---|
| 219 | #define X86_BR_TYPE_MAP_MAX	16 | 
|---|
| 220 |  | 
|---|
| 221 | static int branch_map[X86_BR_TYPE_MAP_MAX] = { | 
|---|
| 222 | PERF_BR_CALL,		/* X86_BR_CALL */ | 
|---|
| 223 | PERF_BR_RET,		/* X86_BR_RET */ | 
|---|
| 224 | PERF_BR_SYSCALL,	/* X86_BR_SYSCALL */ | 
|---|
| 225 | PERF_BR_SYSRET,		/* X86_BR_SYSRET */ | 
|---|
| 226 | PERF_BR_UNKNOWN,	/* X86_BR_INT */ | 
|---|
| 227 | PERF_BR_ERET,		/* X86_BR_IRET */ | 
|---|
| 228 | PERF_BR_COND,		/* X86_BR_JCC */ | 
|---|
| 229 | PERF_BR_UNCOND,		/* X86_BR_JMP */ | 
|---|
| 230 | PERF_BR_IRQ,		/* X86_BR_IRQ */ | 
|---|
| 231 | PERF_BR_IND_CALL,	/* X86_BR_IND_CALL */ | 
|---|
| 232 | PERF_BR_UNKNOWN,	/* X86_BR_ABORT */ | 
|---|
| 233 | PERF_BR_UNKNOWN,	/* X86_BR_IN_TX */ | 
|---|
| 234 | PERF_BR_NO_TX,		/* X86_BR_NO_TX */ | 
|---|
| 235 | PERF_BR_CALL,		/* X86_BR_ZERO_CALL */ | 
|---|
| 236 | PERF_BR_UNKNOWN,	/* X86_BR_CALL_STACK */ | 
|---|
| 237 | PERF_BR_IND,		/* X86_BR_IND_JMP */ | 
|---|
| 238 | }; | 
|---|
| 239 |  | 
|---|
| 240 | int common_branch_type(int type) | 
|---|
| 241 | { | 
|---|
| 242 | int i; | 
|---|
| 243 |  | 
|---|
| 244 | type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */ | 
|---|
| 245 |  | 
|---|
| 246 | if (type) { | 
|---|
| 247 | i = __ffs(type); | 
|---|
| 248 | if (i < X86_BR_TYPE_MAP_MAX) | 
|---|
| 249 | return branch_map[i]; | 
|---|
| 250 | } | 
|---|
| 251 |  | 
|---|
| 252 | return PERF_BR_UNKNOWN; | 
|---|
| 253 | } | 
|---|
| 254 |  | 
|---|