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 * $FreeBSD$ 29 */ 30 31 #ifndef _VMX_H_ 32 #define _VMX_H_ 33 34 #include <vm/vm.h> 35 #include <vm/pmap.h> 36 37 #include "vmcs.h" 38 #include "x86.h" 39 40 struct pmap; 41 struct vmx; 42 43 struct vmxctx { 44 register_t guest_rdi; /* Guest state */ 45 register_t guest_rsi; 46 register_t guest_rdx; 47 register_t guest_rcx; 48 register_t guest_r8; 49 register_t guest_r9; 50 register_t guest_rax; 51 register_t guest_rbx; 52 register_t guest_rbp; 53 register_t guest_r10; 54 register_t guest_r11; 55 register_t guest_r12; 56 register_t guest_r13; 57 register_t guest_r14; 58 register_t guest_r15; 59 register_t guest_cr2; 60 register_t guest_dr0; 61 register_t guest_dr1; 62 register_t guest_dr2; 63 register_t guest_dr3; 64 register_t guest_dr6; 65 66 register_t host_r15; /* Host state */ 67 register_t host_r14; 68 register_t host_r13; 69 register_t host_r12; 70 register_t host_rbp; 71 register_t host_rsp; 72 register_t host_rbx; 73 register_t host_dr0; 74 register_t host_dr1; 75 register_t host_dr2; 76 register_t host_dr3; 77 register_t host_dr6; 78 register_t host_dr7; 79 uint64_t host_debugctl; 80 int host_tf; 81 82 int inst_fail_status; 83 84 /* 85 * The pmap needs to be deactivated in vmx_enter_guest() 86 * so keep a copy of the 'pmap' in each vmxctx. 87 */ 88 struct pmap *pmap; 89 }; 90 91 struct vmxcap { 92 int set; 93 uint32_t proc_ctls; 94 uint32_t proc_ctls2; 95 uint32_t exc_bitmap; 96 }; 97 98 struct vmxstate { 99 uint64_t nextrip; /* next instruction to be executed by guest */ 100 int lastcpu; /* host cpu that this 'vcpu' last ran on */ 101 uint16_t vpid; 102 }; 103 104 struct apic_page { 105 uint32_t reg[PAGE_SIZE / 4]; 106 }; 107 CTASSERT(sizeof(struct apic_page) == PAGE_SIZE); 108 109 /* Posted Interrupt Descriptor (described in section 29.6 of the Intel SDM) */ 110 struct pir_desc { 111 uint64_t pir[4]; 112 uint64_t pending; 113 uint64_t unused[3]; 114 } __aligned(64); 115 CTASSERT(sizeof(struct pir_desc) == 64); 116 117 /* Index into the 'guest_msrs[]' array */ 118 enum { 119 IDX_MSR_LSTAR, 120 IDX_MSR_CSTAR, 121 IDX_MSR_STAR, 122 IDX_MSR_SF_MASK, 123 IDX_MSR_KGSBASE, 124 IDX_MSR_PAT, 125 IDX_MSR_TSC_AUX, 126 GUEST_MSR_NUM /* must be the last enumeration */ 127 }; 128 129 struct vmx_vcpu { 130 struct vmx *vmx; 131 struct vcpu *vcpu; 132 struct vmcs *vmcs; 133 struct apic_page *apic_page; 134 struct pir_desc *pir_desc; 135 uint64_t guest_msrs[GUEST_MSR_NUM]; 136 struct vmxctx ctx; 137 struct vmxcap cap; 138 struct vmxstate state; 139 struct vm_mtrr mtrr; 140 int vcpuid; 141 }; 142 143 /* virtual machine softc */ 144 struct vmx { 145 struct vm *vm; 146 char *msr_bitmap; 147 uint64_t eptp; 148 long eptgen[MAXCPU]; /* cached pmap->pm_eptgen */ 149 pmap_t pmap; 150 }; 151 152 extern bool vmx_have_msr_tsc_aux; 153 154 #define VMX_CTR0(vcpu, format) \ 155 VCPU_CTR0((vcpu)->vmx->vm, (vcpu)->vcpuid, format) 156 157 #define VMX_CTR1(vcpu, format, p1) \ 158 VCPU_CTR1((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1) 159 160 #define VMX_CTR2(vcpu, format, p1, p2) \ 161 VCPU_CTR2((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2) 162 163 #define VMX_CTR3(vcpu, format, p1, p2, p3) \ 164 VCPU_CTR3((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2, p3) 165 166 #define VMX_CTR4(vcpu, format, p1, p2, p3, p4) \ 167 VCPU_CTR4((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2, p3, p4) 168 169 #define VMX_GUEST_VMEXIT 0 170 #define VMX_VMRESUME_ERROR 1 171 #define VMX_VMLAUNCH_ERROR 2 172 int vmx_enter_guest(struct vmxctx *ctx, struct vmx *vmx, int launched); 173 void vmx_call_isr(uintptr_t entry); 174 175 u_long vmx_fix_cr0(u_long cr0); 176 u_long vmx_fix_cr4(u_long cr4); 177 178 int vmx_set_tsc_offset(struct vmx_vcpu *vcpu, uint64_t offset); 179 180 extern char vmx_exit_guest[]; 181 extern char vmx_exit_guest_flush_rsb[]; 182 183 #endif 184