1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011 NetApp, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #ifndef _VMX_H_ 30 #define _VMX_H_ 31 32 #include <vm/vm.h> 33 #include <vm/pmap.h> 34 35 #include "vmcs.h" 36 #include "x86.h" 37 38 struct pmap; 39 struct vmx; 40 41 struct vmxctx { 42 register_t guest_rdi; /* Guest state */ 43 register_t guest_rsi; 44 register_t guest_rdx; 45 register_t guest_rcx; 46 register_t guest_r8; 47 register_t guest_r9; 48 register_t guest_rax; 49 register_t guest_rbx; 50 register_t guest_rbp; 51 register_t guest_r10; 52 register_t guest_r11; 53 register_t guest_r12; 54 register_t guest_r13; 55 register_t guest_r14; 56 register_t guest_r15; 57 register_t guest_cr2; 58 register_t guest_dr0; 59 register_t guest_dr1; 60 register_t guest_dr2; 61 register_t guest_dr3; 62 register_t guest_dr6; 63 64 register_t host_r15; /* Host state */ 65 register_t host_r14; 66 register_t host_r13; 67 register_t host_r12; 68 register_t host_rbp; 69 register_t host_rsp; 70 register_t host_rbx; 71 register_t host_dr0; 72 register_t host_dr1; 73 register_t host_dr2; 74 register_t host_dr3; 75 register_t host_dr6; 76 register_t host_dr7; 77 uint64_t host_debugctl; 78 int host_tf; 79 80 int inst_fail_status; 81 82 /* 83 * The pmap needs to be deactivated in vmx_enter_guest() 84 * so keep a copy of the 'pmap' in each vmxctx. 85 */ 86 struct pmap *pmap; 87 }; 88 89 struct vmxcap { 90 int set; 91 uint32_t proc_ctls; 92 uint32_t proc_ctls2; 93 uint32_t exc_bitmap; 94 }; 95 96 struct vmxstate { 97 uint64_t nextrip; /* next instruction to be executed by guest */ 98 int lastcpu; /* host cpu that this 'vcpu' last ran on */ 99 uint16_t vpid; 100 }; 101 102 struct apic_page { 103 uint32_t reg[PAGE_SIZE / 4]; 104 }; 105 CTASSERT(sizeof(struct apic_page) == PAGE_SIZE); 106 107 /* Posted Interrupt Descriptor (described in section 29.6 of the Intel SDM) */ 108 struct pir_desc { 109 uint64_t pir[4]; 110 uint64_t pending; 111 uint64_t unused[3]; 112 } __aligned(64); 113 CTASSERT(sizeof(struct pir_desc) == 64); 114 115 /* Index into the 'guest_msrs[]' array */ 116 enum { 117 IDX_MSR_LSTAR, 118 IDX_MSR_CSTAR, 119 IDX_MSR_STAR, 120 IDX_MSR_SF_MASK, 121 IDX_MSR_KGSBASE, 122 IDX_MSR_PAT, 123 IDX_MSR_TSC_AUX, 124 GUEST_MSR_NUM /* must be the last enumeration */ 125 }; 126 127 struct vmx_vcpu { 128 struct vmx *vmx; 129 struct vcpu *vcpu; 130 struct vmcs *vmcs; 131 struct apic_page *apic_page; 132 struct pir_desc *pir_desc; 133 uint64_t guest_msrs[GUEST_MSR_NUM]; 134 struct vmxctx ctx; 135 struct vmxcap cap; 136 struct vmxstate state; 137 struct vm_mtrr mtrr; 138 int vcpuid; 139 }; 140 141 /* virtual machine softc */ 142 struct vmx { 143 struct vm *vm; 144 char *msr_bitmap; 145 uint64_t eptp; 146 long eptgen[MAXCPU]; /* cached pmap->pm_eptgen */ 147 pmap_t pmap; 148 }; 149 150 extern bool vmx_have_msr_tsc_aux; 151 152 #define VMX_CTR0(vcpu, format) \ 153 VCPU_CTR0((vcpu)->vmx->vm, (vcpu)->vcpuid, format) 154 155 #define VMX_CTR1(vcpu, format, p1) \ 156 VCPU_CTR1((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1) 157 158 #define VMX_CTR2(vcpu, format, p1, p2) \ 159 VCPU_CTR2((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2) 160 161 #define VMX_CTR3(vcpu, format, p1, p2, p3) \ 162 VCPU_CTR3((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2, p3) 163 164 #define VMX_CTR4(vcpu, format, p1, p2, p3, p4) \ 165 VCPU_CTR4((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2, p3, p4) 166 167 #define VMX_GUEST_VMEXIT 0 168 #define VMX_VMRESUME_ERROR 1 169 #define VMX_VMLAUNCH_ERROR 2 170 int vmx_enter_guest(struct vmxctx *ctx, struct vmx *vmx, int launched); 171 void vmx_call_isr(uintptr_t entry); 172 173 u_long vmx_fix_cr0(u_long cr0); 174 u_long vmx_fix_cr4(u_long cr4); 175 176 int vmx_set_tsc_offset(struct vmx_vcpu *vcpu, uint64_t offset); 177 178 extern char vmx_exit_guest[]; 179 extern char vmx_exit_guest_flush_rsb[]; 180 181 #endif 182