17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*f0089e39SRichard Lowe * Common Development and Distribution License (the "License"). 6*f0089e39SRichard Lowe * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*f0089e39SRichard Lowe * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #ifndef _SYS_TRAPTRACE_H 267c478bd9Sstevel@tonic-gate #define _SYS_TRAPTRACE_H 277c478bd9Sstevel@tonic-gate 28*f0089e39SRichard Lowe #ifdef __cplusplus 29*f0089e39SRichard Lowe extern "C" { 30*f0089e39SRichard Lowe #endif 317c478bd9Sstevel@tonic-gate 32*f0089e39SRichard Lowe #include <sys/privregs.h> 337c478bd9Sstevel@tonic-gate 34*f0089e39SRichard Lowe /* 35*f0089e39SRichard Lowe * Trap tracing. If TRAPTRACE is defined, an entry is recorded every time 36*f0089e39SRichard Lowe * the CPU jumps through the Interrupt Descriptor Table (IDT). One exception 37*f0089e39SRichard Lowe * is the Double Fault handler, which does not record a traptrace entry. 38*f0089e39SRichard Lowe * 39*f0089e39SRichard Lowe * There are facilities to (conditionally) interleave tracing of related 40*f0089e39SRichard Lowe * facilities e.h. x-calls. 41*f0089e39SRichard Lowe */ 427c478bd9Sstevel@tonic-gate 43*f0089e39SRichard Lowe /* 44*f0089e39SRichard Lowe * Note: non-assembler files that include this file must include 45*f0089e39SRichard Lowe * <sys/systm.h> before it, for the typedef of pc_t to be visible. 46*f0089e39SRichard Lowe */ 47*f0089e39SRichard Lowe 48*f0089e39SRichard Lowe #define TTR_STACK_DEPTH 10 49*f0089e39SRichard Lowe 50*f0089e39SRichard Lowe #ifndef _ASM 51*f0089e39SRichard Lowe 52*f0089e39SRichard Lowe #define TTR_PAD1_SIZE (sizeof (long) - 1) 53*f0089e39SRichard Lowe 54*f0089e39SRichard Lowe typedef struct { 55*f0089e39SRichard Lowe uintptr_t ttc_next; 56*f0089e39SRichard Lowe uintptr_t ttc_first; 57*f0089e39SRichard Lowe uintptr_t ttc_limit; 58*f0089e39SRichard Lowe uintptr_t ttc_current; 59*f0089e39SRichard Lowe } trap_trace_ctl_t; 60*f0089e39SRichard Lowe 61*f0089e39SRichard Lowe typedef struct { 62*f0089e39SRichard Lowe struct regs ttr_regs; 63*f0089e39SRichard Lowe greg_t ttr_cr2; 64*f0089e39SRichard Lowe union _ttr_info { 65*f0089e39SRichard Lowe struct _idt_entry { 66*f0089e39SRichard Lowe int cpuid; 67*f0089e39SRichard Lowe short vector; 68*f0089e39SRichard Lowe uchar_t ipl; 69*f0089e39SRichard Lowe uchar_t spl; 70*f0089e39SRichard Lowe uchar_t pri; 71*f0089e39SRichard Lowe } idt_entry; 72*f0089e39SRichard Lowe struct _gate_entry { 73*f0089e39SRichard Lowe int sysnum; 74*f0089e39SRichard Lowe } gate_entry; 75*f0089e39SRichard Lowe } ttr_info; 76*f0089e39SRichard Lowe uintptr_t ttr_curthread; 77*f0089e39SRichard Lowe uchar_t ttr_pad[TTR_PAD1_SIZE]; 78*f0089e39SRichard Lowe uchar_t ttr_marker; 79*f0089e39SRichard Lowe hrtime_t ttr_stamp; 80*f0089e39SRichard Lowe int ttr_sdepth; 81*f0089e39SRichard Lowe pc_t ttr_stack[TTR_STACK_DEPTH]; 82*f0089e39SRichard Lowe } trap_trace_rec_t; 83*f0089e39SRichard Lowe 84*f0089e39SRichard Lowe #define ttr_cpuid ttr_info.idt_entry.cpuid 85*f0089e39SRichard Lowe #define ttr_vector ttr_info.idt_entry.vector 86*f0089e39SRichard Lowe #define ttr_ipl ttr_info.idt_entry.ipl 87*f0089e39SRichard Lowe #define ttr_spl ttr_info.idt_entry.spl 88*f0089e39SRichard Lowe #define ttr_pri ttr_info.idt_entry.pri 89*f0089e39SRichard Lowe #define ttr_sysnum ttr_info.gate_entry.sysnum 90*f0089e39SRichard Lowe 91*f0089e39SRichard Lowe #define TRAPTR_NENT 128 92*f0089e39SRichard Lowe 93*f0089e39SRichard Lowe extern trap_trace_ctl_t trap_trace_ctl[NCPU]; /* Allocated in locore.s */ 94*f0089e39SRichard Lowe extern size_t trap_trace_bufsize; 95*f0089e39SRichard Lowe extern int trap_trace_freeze; 96*f0089e39SRichard Lowe extern trap_trace_rec_t trap_trace_postmort; /* Entry used after death */ 97*f0089e39SRichard Lowe 98*f0089e39SRichard Lowe #define TRAPTRACE_FREEZE trap_trace_freeze = 1; 99*f0089e39SRichard Lowe #define TRAPTRACE_UNFREEZE trap_trace_freeze = 0; 100*f0089e39SRichard Lowe 101*f0089e39SRichard Lowe #else /* _ASM */ 102*f0089e39SRichard Lowe 103*f0089e39SRichard Lowe /* 104*f0089e39SRichard Lowe * ptr -- will be set to a TRAPTRACE entry. 105*f0089e39SRichard Lowe * scr1 -- scratch 106*f0089e39SRichard Lowe * scr1_32 -- 32-bit version of scr1 107*f0089e39SRichard Lowe * scr2 -- scratch 108*f0089e39SRichard Lowe * marker -- register containing byte to store in marker field of entry 109*f0089e39SRichard Lowe * 110*f0089e39SRichard Lowe * Note that this macro defines labels "8" and "9". 111*f0089e39SRichard Lowe */ 112*f0089e39SRichard Lowe #ifdef TRAPTRACE 113*f0089e39SRichard Lowe 114*f0089e39SRichard Lowe #if defined(__amd64) 115*f0089e39SRichard Lowe 116*f0089e39SRichard Lowe #define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker) \ 117*f0089e39SRichard Lowe leaq trap_trace_postmort(%rip), ptr; \ 118*f0089e39SRichard Lowe cmpl $0, trap_trace_freeze(%rip); \ 119*f0089e39SRichard Lowe jne 9f; \ 120*f0089e39SRichard Lowe LOADCPU(ptr); \ 121*f0089e39SRichard Lowe movl CPU_ID(ptr), scr1_32; \ 122*f0089e39SRichard Lowe shlq $TRAPTR_SIZE_SHIFT, scr1; \ 123*f0089e39SRichard Lowe leaq trap_trace_ctl(%rip), scr2; \ 124*f0089e39SRichard Lowe addq scr2, scr1; \ 125*f0089e39SRichard Lowe movq TRAPTR_NEXT(scr1), ptr; \ 126*f0089e39SRichard Lowe leaq TRAP_ENT_SIZE(ptr), scr2; \ 127*f0089e39SRichard Lowe cmpq TRAPTR_LIMIT(scr1), scr2; \ 128*f0089e39SRichard Lowe jl 8f; \ 129*f0089e39SRichard Lowe movq TRAPTR_FIRST(scr1), scr2; \ 130*f0089e39SRichard Lowe 8: movq scr2, TRAPTR_NEXT(scr1); \ 131*f0089e39SRichard Lowe 9: movb marker, TTR_MARKER(ptr); 132*f0089e39SRichard Lowe 133*f0089e39SRichard Lowe #elif defined(__i386) 134*f0089e39SRichard Lowe 135*f0089e39SRichard Lowe #define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker) \ 136*f0089e39SRichard Lowe movl $trap_trace_postmort, ptr; \ 137*f0089e39SRichard Lowe cmpl $0, trap_trace_freeze; \ 138*f0089e39SRichard Lowe jne 9f; \ 139*f0089e39SRichard Lowe LOADCPU(ptr); \ 140*f0089e39SRichard Lowe movl CPU_ID(ptr), scr1_32; \ 141*f0089e39SRichard Lowe shll $TRAPTR_SIZE_SHIFT, scr1; \ 142*f0089e39SRichard Lowe addl $trap_trace_ctl, scr1; \ 143*f0089e39SRichard Lowe movl TRAPTR_NEXT(scr1), ptr; \ 144*f0089e39SRichard Lowe leal TRAP_ENT_SIZE(ptr), scr2; \ 145*f0089e39SRichard Lowe cmpl TRAPTR_LIMIT(scr1), scr2; \ 146*f0089e39SRichard Lowe jl 8f; \ 147*f0089e39SRichard Lowe movl TRAPTR_FIRST(scr1), scr2; \ 148*f0089e39SRichard Lowe 8: movl scr2, TRAPTR_NEXT(scr1); \ 149*f0089e39SRichard Lowe 9: movb marker, TTR_MARKER(ptr); 150*f0089e39SRichard Lowe 151*f0089e39SRichard Lowe #endif /* __i386 */ 152*f0089e39SRichard Lowe 153*f0089e39SRichard Lowe /* 154*f0089e39SRichard Lowe * ptr -- pointer to the current TRAPTRACE entry. 155*f0089e39SRichard Lowe * reg -- pointer to the stored registers; must be on the stack 156*f0089e39SRichard Lowe * scr1 -- scratch used as array index 157*f0089e39SRichard Lowe * scr2 -- scratch used as temporary 158*f0089e39SRichard Lowe * 159*f0089e39SRichard Lowe * Note that this macro defines label "9". 160*f0089e39SRichard Lowe * Also captures curthread on exit of loop. 161*f0089e39SRichard Lowe */ 162*f0089e39SRichard Lowe #if defined(__xpv) 163*f0089e39SRichard Lowe #define __GETCR2(_mov, reg) \ 164*f0089e39SRichard Lowe _mov %gs:CPU_VCPU_INFO, reg; \ 165*f0089e39SRichard Lowe _mov VCPU_INFO_ARCH_CR2(reg), reg 166*f0089e39SRichard Lowe #else 167*f0089e39SRichard Lowe #define __GETCR2(_mov, reg) \ 168*f0089e39SRichard Lowe _mov %cr2, reg 169*f0089e39SRichard Lowe #endif 170*f0089e39SRichard Lowe 171*f0089e39SRichard Lowe #if defined(__amd64) 172*f0089e39SRichard Lowe 173*f0089e39SRichard Lowe #define TRACE_REGS(ptr, reg, scr1, scr2) \ 174*f0089e39SRichard Lowe xorq scr1, scr1; \ 175*f0089e39SRichard Lowe /*CSTYLED*/ \ 176*f0089e39SRichard Lowe 9: movq (reg, scr1, 1), scr2; \ 177*f0089e39SRichard Lowe movq scr2, (ptr, scr1, 1); \ 178*f0089e39SRichard Lowe addq $CLONGSIZE, scr1; \ 179*f0089e39SRichard Lowe cmpq $REGSIZE, scr1; \ 180*f0089e39SRichard Lowe jl 9b; \ 181*f0089e39SRichard Lowe movq %gs:CPU_THREAD, scr2; \ 182*f0089e39SRichard Lowe movq scr2, TTR_CURTHREAD(ptr); \ 183*f0089e39SRichard Lowe __GETCR2(movq, scr2); \ 184*f0089e39SRichard Lowe movq scr2, TTR_CR2(ptr) 185*f0089e39SRichard Lowe 186*f0089e39SRichard Lowe #elif defined(__i386) 187*f0089e39SRichard Lowe 188*f0089e39SRichard Lowe #define TRACE_REGS(ptr, reg, scr1, scr2) \ 189*f0089e39SRichard Lowe xorl scr1, scr1; \ 190*f0089e39SRichard Lowe /*CSTYLED*/ \ 191*f0089e39SRichard Lowe 9: movl (reg, scr1, 1), scr2; \ 192*f0089e39SRichard Lowe movl scr2, (ptr, scr1, 1); \ 193*f0089e39SRichard Lowe addl $CLONGSIZE, scr1; \ 194*f0089e39SRichard Lowe cmpl $REGSIZE, scr1; \ 195*f0089e39SRichard Lowe jl 9b; \ 196*f0089e39SRichard Lowe movl %gs:CPU_THREAD, scr2; \ 197*f0089e39SRichard Lowe movl scr2, TTR_CURTHREAD(ptr); \ 198*f0089e39SRichard Lowe __GETCR2(movl, scr2); \ 199*f0089e39SRichard Lowe movl scr2, TTR_CR2(ptr) 200*f0089e39SRichard Lowe 201*f0089e39SRichard Lowe #endif /* __i386 */ 202*f0089e39SRichard Lowe 203*f0089e39SRichard Lowe /* 204*f0089e39SRichard Lowe * The time stamp macro records a high-resolution time stamp for the 205*f0089e39SRichard Lowe * given TRAPTRACE entry. Note that %eax and %edx are plowed by this 206*f0089e39SRichard Lowe * macro; if they are to be preserved, it's up to the caller of the macro. 207*f0089e39SRichard Lowe */ 208*f0089e39SRichard Lowe 209*f0089e39SRichard Lowe #if defined(__amd64) 210*f0089e39SRichard Lowe 211*f0089e39SRichard Lowe #define TRACE_STAMP(reg) \ 212*f0089e39SRichard Lowe rdtsc; \ 213*f0089e39SRichard Lowe movl %eax, TTR_STAMP(reg); \ 214*f0089e39SRichard Lowe movl %edx, TTR_STAMP+4(reg) 215*f0089e39SRichard Lowe 216*f0089e39SRichard Lowe /* 217*f0089e39SRichard Lowe * %rbp should be set before invoking this macro. 218*f0089e39SRichard Lowe */ 219*f0089e39SRichard Lowe 220*f0089e39SRichard Lowe #define TRACE_STACK(tt) \ 221*f0089e39SRichard Lowe pushq %rdi; \ 222*f0089e39SRichard Lowe pushq %rsi; \ 223*f0089e39SRichard Lowe pushq %rdx; \ 224*f0089e39SRichard Lowe pushq %rcx; \ 225*f0089e39SRichard Lowe pushq %r8; \ 226*f0089e39SRichard Lowe pushq %r9; \ 227*f0089e39SRichard Lowe pushq %rax; \ 228*f0089e39SRichard Lowe pushq %r12; \ 229*f0089e39SRichard Lowe movq tt, %r12; \ 230*f0089e39SRichard Lowe leaq TTR_STACK(%r12), %rdi; \ 231*f0089e39SRichard Lowe movl $TTR_STACK_DEPTH, %esi; \ 232*f0089e39SRichard Lowe call getpcstack; \ 233*f0089e39SRichard Lowe movl %eax, TTR_SDEPTH(%r12); \ 234*f0089e39SRichard Lowe popq %r12; \ 235*f0089e39SRichard Lowe popq %rax; \ 236*f0089e39SRichard Lowe popq %r9; \ 237*f0089e39SRichard Lowe popq %r8; \ 238*f0089e39SRichard Lowe popq %rcx; \ 239*f0089e39SRichard Lowe popq %rdx; \ 240*f0089e39SRichard Lowe popq %rsi; \ 241*f0089e39SRichard Lowe popq %rdi 242*f0089e39SRichard Lowe 243*f0089e39SRichard Lowe #elif defined(__i386) 244*f0089e39SRichard Lowe 245*f0089e39SRichard Lowe #define TRACE_STAMP(reg) \ 246*f0089e39SRichard Lowe xorl %eax, %eax; \ 247*f0089e39SRichard Lowe xorl %edx, %edx; \ 248*f0089e39SRichard Lowe btl $X86FSET_TSC, x86_featureset; \ 249*f0089e39SRichard Lowe jnc 9f; \ 250*f0089e39SRichard Lowe rdtsc; \ 251*f0089e39SRichard Lowe 9: movl %eax, TTR_STAMP(reg); \ 252*f0089e39SRichard Lowe movl %edx, TTR_STAMP+4(reg) 253*f0089e39SRichard Lowe 254*f0089e39SRichard Lowe #define TRACE_STACK(tt) \ 255*f0089e39SRichard Lowe pushl %eax; \ 256*f0089e39SRichard Lowe pushl %ecx; \ 257*f0089e39SRichard Lowe pushl %edx; \ 258*f0089e39SRichard Lowe pushl %ebx; \ 259*f0089e39SRichard Lowe pushl $TTR_STACK_DEPTH; \ 260*f0089e39SRichard Lowe movl tt, %ebx; \ 261*f0089e39SRichard Lowe leal TTR_STACK(%ebx), %eax; \ 262*f0089e39SRichard Lowe pushl %eax; \ 263*f0089e39SRichard Lowe call getpcstack; \ 264*f0089e39SRichard Lowe addl $8, %esp; \ 265*f0089e39SRichard Lowe movl %eax, TTR_SDEPTH(%ebx); \ 266*f0089e39SRichard Lowe popl %ebx; \ 267*f0089e39SRichard Lowe popl %edx; \ 268*f0089e39SRichard Lowe popl %ecx; \ 269*f0089e39SRichard Lowe popl %eax 270*f0089e39SRichard Lowe 271*f0089e39SRichard Lowe #endif /* __i386 */ 272*f0089e39SRichard Lowe 273*f0089e39SRichard Lowe #else 274*f0089e39SRichard Lowe 275*f0089e39SRichard Lowe #define TRACE_PTR(ptr, scr1, scr1_32, scr2, marker) 276*f0089e39SRichard Lowe #define TRACE_REGS(ptr, reg, scr1, scr2) 277*f0089e39SRichard Lowe #define TRACE_STAMP(reg) 278*f0089e39SRichard Lowe #define TRACE_STACK(reg) 279*f0089e39SRichard Lowe 280*f0089e39SRichard Lowe #endif /* TRAPTRACE */ 281*f0089e39SRichard Lowe 282*f0089e39SRichard Lowe #endif /* _ASM */ 283*f0089e39SRichard Lowe 284*f0089e39SRichard Lowe #define TT_SYSCALL 0xaa /* system call via lcall */ 285*f0089e39SRichard Lowe #define TT_SYSENTER 0xab /* system call via sysenter */ 286*f0089e39SRichard Lowe #define TT_SYSC 0xad /* system call via syscall (32-bit) */ 287*f0089e39SRichard Lowe #define TT_SYSC64 0xae /* system call via syscall (64-bit) */ 288*f0089e39SRichard Lowe #define TT_INTERRUPT 0xbb 289*f0089e39SRichard Lowe #define TT_TRAP 0xcc 290*f0089e39SRichard Lowe #define TT_INTTRAP 0xdd 291*f0089e39SRichard Lowe #define TT_EVENT 0xee /* hypervisor event */ 292*f0089e39SRichard Lowe 293*f0089e39SRichard Lowe #ifdef __cplusplus 294*f0089e39SRichard Lowe } 2957c478bd9Sstevel@tonic-gate #endif 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate #endif /* _SYS_TRAPTRACE_H */ 298