xref: /freebsd/sys/dev/hwpmc/hwpmc_x86.c (revision 1669d8afc64812c8d2d1d147ae1fd42ff441e1b1)
1 /*-
2  * Copyright (c) 2005, Joseph Koshy
3  * Copyright (c) 2007 The FreeBSD Foundation
4  * All rights reserved.
5  *
6  * Portions of this software were developed by A. Joseph Koshy under
7  * sponsorship from the FreeBSD Foundation and Google, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <sys/param.h>
35 #include <sys/bus.h>
36 #include <sys/pmc.h>
37 #include <sys/proc.h>
38 #include <sys/systm.h>
39 
40 #include <machine/cpu.h>
41 #include <machine/apicreg.h>
42 #include <machine/pmc_mdep.h>
43 #include <machine/md_var.h>
44 
45 #include <vm/vm.h>
46 #include <vm/vm_param.h>
47 #include <vm/pmap.h>
48 
49 extern volatile lapic_t *lapic;
50 
51 void
52 pmc_x86_lapic_enable_pmc_interrupt(void)
53 {
54 	uint32_t value;
55 
56 	value =  lapic->lvt_pcint;
57 	value &= ~APIC_LVT_M;
58 	lapic->lvt_pcint = value;
59 }
60 
61 /*
62  * Attempt to walk a user call stack using a too-simple algorithm.
63  * In the general case we need unwind information associated with
64  * the executable to be able to walk the user stack.
65  *
66  * We are handed a trap frame laid down at the time the PMC interrupt
67  * was taken.  If the application is using frame pointers, the saved
68  * PC value could be:
69  * a. at the beginning of a function before the stack frame is laid
70  *    down,
71  * b. just before a 'ret', after the stack frame has been taken off,
72  * c. somewhere else in the function with a valid stack frame being
73  *    present,
74  *
75  * If the application is not using frame pointers, this algorithm will
76  * fail to yield an interesting call chain.
77  *
78  * TODO: figure out a way to use unwind information.
79  */
80 
81 int
82 pmc_save_user_callchain(uintptr_t *cc, int nframes, struct trapframe *tf)
83 {
84 	int n;
85 	uint32_t instr;
86 	uintptr_t fp, oldfp, pc, r, sp;
87 
88 	KASSERT(TRAPF_USERMODE(tf), ("[x86,%d] Not a user trap frame tf=%p",
89 	    __LINE__, (void *) tf));
90 
91 	pc = PMC_TRAPFRAME_TO_PC(tf);
92 	oldfp = fp = PMC_TRAPFRAME_TO_FP(tf);
93 	sp = PMC_TRAPFRAME_TO_SP(tf);
94 
95 	*cc++ = pc; n = 1;
96 
97 	r = fp + sizeof(uintptr_t); /* points to return address */
98 
99 	if (!PMC_IN_USERSPACE(pc))
100 		return (n);
101 
102 	if (copyin((void *) pc, &instr, sizeof(instr)) != 0)
103 		return (n);
104 
105 	if (PMC_AT_FUNCTION_PROLOGUE_PUSH_BP(instr) ||
106 	    PMC_AT_FUNCTION_EPILOGUE_RET(instr)) { /* ret */
107 		if (copyin((void *) sp, &pc, sizeof(pc)) != 0)
108 			return (n);
109 	} else if (PMC_AT_FUNCTION_PROLOGUE_MOV_SP_BP(instr)) {
110 		sp += sizeof(uintptr_t);
111 		if (copyin((void *) sp, &pc, sizeof(pc)) != 0)
112 			return (n);
113 	} else if (copyin((void *) r, &pc, sizeof(pc)) != 0 ||
114 	    copyin((void *) fp, &fp, sizeof(fp) != 0))
115 		return (n);
116 
117 	for (; n < nframes;) {
118 		if (pc == 0 || !PMC_IN_USERSPACE(pc))
119 			break;
120 
121 		*cc++ = pc; n++;
122 
123 		if (fp < oldfp)
124 			break;
125 
126 		r = fp + sizeof(uintptr_t); /* address of return address */
127 		oldfp = fp;
128 
129 		if (copyin((void *) r, &pc, sizeof(pc)) != 0 ||
130 		    copyin((void *) fp, &fp, sizeof(fp)) != 0)
131 			break;
132 	}
133 
134 	return (n);
135 }
136 
137 /*
138  * Walking the kernel call stack.
139  *
140  * We are handed the trap frame laid down at the time the PMC
141  * interrupt was taken.  The saved PC could be:
142  * a. in the lowlevel trap handler, meaning that there isn't a C stack
143  *    to traverse,
144  * b. at the beginning of a function before the stack frame is laid
145  *    down,
146  * c. just before a 'ret', after the stack frame has been taken off,
147  * d. somewhere else in a function with a valid stack frame being
148  *    present.
149  *
150  * In case (d), the previous frame pointer is at [%ebp]/[%rbp] and
151  * the return address is at [%ebp+4]/[%rbp+8].
152  *
153  * For cases (b) and (c), the return address is at [%esp]/[%rsp] and
154  * the frame pointer doesn't need to be changed when going up one
155  * level in the stack.
156  *
157  * For case (a), we check if the PC lies in low-level trap handling
158  * code, and if so we terminate our trace.
159  */
160 
161 int
162 pmc_save_kernel_callchain(uintptr_t *cc, int nframes, struct trapframe *tf)
163 {
164 	int n;
165 	uint32_t instr;
166 	uintptr_t fp, pc, r, sp, stackstart, stackend;
167 	struct thread *td;
168 
169 	KASSERT(TRAPF_USERMODE(tf) == 0,("[x86,%d] not a kernel backtrace",
170 	    __LINE__));
171 
172 	pc = PMC_TRAPFRAME_TO_PC(tf);
173 	fp = PMC_TRAPFRAME_TO_FP(tf);
174 	sp = PMC_TRAPFRAME_TO_SP(tf);
175 
176 	*cc++ = pc;
177 	r = fp + sizeof(uintptr_t); /* points to return address */
178 
179 	if ((td = curthread) == NULL)
180 		return (1);
181 
182 	if (nframes <= 1)
183 		return (1);
184 
185 	stackstart = (uintptr_t) td->td_kstack;
186 	stackend = (uintptr_t) td->td_kstack + td->td_kstack_pages * PAGE_SIZE;
187 
188 	if (PMC_IN_TRAP_HANDLER(pc) ||
189 	    !PMC_IN_KERNEL(pc) || !PMC_IN_KERNEL(r) ||
190 	    !PMC_IN_KERNEL_STACK(sp, stackstart, stackend) ||
191 	    !PMC_IN_KERNEL_STACK(fp, stackstart, stackend))
192 		return (1);
193 
194 	instr = *(uint32_t *) pc;
195 
196 	/*
197 	 * Determine whether the interrupted function was in the
198 	 * processing of either laying down its stack frame or taking
199 	 * it off.
200 	 *
201 	 * If we haven't started laying down a stack frame, or are
202 	 * just about to return, then our caller's address is at
203 	 * *sp, and we don't have a frame to unwind.
204 	 */
205 	if (PMC_AT_FUNCTION_PROLOGUE_PUSH_BP(instr) ||
206 	    PMC_AT_FUNCTION_EPILOGUE_RET(instr))
207 		pc = *(uintptr_t *) sp;
208 	else if (PMC_AT_FUNCTION_PROLOGUE_MOV_SP_BP(instr)) {
209 		/*
210 		 * The code was midway through laying down a frame.
211 		 * At this point sp[0] has a frame back pointer,
212 		 * and the caller's address is therefore at sp[1].
213 		 */
214 		sp += sizeof(uintptr_t);
215 		if (!PMC_IN_KERNEL_STACK(sp, stackstart, stackend))
216 			return (1);
217 		pc = *(uintptr_t *) sp;
218 	} else {
219 		/*
220 		 * Not in the function prologue or epilogue.
221 		 */
222 		pc = *(uintptr_t *) r;
223 		fp = *(uintptr_t *) fp;
224 	}
225 
226 	for (n = 1; n < nframes; n++) {
227 		*cc++ = pc;
228 
229 		if (PMC_IN_TRAP_HANDLER(pc))
230 			break;
231 
232 		r = fp + sizeof(uintptr_t);
233 		if (!PMC_IN_KERNEL_STACK(fp, stackstart, stackend) ||
234 		    !PMC_IN_KERNEL(r))
235 			break;
236 		pc = *(uintptr_t *) r;
237 		fp = *(uintptr_t *) fp;
238 	}
239 
240 	return (n);
241 }
242 
243 static struct pmc_mdep *
244 pmc_intel_initialize(void)
245 {
246 	struct pmc_mdep *pmc_mdep;
247 	enum pmc_cputype cputype;
248 	int error, model;
249 
250 	KASSERT(strcmp(cpu_vendor, "GenuineIntel") == 0,
251 	    ("[intel,%d] Initializing non-intel processor", __LINE__));
252 
253 	PMCDBG(MDP,INI,0, "intel-initialize cpuid=0x%x", cpu_id);
254 
255 	cputype = -1;
256 
257 	switch (cpu_id & 0xF00) {
258 #if	defined(__i386__)
259 	case 0x500:		/* Pentium family processors */
260 		cputype = PMC_CPU_INTEL_P5;
261 		break;
262 	case 0x600:		/* Pentium Pro, Celeron, Pentium II & III */
263 		switch ((cpu_id & 0xF0) >> 4) { /* model number field */
264 		case 0x1:
265 			cputype = PMC_CPU_INTEL_P6;
266 			break;
267 		case 0x3: case 0x5:
268 			cputype = PMC_CPU_INTEL_PII;
269 			break;
270 		case 0x6:
271 			cputype = PMC_CPU_INTEL_CL;
272 			break;
273 		case 0x7: case 0x8: case 0xA: case 0xB:
274 			cputype = PMC_CPU_INTEL_PIII;
275 			break;
276 		case 0x9: case 0xD:
277 			cputype = PMC_CPU_INTEL_PM;
278 			break;
279 		}
280 		break;
281 #endif
282 #if	defined(__i386__) || defined(__amd64__)
283 	case 0xF00:		/* P4 */
284 		model = ((cpu_id & 0xF0000) >> 12) | ((cpu_id & 0xF0) >> 4);
285 		if (model >= 0 && model <= 6) /* known models */
286 			cputype = PMC_CPU_INTEL_PIV;
287 		break;
288 	}
289 #endif
290 
291 	if ((int) cputype == -1) {
292 		printf("pmc: Unknown Intel CPU.\n");
293 		return NULL;
294 	}
295 
296 	MALLOC(pmc_mdep, struct pmc_mdep *, sizeof(struct pmc_mdep),
297 	    M_PMC, M_WAITOK|M_ZERO);
298 
299 	pmc_mdep->pmd_cputype 	    = cputype;
300 	pmc_mdep->pmd_nclass	    = 2;
301 	pmc_mdep->pmd_classes[0].pm_class    = PMC_CLASS_TSC;
302 	pmc_mdep->pmd_classes[0].pm_caps     = PMC_CAP_READ;
303 	pmc_mdep->pmd_classes[0].pm_width    = 64;
304 	pmc_mdep->pmd_nclasspmcs[0] = 1;
305 
306 	error = 0;
307 
308 	switch (cputype) {
309 
310 #if	defined(__i386__) || defined(__amd64__)
311 
312 		/*
313 		 * Intel Pentium 4 Processors, and P4/EMT64 processors.
314 		 */
315 
316 	case PMC_CPU_INTEL_PIV:
317 		error = pmc_initialize_p4(pmc_mdep);
318 		break;
319 #endif
320 
321 #if	defined(__i386__)
322 		/*
323 		 * P6 Family Processors
324 		 */
325 
326 	case PMC_CPU_INTEL_P6:
327 	case PMC_CPU_INTEL_CL:
328 	case PMC_CPU_INTEL_PII:
329 	case PMC_CPU_INTEL_PIII:
330 	case PMC_CPU_INTEL_PM:
331 
332 		error = pmc_initialize_p6(pmc_mdep);
333 		break;
334 
335 		/*
336 		 * Intel Pentium PMCs.
337 		 */
338 
339 	case PMC_CPU_INTEL_P5:
340 		error = pmc_initialize_p5(pmc_mdep);
341 		break;
342 #endif
343 
344 	default:
345 		KASSERT(0,("[intel,%d] Unknown CPU type", __LINE__));
346 	}
347 
348 	if (error) {
349 		FREE(pmc_mdep, M_PMC);
350 		pmc_mdep = NULL;
351 	}
352 
353 	return pmc_mdep;
354 }
355 
356 
357 /*
358  * Machine dependent initialization for x86 class platforms.
359  */
360 
361 struct pmc_mdep *
362 pmc_md_initialize()
363 {
364 	int i;
365 	struct pmc_mdep *md;
366 
367 	/* determine the CPU kind */
368 	md = NULL;
369 	if (strcmp(cpu_vendor, "AuthenticAMD") == 0)
370 		md = pmc_amd_initialize();
371 	else if (strcmp(cpu_vendor, "GenuineIntel") == 0)
372 		md = pmc_intel_initialize();
373 
374 	/* disallow sampling if we do not have an LAPIC */
375 	if (md != NULL && lapic == NULL)
376 		for (i = 1; i < md->pmd_nclass; i++)
377 			md->pmd_classes[i].pm_caps &= ~PMC_CAP_INTERRUPT;
378 
379 	return md;
380 }
381