1 1.6 maxv /* $NetBSD: nvmm_x86_svmfunc.S,v 1.6 2020/09/05 07:22:26 maxv Exp $ */ 2 1.1 maxv 3 1.1 maxv /* 4 1.6 maxv * Copyright (c) 2018-2020 Maxime Villard, m00nbsd.net 5 1.1 maxv * All rights reserved. 6 1.1 maxv * 7 1.6 maxv * This code is part of the NVMM hypervisor. 8 1.1 maxv * 9 1.1 maxv * Redistribution and use in source and binary forms, with or without 10 1.1 maxv * modification, are permitted provided that the following conditions 11 1.1 maxv * are met: 12 1.1 maxv * 1. Redistributions of source code must retain the above copyright 13 1.1 maxv * notice, this list of conditions and the following disclaimer. 14 1.1 maxv * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 maxv * notice, this list of conditions and the following disclaimer in the 16 1.1 maxv * documentation and/or other materials provided with the distribution. 17 1.1 maxv * 18 1.6 maxv * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.6 maxv * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.6 maxv * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.6 maxv * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.6 maxv * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 1.6 maxv * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 1.6 maxv * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 1.6 maxv * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 1.6 maxv * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 1.6 maxv * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 1.6 maxv * SUCH DAMAGE. 29 1.1 maxv */ 30 1.1 maxv 31 1.1 maxv /* Override user-land alignment before including asm.h */ 32 1.1 maxv #define ALIGN_DATA .align 8 33 1.1 maxv #define ALIGN_TEXT .align 16,0x90 34 1.1 maxv #define _ALIGN_TEXT ALIGN_TEXT 35 1.1 maxv 36 1.1 maxv #define _LOCORE 37 1.1 maxv #include "assym.h" 38 1.1 maxv #include <machine/asm.h> 39 1.1 maxv #include <machine/segments.h> 40 1.1 maxv #include <x86/specialreg.h> 41 1.1 maxv 42 1.1 maxv #define ASM_NVMM 43 1.1 maxv #include <dev/nvmm/x86/nvmm_x86.h> 44 1.1 maxv 45 1.1 maxv .text 46 1.1 maxv 47 1.1 maxv #define HOST_SAVE_GPRS \ 48 1.1 maxv pushq %rbx ;\ 49 1.1 maxv pushq %rbp ;\ 50 1.1 maxv pushq %r12 ;\ 51 1.1 maxv pushq %r13 ;\ 52 1.1 maxv pushq %r14 ;\ 53 1.1 maxv pushq %r15 54 1.1 maxv 55 1.1 maxv #define HOST_RESTORE_GPRS \ 56 1.1 maxv popq %r15 ;\ 57 1.1 maxv popq %r14 ;\ 58 1.1 maxv popq %r13 ;\ 59 1.1 maxv popq %r12 ;\ 60 1.1 maxv popq %rbp ;\ 61 1.1 maxv popq %rbx 62 1.1 maxv 63 1.1 maxv #define HOST_SAVE_MSR(msr) \ 64 1.1 maxv movq $msr,%rcx ;\ 65 1.1 maxv rdmsr ;\ 66 1.1 maxv pushq %rdx ;\ 67 1.1 maxv pushq %rax 68 1.1 maxv 69 1.1 maxv #define HOST_RESTORE_MSR(msr) \ 70 1.1 maxv popq %rax ;\ 71 1.1 maxv popq %rdx ;\ 72 1.1 maxv movq $msr,%rcx ;\ 73 1.1 maxv wrmsr 74 1.1 maxv 75 1.1 maxv #define HOST_SAVE_TR \ 76 1.1 maxv strw %ax ;\ 77 1.5 maxv pushq %rax 78 1.1 maxv 79 1.1 maxv #define HOST_RESTORE_TR \ 80 1.5 maxv popq %rax ;\ 81 1.1 maxv movzwq %ax,%rdx ;\ 82 1.1 maxv movq CPUVAR(GDT),%rax ;\ 83 1.1 maxv andq $~0x0200,4(%rax,%rdx, 1) ;\ 84 1.1 maxv ltrw %dx 85 1.1 maxv 86 1.1 maxv #define HOST_SAVE_LDT \ 87 1.1 maxv sldtw %ax ;\ 88 1.5 maxv pushq %rax 89 1.1 maxv 90 1.1 maxv #define HOST_RESTORE_LDT \ 91 1.5 maxv popq %rax ;\ 92 1.1 maxv lldtw %ax 93 1.1 maxv 94 1.1 maxv /* 95 1.1 maxv * All GPRs except RAX and RSP, which are taken care of in VMCB. 96 1.1 maxv */ 97 1.1 maxv 98 1.1 maxv #define GUEST_SAVE_GPRS(reg) \ 99 1.1 maxv movq %rcx,(NVMM_X64_GPR_RCX * 8)(reg) ;\ 100 1.1 maxv movq %rdx,(NVMM_X64_GPR_RDX * 8)(reg) ;\ 101 1.3 maxv movq %rbx,(NVMM_X64_GPR_RBX * 8)(reg) ;\ 102 1.3 maxv movq %rbp,(NVMM_X64_GPR_RBP * 8)(reg) ;\ 103 1.3 maxv movq %rsi,(NVMM_X64_GPR_RSI * 8)(reg) ;\ 104 1.3 maxv movq %rdi,(NVMM_X64_GPR_RDI * 8)(reg) ;\ 105 1.1 maxv movq %r8,(NVMM_X64_GPR_R8 * 8)(reg) ;\ 106 1.1 maxv movq %r9,(NVMM_X64_GPR_R9 * 8)(reg) ;\ 107 1.1 maxv movq %r10,(NVMM_X64_GPR_R10 * 8)(reg) ;\ 108 1.1 maxv movq %r11,(NVMM_X64_GPR_R11 * 8)(reg) ;\ 109 1.1 maxv movq %r12,(NVMM_X64_GPR_R12 * 8)(reg) ;\ 110 1.1 maxv movq %r13,(NVMM_X64_GPR_R13 * 8)(reg) ;\ 111 1.1 maxv movq %r14,(NVMM_X64_GPR_R14 * 8)(reg) ;\ 112 1.3 maxv movq %r15,(NVMM_X64_GPR_R15 * 8)(reg) 113 1.1 maxv 114 1.1 maxv #define GUEST_RESTORE_GPRS(reg) \ 115 1.1 maxv movq (NVMM_X64_GPR_RCX * 8)(reg),%rcx ;\ 116 1.1 maxv movq (NVMM_X64_GPR_RDX * 8)(reg),%rdx ;\ 117 1.3 maxv movq (NVMM_X64_GPR_RBX * 8)(reg),%rbx ;\ 118 1.3 maxv movq (NVMM_X64_GPR_RBP * 8)(reg),%rbp ;\ 119 1.3 maxv movq (NVMM_X64_GPR_RSI * 8)(reg),%rsi ;\ 120 1.3 maxv movq (NVMM_X64_GPR_RDI * 8)(reg),%rdi ;\ 121 1.1 maxv movq (NVMM_X64_GPR_R8 * 8)(reg),%r8 ;\ 122 1.1 maxv movq (NVMM_X64_GPR_R9 * 8)(reg),%r9 ;\ 123 1.1 maxv movq (NVMM_X64_GPR_R10 * 8)(reg),%r10 ;\ 124 1.1 maxv movq (NVMM_X64_GPR_R11 * 8)(reg),%r11 ;\ 125 1.1 maxv movq (NVMM_X64_GPR_R12 * 8)(reg),%r12 ;\ 126 1.1 maxv movq (NVMM_X64_GPR_R13 * 8)(reg),%r13 ;\ 127 1.1 maxv movq (NVMM_X64_GPR_R14 * 8)(reg),%r14 ;\ 128 1.3 maxv movq (NVMM_X64_GPR_R15 * 8)(reg),%r15 129 1.1 maxv 130 1.1 maxv /* 131 1.1 maxv * %rdi = PA of VMCB 132 1.1 maxv * %rsi = VA of guest GPR state 133 1.1 maxv */ 134 1.1 maxv ENTRY(svm_vmrun) 135 1.1 maxv /* Save the Host GPRs. */ 136 1.1 maxv HOST_SAVE_GPRS 137 1.1 maxv 138 1.1 maxv /* Save the Host TR. */ 139 1.1 maxv HOST_SAVE_TR 140 1.1 maxv 141 1.2 maxv /* Save the Host GSBASE. */ 142 1.1 maxv HOST_SAVE_MSR(MSR_GSBASE) 143 1.1 maxv 144 1.2 maxv /* Reset DS and ES. */ 145 1.1 maxv movq $GSEL(GUDATA_SEL, SEL_UPL),%rax 146 1.1 maxv movw %ax,%ds 147 1.1 maxv movw %ax,%es 148 1.1 maxv 149 1.1 maxv /* Save the Host LDT. */ 150 1.1 maxv HOST_SAVE_LDT 151 1.1 maxv 152 1.1 maxv /* Prepare RAX. */ 153 1.1 maxv pushq %rsi 154 1.1 maxv pushq %rdi 155 1.1 maxv 156 1.1 maxv /* Restore the Guest GPRs. */ 157 1.1 maxv movq %rsi,%rax 158 1.1 maxv GUEST_RESTORE_GPRS(%rax) 159 1.1 maxv 160 1.1 maxv /* Set RAX. */ 161 1.1 maxv popq %rax 162 1.1 maxv 163 1.1 maxv /* Run the VM. */ 164 1.1 maxv vmload %rax 165 1.1 maxv vmrun %rax 166 1.1 maxv vmsave %rax 167 1.1 maxv 168 1.1 maxv /* Get RAX. */ 169 1.1 maxv popq %rax 170 1.1 maxv 171 1.1 maxv /* Save the Guest GPRs. */ 172 1.1 maxv GUEST_SAVE_GPRS(%rax) 173 1.1 maxv 174 1.1 maxv /* Restore the Host LDT. */ 175 1.1 maxv HOST_RESTORE_LDT 176 1.1 maxv 177 1.2 maxv /* Reset FS and GS. */ 178 1.2 maxv xorq %rax,%rax 179 1.2 maxv movw %ax,%fs 180 1.2 maxv movw %ax,%gs 181 1.1 maxv 182 1.2 maxv /* Restore the Host GSBASE. */ 183 1.1 maxv HOST_RESTORE_MSR(MSR_GSBASE) 184 1.1 maxv 185 1.1 maxv /* Restore the Host TR. */ 186 1.1 maxv HOST_RESTORE_TR 187 1.1 maxv 188 1.1 maxv /* Restore the Host GPRs. */ 189 1.1 maxv HOST_RESTORE_GPRS 190 1.1 maxv 191 1.1 maxv xorq %rax,%rax 192 1.1 maxv retq 193 1.1 maxv END(svm_vmrun) 194