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
8static 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 */
88static 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
208int branch_type(unsigned long from, unsigned long to, int abort)
209{
210 return get_branch_type(from, to, abort, fused: false, NULL);
211}
212
213int 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
221static 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
240int 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