Print this page
XXX AVX procfs
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/amd64/sys/privregs.h
+++ new/usr/src/uts/intel/amd64/sys/privregs.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 #ifndef _AMD64_SYS_PRIVREGS_H
28 28 #define _AMD64_SYS_PRIVREGS_H
29 29
30 30 #include <sys/ccompile.h>
31 31
32 32 #ifdef __cplusplus
33 33 extern "C" {
34 34 #endif
35 35
36 36 /*
37 37 * This file describes the cpu's privileged register set, and
38 38 * how the machine state is saved on the stack when a trap occurs.
39 39 */
40 40
41 41 #if !defined(__amd64)
42 42 #error "non-amd64 code depends on amd64 privileged header!"
43 43 #endif
44 44
45 45 #ifndef _ASM
46 46
47 47 /*
48 48 * This is NOT the structure to use for general purpose debugging;
49 49 * see /proc for that. This is NOT the structure to use to decode
50 50 * the ucontext or grovel about in a core file; see <sys/regset.h>.
51 51 */
52 52
53 53 struct regs {
54 54 /*
55 55 * Extra frame for mdb to follow through high level interrupts and
56 56 * system traps. Set them to 0 to terminate stacktrace.
57 57 */
58 58 greg_t r_savfp; /* a copy of %rbp */
59 59 greg_t r_savpc; /* a copy of %rip */
60 60
61 61 greg_t r_rdi; /* 1st arg to function */
62 62 greg_t r_rsi; /* 2nd arg to function */
63 63 greg_t r_rdx; /* 3rd arg to function, 2nd return register */
64 64 greg_t r_rcx; /* 4th arg to function */
65 65
66 66 greg_t r_r8; /* 5th arg to function */
67 67 greg_t r_r9; /* 6th arg to function */
68 68 greg_t r_rax; /* 1st return register, # SSE registers */
69 69 greg_t r_rbx; /* callee-saved, optional base pointer */
70 70
71 71 greg_t r_rbp; /* callee-saved, optional frame pointer */
72 72 greg_t r_r10; /* temporary register, static chain pointer */
73 73 greg_t r_r11; /* temporary register */
74 74 greg_t r_r12; /* callee-saved */
75 75
76 76 greg_t r_r13; /* callee-saved */
77 77 greg_t r_r14; /* callee-saved */
78 78 greg_t r_r15; /* callee-saved */
79 79
80 80 /*
81 81 * fsbase and gsbase are sampled on every exception in DEBUG kernels
82 82 * only. They remain in the non-DEBUG kernel to avoid any flag days.
83 83 */
84 84 greg_t __r_fsbase; /* no longer used in non-DEBUG builds */
85 85 greg_t __r_gsbase; /* no longer used in non-DEBUG builds */
86 86 greg_t r_ds;
87 87 greg_t r_es;
88 88 greg_t r_fs; /* %fs is *never* used by the kernel */
89 89 greg_t r_gs;
90 90
91 91 greg_t r_trapno;
92 92
93 93 /*
94 94 * (the rest of these are defined by the hardware)
95 95 */
96 96 greg_t r_err;
97 97 greg_t r_rip;
98 98 greg_t r_cs;
99 99 greg_t r_rfl;
100 100 greg_t r_rsp;
101 101 greg_t r_ss;
102 102 };
↓ open down ↓ |
102 lines elided |
↑ open up ↑ |
103 103
104 104 #define r_r0 r_rax /* r0 for portability */
105 105 #define r_r1 r_rdx /* r1 for portability */
106 106 #define r_fp r_rbp /* kernel frame pointer */
107 107 #define r_sp r_rsp /* user stack pointer */
108 108 #define r_pc r_rip /* user's instruction pointer */
109 109 #define r_ps r_rfl /* user's RFLAGS */
110 110
111 111 #ifdef _KERNEL
112 112 #define lwptoregs(lwp) ((struct regs *)((lwp)->lwp_regs))
113 +#define lwptofpu(lwp) ((kfpu_t *)((lwp)->lwp_fpu))
113 114 #endif /* _KERNEL */
114 115
115 116 #else /* !_ASM */
116 117
117 118 #if defined(_MACHDEP)
118 119
119 120 #include <sys/machprivregs.h>
120 121 #include <sys/pcb.h>
121 122
122 123 /*
123 124 * We can not safely sample {fs,gs}base on the hypervisor. The rdmsr
124 125 * instruction triggers a #gp fault which is emulated in the hypervisor
125 126 * on behalf of the guest. This is normally ok but if the guest is in
126 127 * the special failsafe handler it must not fault again or the hypervisor
127 128 * will kill the domain. We could use something different than INTR_PUSH
128 129 * in xen_failsafe_callback but for now we will not sample them.
129 130 */
130 131 #if defined(DEBUG) && !defined(__xpv)
131 132 #define __SAVE_BASES \
132 133 movl $MSR_AMD_FSBASE, %ecx; \
133 134 rdmsr; \
134 135 movl %eax, REGOFF_FSBASE(%rsp); \
135 136 movl %edx, REGOFF_FSBASE+4(%rsp); \
136 137 movl $MSR_AMD_GSBASE, %ecx; \
137 138 rdmsr; \
138 139 movl %eax, REGOFF_GSBASE(%rsp); \
139 140 movl %edx, REGOFF_GSBASE+4(%rsp)
140 141 #else
141 142 #define __SAVE_BASES
142 143 #endif
143 144
144 145 /*
145 146 * Create a struct regs on the stack suitable for an
146 147 * interrupt trap.
147 148 *
148 149 * Assumes that the trap handler has already pushed an
149 150 * appropriate r_err and r_trapno
150 151 */
151 152 #define __SAVE_REGS \
152 153 movq %r15, REGOFF_R15(%rsp); \
153 154 movq %r14, REGOFF_R14(%rsp); \
154 155 movq %r13, REGOFF_R13(%rsp); \
155 156 movq %r12, REGOFF_R12(%rsp); \
156 157 movq %r11, REGOFF_R11(%rsp); \
157 158 movq %r10, REGOFF_R10(%rsp); \
158 159 movq %rbp, REGOFF_RBP(%rsp); \
159 160 movq %rbx, REGOFF_RBX(%rsp); \
160 161 movq %rax, REGOFF_RAX(%rsp); \
161 162 movq %r9, REGOFF_R9(%rsp); \
162 163 movq %r8, REGOFF_R8(%rsp); \
163 164 movq %rcx, REGOFF_RCX(%rsp); \
164 165 movq %rdx, REGOFF_RDX(%rsp); \
165 166 movq %rsi, REGOFF_RSI(%rsp); \
166 167 movq %rdi, REGOFF_RDI(%rsp); \
167 168 movq %rbp, REGOFF_SAVFP(%rsp); \
168 169 movq REGOFF_RIP(%rsp), %rcx; \
169 170 movq %rcx, REGOFF_SAVPC(%rsp); \
170 171 xorl %ecx, %ecx; \
171 172 movw %gs, %cx; \
172 173 movq %rcx, REGOFF_GS(%rsp); \
173 174 movw %fs, %cx; \
174 175 movq %rcx, REGOFF_FS(%rsp); \
175 176 movw %es, %cx; \
176 177 movq %rcx, REGOFF_ES(%rsp); \
177 178 movw %ds, %cx; \
178 179 movq %rcx, REGOFF_DS(%rsp); \
179 180 __SAVE_BASES
180 181
181 182 #define __RESTORE_REGS \
182 183 movq REGOFF_RDI(%rsp), %rdi; \
183 184 movq REGOFF_RSI(%rsp), %rsi; \
184 185 movq REGOFF_RDX(%rsp), %rdx; \
185 186 movq REGOFF_RCX(%rsp), %rcx; \
186 187 movq REGOFF_R8(%rsp), %r8; \
187 188 movq REGOFF_R9(%rsp), %r9; \
188 189 movq REGOFF_RAX(%rsp), %rax; \
189 190 movq REGOFF_RBX(%rsp), %rbx; \
190 191 movq REGOFF_RBP(%rsp), %rbp; \
191 192 movq REGOFF_R10(%rsp), %r10; \
192 193 movq REGOFF_R11(%rsp), %r11; \
193 194 movq REGOFF_R12(%rsp), %r12; \
194 195 movq REGOFF_R13(%rsp), %r13; \
195 196 movq REGOFF_R14(%rsp), %r14; \
196 197 movq REGOFF_R15(%rsp), %r15
197 198
198 199 /*
199 200 * Push register state onto the stack. If we've
200 201 * interrupted userland, do a swapgs as well.
201 202 */
202 203 #define INTR_PUSH \
203 204 subq $REGOFF_TRAPNO, %rsp; \
204 205 __SAVE_REGS; \
205 206 cmpw $KCS_SEL, REGOFF_CS(%rsp); \
206 207 je 6f; \
207 208 movq $0, REGOFF_SAVFP(%rsp); \
208 209 SWAPGS; \
209 210 6: CLEAN_CS
210 211
211 212 #define INTR_POP \
212 213 leaq sys_lcall32(%rip), %r11;\
213 214 cmpq %r11, REGOFF_RIP(%rsp); \
214 215 __RESTORE_REGS; \
215 216 je 5f; \
216 217 cmpw $KCS_SEL, REGOFF_CS(%rsp);\
217 218 je 8f; \
218 219 5: SWAPGS; \
219 220 8: addq $REGOFF_RIP, %rsp
220 221
221 222 #define USER_POP \
222 223 __RESTORE_REGS; \
223 224 SWAPGS; \
224 225 addq $REGOFF_RIP, %rsp /* Adjust %rsp to prepare for iretq */
225 226
226 227 #define USER32_POP \
227 228 movl REGOFF_RDI(%rsp), %edi; \
228 229 movl REGOFF_RSI(%rsp), %esi; \
229 230 movl REGOFF_RDX(%rsp), %edx; \
230 231 movl REGOFF_RCX(%rsp), %ecx; \
231 232 movl REGOFF_RAX(%rsp), %eax; \
232 233 movl REGOFF_RBX(%rsp), %ebx; \
233 234 movl REGOFF_RBP(%rsp), %ebp; \
234 235 SWAPGS; \
235 236 addq $REGOFF_RIP, %rsp /* Adjust %rsp to prepare for iretq */
236 237
237 238 #define DFTRAP_PUSH \
238 239 subq $REGOFF_TRAPNO, %rsp; \
239 240 __SAVE_REGS
240 241
241 242 #endif /* _MACHDEP */
242 243
243 244 /*
244 245 * Used to set rflags to known values at the head of an
245 246 * interrupt gate handler, i.e. interrupts are -already- disabled.
246 247 */
247 248 #define INTGATE_INIT_KERNEL_FLAGS \
248 249 pushq $F_OFF; \
249 250 popfq
250 251
251 252 #endif /* !_ASM */
252 253
253 254 #include <sys/controlregs.h>
254 255
255 256 #if defined(_KERNEL) && !defined(_ASM)
256 257 #if !defined(__lint) && defined(__GNUC__)
257 258
258 259 extern __GNU_INLINE ulong_t
259 260 getcr8(void)
260 261 {
261 262 uint64_t value;
262 263
263 264 __asm__ __volatile__(
264 265 "movq %%cr8, %0"
265 266 : "=r" (value));
266 267 return (value);
267 268 }
268 269
269 270 extern __GNU_INLINE void
270 271 setcr8(ulong_t value)
271 272 {
272 273 __asm__ __volatile__(
273 274 "movq %0, %%cr8"
274 275 : /* no output */
275 276 : "r" (value));
276 277 }
277 278
278 279 #else
279 280
280 281 extern ulong_t getcr8(void);
281 282 extern void setcr8(ulong_t);
282 283
283 284 #endif /* !defined(__lint) && defined(__GNUC__) */
284 285 #endif /* _KERNEL && !_ASM */
285 286
286 287 /* Control register layout for panic dump */
287 288
288 289 #define CREGSZ 0x68
289 290 #define CREG_GDT 0
290 291 #define CREG_IDT 0x10
291 292 #define CREG_LDT 0x20
292 293 #define CREG_TASKR 0x28
293 294 #define CREG_CR0 0x30
294 295 #define CREG_CR2 0x38
295 296 #define CREG_CR3 0x40
296 297 #define CREG_CR4 0x48
297 298 #define CREG_CR8 0x50
298 299 #define CREG_KGSBASE 0x58
299 300 #define CREG_EFER 0x60
300 301
301 302 #if !defined(_ASM) && defined(_INT64_TYPE)
302 303
303 304 typedef uint64_t creg64_t;
304 305 typedef upad128_t creg128_t;
305 306
306 307 struct cregs {
307 308 creg128_t cr_gdt;
308 309 creg128_t cr_idt;
309 310 creg64_t cr_ldt;
310 311 creg64_t cr_task;
311 312 creg64_t cr_cr0;
312 313 creg64_t cr_cr2;
313 314 creg64_t cr_cr3;
314 315 creg64_t cr_cr4;
315 316 creg64_t cr_cr8;
316 317 creg64_t cr_kgsbase;
317 318 creg64_t cr_efer;
318 319 };
319 320
320 321 #if defined(_KERNEL)
321 322 extern void getcregs(struct cregs *);
322 323 #endif /* _KERNEL */
323 324
324 325 #endif /* !_ASM && _INT64_TYPE */
325 326
326 327 #ifdef __cplusplus
327 328 }
328 329 #endif
329 330
330 331 #endif /* !_AMD64_SYS_PRIVREGS_H */
↓ open down ↓ |
208 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX