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