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 #include <sys/asm_linkage.h> 28 #include <sys/hypervisor.h> 29 #include <sys/privregs.h> 30 #include <sys/segments.h> 31 #include <sys/traptrace.h> 32 #include <sys/trap.h> 33 #include <sys/psw.h> 34 #include <sys/x86_archext.h> 35 #include <sys/asm_misc.h> 36 #include <sys/panic.h> 37 38 #include "assym.h" 39 40 #if defined(__amd64) 41 ENTRY_NP(xpv_panic_getcr3) 42 movq %cr3, %rax 43 ret 44 SET_SIZE(xpv_panic_getcr3) 45 46 ENTRY_NP(xpv_panic_setcr3) 47 movq %rdi, %cr3 48 ret 49 SET_SIZE(xpv_panic_setcr3) 50 51 ENTRY(xpv_panic_reload_cr3) 52 movq %cr3, %rdi 53 movq %rdi, %cr3 54 ret 55 SET_SIZE(xpv_panic_reload_cr3) 56 57 ENTRY_NP(xpv_panic_prep) 58 pushq %rbp 59 movq %rsp, %rbp 60 61 subq $REGSIZE, %rsp 62 movq %rax, REGOFF_RAX(%rsp) 63 movq %rbx, REGOFF_RBX(%rsp) 64 movq %rsp, %rax 65 addq $REGSIZE, %rax 66 movq (%rax), %rbx 67 movq %rbx, REGOFF_RBP(%rsp) 68 movq 8(%rax), %rbx 69 movq %rbx, REGOFF_TRAPNO(%rsp) 70 movq 16(%rax), %rbx 71 movq %rbx, REGOFF_ERR(%rsp) 72 movq 24(%rax), %rbx 73 movq %rbx, REGOFF_RIP(%rsp) 74 movq 32(%rax), %rbx 75 movq %rbx, REGOFF_CS(%rsp) 76 movq 40(%rax), %rbx 77 movq %rbx, REGOFF_RFL(%rsp) 78 addq $56, %rax 79 movq %rax, REGOFF_RSP(%rsp) 80 xorl %eax, %eax 81 movw %gs, %ax 82 mov %rax, REGOFF_GS(%rsp) 83 movw %fs, %ax 84 mov %rax, REGOFF_FS(%rsp) 85 movw %es, %ax 86 mov %rax, REGOFF_ES(%rsp) 87 movw %ds, %ax 88 mov %rax, REGOFF_DS(%rsp) 89 movw %ss, %ax 90 mov %rax, REGOFF_SS(%rsp) 91 movq %rcx, REGOFF_RCX(%rsp) 92 movq %rdx, REGOFF_RDX(%rsp) 93 movq %rdi, REGOFF_RDI(%rsp) 94 movq %rsi, REGOFF_RSI(%rsp) 95 movq %r8, REGOFF_R8(%rsp) 96 movq %r9, REGOFF_R9(%rsp) 97 movq %r10, REGOFF_R10(%rsp) 98 movq %r11, REGOFF_R11(%rsp) 99 movq %r12, REGOFF_R12(%rsp) 100 movq %r13, REGOFF_R13(%rsp) 101 movq %r14, REGOFF_R14(%rsp) 102 movq %r15, REGOFF_R15(%rsp) 103 104 movq %rsp, %rdi 105 call xpv_die 106 SET_SIZE(xpv_panic_prep) 107 108 /* 109 * Switch to the Solaris panic stack and jump into the Xen panic 110 * handling code. 111 */ 112 ENTRY_NP(xpv_panic_hdlr) 113 leaq panic_stack(%rip), %rsp 114 addq $PANICSTKSIZE, %rsp 115 call xpv_do_panic 116 SET_SIZE(xpv_panic_hdlr) 117 118 ENTRY_NP(xpv_surprise_intr) 119 pushq %rbp 120 movq %rsp, %rbp 121 subq $REGOFF_TRAPNO, %rsp 122 __SAVE_REGS 123 movq %rsp, %rdi 124 addq $REGOFF_TRAPNO, %rdi 125 call xpv_interrupt 126 __RESTORE_REGS 127 addq $REGOFF_TRAPNO, %rsp 128 popq %rbp 129 iretq 130 SET_SIZE(xpv_surprise_intr) 131 132 ENTRY_NP(xpv_timer_trap) 133 pushq %rbp 134 movq %rsp, %rbp 135 subq $REGOFF_TRAPNO, %rsp 136 __SAVE_REGS 137 movq %rsp, %rdi 138 addq $REGOFF_TRAPNO, %rdi 139 call xpv_timer_tick 140 __RESTORE_REGS 141 addq $REGOFF_TRAPNO, %rsp 142 popq %rbp 143 iretq 144 SET_SIZE(xpv_timer_trap) 145 146 #elif defined(__i386) 147 148 ENTRY_NP(xpv_panic_setcr3) 149 movl 4(%esp), %eax 150 movl %eax, %cr3 151 ret 152 SET_SIZE(xpv_panic_setcr3) 153 154 ENTRY(xpv_panic_reload_cr3) 155 movl %cr3, %eax 156 movl %eax, %cr3 157 ret 158 SET_SIZE(xpv_panic_reload_cr3) 159 160 /* 161 * Stack on entry: 162 * +------------+ 163 * | EFLAGS | 164 * | CS | 165 * | EIP | 166 * | Error | 167 * | Trap | <---- %esp 168 * +------------+ 169 */ 170 ENTRY_NP(xpv_panic_prep) 171 pushl %ebp 172 movl %esp, %ebp 173 174 subl $REGSIZE, %esp 175 movl %eax, REGOFF_EAX(%esp) 176 movl %ebx, REGOFF_EBX(%esp) 177 movl %esp, %eax 178 addl $REGSIZE, %eax 179 movl (%eax), %ebx 180 movl %ebx, REGOFF_EBP(%esp) 181 movl 4(%eax), %ebx 182 movl %ebx, REGOFF_TRAPNO(%esp) 183 movl 8(%eax), %ebx 184 movl %ebx, REGOFF_ERR(%esp) 185 movl 12(%eax), %ebx 186 movl %ebx, REGOFF_EIP(%esp) 187 movl 16(%eax), %ebx 188 movl %ebx, REGOFF_CS(%esp) 189 movl 20(%eax), %ebx 190 movl %ebx, REGOFF_EFL(%esp) 191 addl $28, %eax 192 movl %eax, REGOFF_ESP(%esp) 193 xorl %eax, %eax 194 movw %gs, %ax 195 mov %eax, REGOFF_GS(%esp) 196 movw %fs, %ax 197 mov %eax, REGOFF_FS(%esp) 198 movw %es, %ax 199 mov %eax, REGOFF_ES(%esp) 200 movw %ds, %ax 201 mov %eax, REGOFF_DS(%esp) 202 movw %ss, %ax 203 mov %eax, REGOFF_SS(%esp) 204 movl %ecx, REGOFF_ECX(%esp) 205 movl %edx, REGOFF_EDX(%esp) 206 movl %edi, REGOFF_EDI(%esp) 207 movl %esi, REGOFF_ESI(%esp) 208 pushl %esp 209 call xpv_die 210 SET_SIZE(xpv_panic_prep) 211 212 /* 213 * Switch to the Solaris panic stack and jump into the Xen panic 214 * handling code. 215 */ 216 ENTRY_NP(xpv_panic_hdlr) 217 movl 4(%esp), %eax 218 lea panic_stack, %esp 219 add $PANICSTKSIZE, %esp 220 pushl %eax 221 call xpv_do_panic 222 SET_SIZE(xpv_panic_hdlr) 223 224 ENTRY_NP(xpv_surprise_intr) 225 push %ebp 226 movl %esp, %ebp 227 pusha 228 call xpv_interrupt 229 popa 230 pop %ebp 231 iret 232 SET_SIZE(xpv_surprise_intr) 233 234 ENTRY_NP(xpv_timer_trap) 235 push %ebp 236 movl %esp, %ebp 237 pusha 238 call xpv_timer_tick 239 popa 240 pop %ebp 241 iret 242 SET_SIZE(xpv_timer_trap) 243 244 #endif /* __i386 */ 245 246 ENTRY_NP(xpv_panic_sti) 247 sti 248 ret 249 SET_SIZE(xpv_panic_sti) 250 251 ENTRY_NP(xpv_panic_halt) 252 sti 253 hlt 254 ret 255 SET_SIZE(xpv_panic_halt) 256 257 ENTRY_NP(xpv_panic_resetgs) 258 movl $KGS_SEL, %eax 259 movw %ax, %gs 260 ret 261 SET_SIZE(xpv_panic_resetgs) 262 263 ENTRY_NP(xpv_invaltrap) 264 push $0xbad0 265 push $0x0bad 266 jmp xpv_panic_prep 267 SET_SIZE(xpv_invaltrap) 268 269 ENTRY_NP(xpv_div0trap) 270 push $0 271 push $T_ZERODIV 272 jmp xpv_panic_prep 273 SET_SIZE(xpv_div0trap) 274 275 ENTRY_NP(xpv_dbgtrap) 276 push $0 277 push $T_SGLSTP 278 jmp xpv_panic_prep 279 SET_SIZE(xpv_dbgtrap) 280 281 ENTRY_NP(xpv_nmiint) 282 push $0 283 push $T_NMIFLT 284 jmp xpv_panic_prep 285 SET_SIZE(xpv_nmiint) 286 287 ENTRY_NP(xpv_brktrap) 288 /* XXX: check for error */ 289 push $T_BPTFLT 290 jmp xpv_panic_prep 291 SET_SIZE(xpv_brktrap) 292 293 ENTRY_NP(xpv_ovflotrap) 294 push $0 295 push $T_OVFLW 296 jmp xpv_panic_prep 297 SET_SIZE(xpv_ovflotrap) 298 299 ENTRY_NP(xpv_boundstrap) 300 push $0 301 push $T_BOUNDFLT 302 jmp xpv_panic_prep 303 SET_SIZE(xpv_boundstrap) 304 305 ENTRY_NP(xpv_invoptrap) 306 push $T_ILLINST 307 jmp xpv_panic_prep 308 SET_SIZE(xpv_invoptrap) 309 310 ENTRY_NP(xpv_ndptrap) 311 push $0 312 push $T_NOEXTFLT 313 jmp xpv_panic_prep 314 SET_SIZE(xpv_ndptrap) 315 316 ENTRY_NP(xpv_syserrtrap) 317 /* XXX: check for error */ 318 push $T_DBLFLT 319 jmp xpv_panic_prep 320 SET_SIZE(xpv_syserrtrap) 321 322 ENTRY_NP(xpv_invtsstrap) 323 push $T_TSSFLT 324 jmp xpv_panic_prep 325 SET_SIZE(xpv_invtsstrap) 326 327 ENTRY_NP(xpv_segnptrap) 328 push $T_SEGFLT 329 jmp xpv_panic_prep 330 SET_SIZE(xpv_segnptrap) 331 332 ENTRY_NP(xpv_stktrap) 333 push $T_STKFLT 334 jmp xpv_panic_prep 335 SET_SIZE(xpv_stktrap) 336 337 ENTRY_NP(xpv_gptrap) 338 push $T_GPFLT 339 jmp xpv_panic_prep 340 SET_SIZE(xpv_gptrap) 341 342 ENTRY_NP(xpv_pftrap) 343 push $T_PGFLT 344 jmp xpv_panic_prep 345 SET_SIZE(xpv_pftrap) 346 347 ENTRY_NP(xpv_ndperr) 348 push $0 349 push $T_EXTERRFLT 350 jmp xpv_panic_prep 351 SET_SIZE(xpv_ndperr) 352 353 ENTRY_NP(xpv_achktrap) 354 push $T_ALIGNMENT 355 jmp xpv_panic_prep 356 SET_SIZE(xpv_achktrap) 357 358 ENTRY_NP(xpv_mcetrap) 359 push $0 360 push $T_MCE 361 jmp xpv_panic_prep 362 SET_SIZE(xpv_mcetrap) 363 364 ENTRY_NP(xpv_xmtrap) 365 push $0 366 push $T_SIMDFPE 367 jmp xpv_panic_prep 368 SET_SIZE(xpv_xmtrap) 369