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