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