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