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 */