1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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
Cache object: 1d95847187b4d622bb76a83f8660581a
|