1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/asm_linkage.h>
30 #include <sys/hypervisor.h>
31 #include <sys/privregs.h>
32 #include <sys/segments.h>
33 #include <sys/traptrace.h>
34 #include <sys/trap.h>
35 #include <sys/psw.h>
36 #include <sys/x86_archext.h>
37 #include <sys/asm_misc.h>
38 #include <sys/panic.h>
39
40 #if !defined(__lint)
41 #include "assym.h"
42 #endif
43
44 #if defined(__lint)
45
46 void
47 xpv_panic_callback(void)
48 {}
49
50 /* ARGSUSED */
51 void
52 xpv_panic_setcr3(ulong_t cr3)
53 {}
54
55 void
56 xpv_panic_reload_cr3(void)
57 {}
58
59 void
60 xpv_resetgs(void)
61 {}
62
63 #else /* __lint */
64
65 #if defined(__amd64)
66 ENTRY_NP(xpv_panic_getcr3)
67 movq %cr3, %rax
68 ret
69 SET_SIZE(xpv_panic_getcr3)
70
71 ENTRY_NP(xpv_panic_setcr3)
72 movq %rdi, %cr3
73 ret
74 SET_SIZE(xpv_panic_setcr3)
75
76 ENTRY(xpv_panic_reload_cr3)
77 movq %cr3, %rdi
78 movq %rdi, %cr3
79 ret
80 SET_SIZE(xpv_panic_reload_cr3)
81
82 ENTRY_NP(xpv_panic_prep)
83 pushq %rbp
84 movq %rsp, %rbp
85
86 subq $REGSIZE, %rsp
87 movq %rax, REGOFF_RAX(%rsp)
88 movq %rbx, REGOFF_RBX(%rsp)
89 movq %rsp, %rax
90 addq $REGSIZE, %rax
91 movq (%rax), %rbx
92 movq %rbx, REGOFF_RBP(%rsp)
93 movq 8(%rax), %rbx
94 movq %rbx, REGOFF_TRAPNO(%rsp)
95 movq 16(%rax), %rbx
96 movq %rbx, REGOFF_ERR(%rsp)
97 movq 24(%rax), %rbx
98 movq %rbx, REGOFF_RIP(%rsp)
99 movq 32(%rax), %rbx
100 movq %rbx, REGOFF_CS(%rsp)
101 movq 40(%rax), %rbx
102 movq %rbx, REGOFF_RFL(%rsp)
103 addq $56, %rax
104 movq %rax, REGOFF_RSP(%rsp)
105 xorl %eax, %eax
106 movw %gs, %ax
107 mov %rax, REGOFF_GS(%rsp)
108 movw %fs, %ax
109 mov %rax, REGOFF_FS(%rsp)
110 movw %es, %ax
111 mov %rax, REGOFF_ES(%rsp)
112 movw %ds, %ax
113 mov %rax, REGOFF_DS(%rsp)
114 movw %ss, %ax
115 mov %rax, REGOFF_SS(%rsp)
116 movq %rcx, REGOFF_RCX(%rsp)
117 movq %rdx, REGOFF_RDX(%rsp)
118 movq %rdi, REGOFF_RDI(%rsp)
119 movq %rsi, REGOFF_RSI(%rsp)
120 movq %r8, REGOFF_R8(%rsp)
121 movq %r9, REGOFF_R9(%rsp)
122 movq %r10, REGOFF_R10(%rsp)
123 movq %r11, REGOFF_R11(%rsp)
124 movq %r12, REGOFF_R12(%rsp)
125 movq %r13, REGOFF_R13(%rsp)
126 movq %r14, REGOFF_R14(%rsp)
127 movq %r15, REGOFF_R15(%rsp)
128
129 movq %rsp, %rdi
130 call xpv_die
131 SET_SIZE(xpv_panic_prep)
132
133 /*
134 * Switch to the Solaris panic stack and jump into the Xen panic
135 * handling code.
136 */
137 ENTRY_NP(xpv_panic_hdlr)
138 leaq panic_stack(%rip), %rsp
139 addq $PANICSTKSIZE, %rsp
140 call xpv_do_panic
141 SET_SIZE(xpv_panic_hdlr)
142
143 ENTRY_NP(xpv_surprise_intr)
144 pushq %rbp
145 movq %rsp, %rbp
146 subq $REGOFF_TRAPNO, %rsp
147 __SAVE_REGS
148 movq %rsp, %rdi
149 addq $REGOFF_TRAPNO, %rdi
150 call xpv_interrupt
151 __RESTORE_REGS
152 addq $REGOFF_TRAPNO, %rsp
153 popq %rbp
154 iretq
155 SET_SIZE(xpv_surprise_intr)
156
157 ENTRY_NP(xpv_timer_trap)
158 pushq %rbp
159 movq %rsp, %rbp
160 subq $REGOFF_TRAPNO, %rsp
161 __SAVE_REGS
162 movq %rsp, %rdi
163 addq $REGOFF_TRAPNO, %rdi
164 call xpv_timer_tick
165 __RESTORE_REGS
166 addq $REGOFF_TRAPNO, %rsp
167 popq %rbp
168 iretq
169 SET_SIZE(xpv_timer_trap)
170
171 #elif defined(__i386)
172
173 ENTRY_NP(xpv_panic_setcr3)
174 movl 4(%esp), %eax
175 movl %eax, %cr3
176 ret
177 SET_SIZE(xpv_panic_setcr3)
178
179 ENTRY(xpv_panic_reload_cr3)
180 movl %cr3, %eax
181 movl %eax, %cr3
182 ret
183 SET_SIZE(xpv_panic_reload_cr3)
184
185 /*
186 * Stack on entry:
187 * +------------+
188 * | EFLAGS |
189 * | CS |
190 * | EIP |
191 * | Error |
192 * | Trap | <---- %esp
193 * +------------+
194 */
195 ENTRY_NP(xpv_panic_prep)
196 pushl %ebp
197 movl %esp, %ebp
198
199 subl $REGSIZE, %esp
200 movl %eax, REGOFF_EAX(%esp)
201 movl %ebx, REGOFF_EBX(%esp)
202 movl %esp, %eax
203 addl $REGSIZE, %eax
204 movl (%eax), %ebx
205 movl %ebx, REGOFF_EBP(%esp)
206 movl 4(%eax), %ebx
207 movl %ebx, REGOFF_TRAPNO(%esp)
208 movl 8(%eax), %ebx
209 movl %ebx, REGOFF_ERR(%esp)
210 movl 12(%eax), %ebx
211 movl %ebx, REGOFF_EIP(%esp)
212 movl 16(%eax), %ebx
213 movl %ebx, REGOFF_CS(%esp)
214 movl 20(%eax), %ebx
215 movl %ebx, REGOFF_EFL(%esp)
216 addl $28, %eax
217 movl %eax, REGOFF_ESP(%esp)
218 xorl %eax, %eax
219 movw %gs, %ax
220 mov %eax, REGOFF_GS(%esp)
221 movw %fs, %ax
222 mov %eax, REGOFF_FS(%esp)
223 movw %es, %ax
224 mov %eax, REGOFF_ES(%esp)
225 movw %ds, %ax
226 mov %eax, REGOFF_DS(%esp)
227 movw %ss, %ax
228 mov %eax, REGOFF_SS(%esp)
229 movl %ecx, REGOFF_ECX(%esp)
230 movl %edx, REGOFF_EDX(%esp)
231 movl %edi, REGOFF_EDI(%esp)
232 movl %esi, REGOFF_ESI(%esp)
233 pushl %esp
234 call xpv_die
235 SET_SIZE(xpv_panic_prep)
236
237 /*
238 * Switch to the Solaris panic stack and jump into the Xen panic
239 * handling code.
240 */
241 ENTRY_NP(xpv_panic_hdlr)
242 movl 4(%esp), %eax
243 lea panic_stack, %esp
244 add $PANICSTKSIZE, %esp
245 pushl %eax
246 call xpv_do_panic
247 SET_SIZE(xpv_panic_hdlr)
248
249 ENTRY_NP(xpv_surprise_intr)
250 push %ebp
251 movl %esp, %ebp
252 pusha
253 call xpv_interrupt
254 popa
255 pop %ebp
256 iret
257 SET_SIZE(xpv_surprise_intr)
258
259 ENTRY_NP(xpv_timer_trap)
260 push %ebp
261 movl %esp, %ebp
262 pusha
263 call xpv_timer_tick
264 popa
265 pop %ebp
266 iret
267 SET_SIZE(xpv_timer_trap)
268
269 #endif /* __i386 */
270
271 ENTRY_NP(xpv_panic_sti)
272 sti
273 ret
274 SET_SIZE(xpv_panic_sti)
275
276 ENTRY_NP(xpv_panic_halt)
277 sti
278 hlt
279 ret
280 SET_SIZE(xpv_panic_halt)
281
282 ENTRY_NP(xpv_panic_resetgs)
283 movl $KGS_SEL, %eax
284 movw %ax, %gs
285 ret
286 SET_SIZE(xpv_panic_resetgs)
287
288 ENTRY_NP(xpv_invaltrap)
289 push $0xbad0
290 push $0x0bad
291 jmp xpv_panic_prep
292 SET_SIZE(xpv_invaltrap)
293
294 ENTRY_NP(xpv_div0trap)
295 push $0
296 push $T_ZERODIV
297 jmp xpv_panic_prep
298 SET_SIZE(xpv_div0trap)
299
300 ENTRY_NP(xpv_dbgtrap)
301 push $0
302 push $T_SGLSTP
303 jmp xpv_panic_prep
304 SET_SIZE(xpv_dbgtrap)
305
306 ENTRY_NP(xpv_nmiint)
307 push $0
308 push $T_NMIFLT
309 jmp xpv_panic_prep
310 SET_SIZE(xpv_nmiint)
311
312 ENTRY_NP(xpv_brktrap)
313 /* XXX: check for error */
314 push $T_BPTFLT
315 jmp xpv_panic_prep
316 SET_SIZE(xpv_brktrap)
317
318 ENTRY_NP(xpv_ovflotrap)
319 push $0
320 push $T_OVFLW
321 jmp xpv_panic_prep
322 SET_SIZE(xpv_ovflotrap)
323
324 ENTRY_NP(xpv_boundstrap)
325 push $0
326 push $T_BOUNDFLT
327 jmp xpv_panic_prep
328 SET_SIZE(xpv_boundstrap)
329
330 ENTRY_NP(xpv_invoptrap)
331 push $T_ILLINST
332 jmp xpv_panic_prep
333 SET_SIZE(xpv_invoptrap)
334
335 ENTRY_NP(xpv_ndptrap)
336 push $0
337 push $T_NOEXTFLT
338 jmp xpv_panic_prep
339 SET_SIZE(xpv_ndptrap)
340
341 ENTRY_NP(xpv_syserrtrap)
342 /* XXX: check for error */
343 push $T_DBLFLT
344 jmp xpv_panic_prep
345 SET_SIZE(xpv_syserrtrap)
346
347 ENTRY_NP(xpv_invtsstrap)
348 push $T_TSSFLT
349 jmp xpv_panic_prep
350 SET_SIZE(xpv_invtsstrap)
351
352 ENTRY_NP(xpv_segnptrap)
353 push $T_SEGFLT
354 jmp xpv_panic_prep
355 SET_SIZE(xpv_segnptrap)
356
357 ENTRY_NP(xpv_stktrap)
358 push $T_STKFLT
359 jmp xpv_panic_prep
360 SET_SIZE(xpv_stktrap)
361
362 ENTRY_NP(xpv_gptrap)
363 push $T_GPFLT
364 jmp xpv_panic_prep
365 SET_SIZE(xpv_gptrap)
366
367 ENTRY_NP(xpv_pftrap)
368 push $T_PGFLT
369 jmp xpv_panic_prep
370 SET_SIZE(xpv_pftrap)
371
372 ENTRY_NP(xpv_ndperr)
373 push $0
374 push $T_EXTERRFLT
375 jmp xpv_panic_prep
376 SET_SIZE(xpv_ndperr)
377
378 ENTRY_NP(xpv_achktrap)
379 push $T_ALIGNMENT
380 jmp xpv_panic_prep
381 SET_SIZE(xpv_achktrap)
382
383 ENTRY_NP(xpv_mcetrap)
384 push $0
385 push $T_MCE
386 jmp xpv_panic_prep
387 SET_SIZE(xpv_mcetrap)
388
389 ENTRY_NP(xpv_xmtrap)
390 push $0
391 push $T_SIMDFPE
392 jmp xpv_panic_prep
393 SET_SIZE(xpv_xmtrap)
394
395 #endif /* __lint */