xref: /freebsd/sys/amd64/vmm/intel/vmx.h (revision 95ee2897)
1366f6083SPeter Grehan /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3c49761ddSPedro F. Giffuni  *
4366f6083SPeter Grehan  * Copyright (c) 2011 NetApp, Inc.
5366f6083SPeter Grehan  * All rights reserved.
6366f6083SPeter Grehan  *
7366f6083SPeter Grehan  * Redistribution and use in source and binary forms, with or without
8366f6083SPeter Grehan  * modification, are permitted provided that the following conditions
9366f6083SPeter Grehan  * are met:
10366f6083SPeter Grehan  * 1. Redistributions of source code must retain the above copyright
11366f6083SPeter Grehan  *    notice, this list of conditions and the following disclaimer.
12366f6083SPeter Grehan  * 2. Redistributions in binary form must reproduce the above copyright
13366f6083SPeter Grehan  *    notice, this list of conditions and the following disclaimer in the
14366f6083SPeter Grehan  *    documentation and/or other materials provided with the distribution.
15366f6083SPeter Grehan  *
16366f6083SPeter Grehan  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17366f6083SPeter Grehan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18366f6083SPeter Grehan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19366f6083SPeter Grehan  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20366f6083SPeter Grehan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21366f6083SPeter Grehan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22366f6083SPeter Grehan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23366f6083SPeter Grehan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24366f6083SPeter Grehan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25366f6083SPeter Grehan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26366f6083SPeter Grehan  * SUCH DAMAGE.
27366f6083SPeter Grehan  */
28366f6083SPeter Grehan 
29366f6083SPeter Grehan #ifndef _VMX_H_
30366f6083SPeter Grehan #define	_VMX_H_
31366f6083SPeter Grehan 
321aa51504SJohn Baldwin #include <vm/vm.h>
331aa51504SJohn Baldwin #include <vm/pmap.h>
341aa51504SJohn Baldwin 
35366f6083SPeter Grehan #include "vmcs.h"
366171e026SCorvin Köhne #include "x86.h"
37366f6083SPeter Grehan 
38318224bbSNeel Natu struct pmap;
39869c8d19SJohn Baldwin struct vmx;
40318224bbSNeel Natu 
41366f6083SPeter Grehan struct vmxctx {
42366f6083SPeter Grehan 	register_t	guest_rdi;		/* Guest state */
43366f6083SPeter Grehan 	register_t	guest_rsi;
44366f6083SPeter Grehan 	register_t	guest_rdx;
45366f6083SPeter Grehan 	register_t	guest_rcx;
46366f6083SPeter Grehan 	register_t	guest_r8;
47366f6083SPeter Grehan 	register_t	guest_r9;
48366f6083SPeter Grehan 	register_t	guest_rax;
49366f6083SPeter Grehan 	register_t	guest_rbx;
50366f6083SPeter Grehan 	register_t	guest_rbp;
51366f6083SPeter Grehan 	register_t	guest_r10;
52366f6083SPeter Grehan 	register_t	guest_r11;
53366f6083SPeter Grehan 	register_t	guest_r12;
54366f6083SPeter Grehan 	register_t	guest_r13;
55366f6083SPeter Grehan 	register_t	guest_r14;
56366f6083SPeter Grehan 	register_t	guest_r15;
57366f6083SPeter Grehan 	register_t	guest_cr2;
5865eefbe4SJohn Baldwin 	register_t	guest_dr0;
5965eefbe4SJohn Baldwin 	register_t	guest_dr1;
6065eefbe4SJohn Baldwin 	register_t	guest_dr2;
6165eefbe4SJohn Baldwin 	register_t	guest_dr3;
6265eefbe4SJohn Baldwin 	register_t	guest_dr6;
63366f6083SPeter Grehan 
64366f6083SPeter Grehan 	register_t	host_r15;		/* Host state */
65366f6083SPeter Grehan 	register_t	host_r14;
66366f6083SPeter Grehan 	register_t	host_r13;
67366f6083SPeter Grehan 	register_t	host_r12;
68366f6083SPeter Grehan 	register_t	host_rbp;
69366f6083SPeter Grehan 	register_t	host_rsp;
70366f6083SPeter Grehan 	register_t	host_rbx;
7165eefbe4SJohn Baldwin 	register_t	host_dr0;
7265eefbe4SJohn Baldwin 	register_t	host_dr1;
7365eefbe4SJohn Baldwin 	register_t	host_dr2;
7465eefbe4SJohn Baldwin 	register_t	host_dr3;
7565eefbe4SJohn Baldwin 	register_t	host_dr6;
7665eefbe4SJohn Baldwin 	register_t	host_dr7;
7765eefbe4SJohn Baldwin 	uint64_t	host_debugctl;
7865eefbe4SJohn Baldwin 	int		host_tf;
79366f6083SPeter Grehan 
800492757cSNeel Natu 	int		inst_fail_status;
81318224bbSNeel Natu 
82318224bbSNeel Natu 	/*
83897bb47eSPeter Grehan 	 * The pmap needs to be deactivated in vmx_enter_guest()
84953c2c47SNeel Natu 	 * so keep a copy of the 'pmap' in each vmxctx.
85318224bbSNeel Natu 	 */
86318224bbSNeel Natu 	struct pmap	*pmap;
87366f6083SPeter Grehan };
88366f6083SPeter Grehan 
89366f6083SPeter Grehan struct vmxcap {
90366f6083SPeter Grehan 	int	set;
91366f6083SPeter Grehan 	uint32_t proc_ctls;
9249cc03daSNeel Natu 	uint32_t proc_ctls2;
93cbd03a9dSJohn Baldwin 	uint32_t exc_bitmap;
94366f6083SPeter Grehan };
95366f6083SPeter Grehan 
96366f6083SPeter Grehan struct vmxstate {
972ce12423SNeel Natu 	uint64_t nextrip;	/* next instruction to be executed by guest */
98366f6083SPeter Grehan 	int	lastcpu;	/* host cpu that this 'vcpu' last ran on */
99366f6083SPeter Grehan 	uint16_t vpid;
100366f6083SPeter Grehan };
101366f6083SPeter Grehan 
102de5ea6b6SNeel Natu struct apic_page {
103de5ea6b6SNeel Natu 	uint32_t reg[PAGE_SIZE / 4];
104de5ea6b6SNeel Natu };
105de5ea6b6SNeel Natu CTASSERT(sizeof(struct apic_page) == PAGE_SIZE);
106de5ea6b6SNeel Natu 
107176666c2SNeel Natu /* Posted Interrupt Descriptor (described in section 29.6 of the Intel SDM) */
108176666c2SNeel Natu struct pir_desc {
109176666c2SNeel Natu 	uint64_t	pir[4];
110176666c2SNeel Natu 	uint64_t	pending;
111176666c2SNeel Natu 	uint64_t	unused[3];
112176666c2SNeel Natu } __aligned(64);
113176666c2SNeel Natu CTASSERT(sizeof(struct pir_desc) == 64);
114176666c2SNeel Natu 
115c3498942SNeel Natu /* Index into the 'guest_msrs[]' array */
116c3498942SNeel Natu enum {
117c3498942SNeel Natu 	IDX_MSR_LSTAR,
118c3498942SNeel Natu 	IDX_MSR_CSTAR,
119c3498942SNeel Natu 	IDX_MSR_STAR,
120c3498942SNeel Natu 	IDX_MSR_SF_MASK,
121c3498942SNeel Natu 	IDX_MSR_KGSBASE,
122a318f7ddSNeel Natu 	IDX_MSR_PAT,
123f5f5f1e7SPeter Grehan 	IDX_MSR_TSC_AUX,
124c3498942SNeel Natu 	GUEST_MSR_NUM		/* must be the last enumeration */
125c3498942SNeel Natu };
126c3498942SNeel Natu 
1270f00260cSJohn Baldwin struct vmx_vcpu {
128869c8d19SJohn Baldwin 	struct vmx	*vmx;
129950af9ffSJohn Baldwin 	struct vcpu	*vcpu;
1300f00260cSJohn Baldwin 	struct vmcs	*vmcs;
1310f00260cSJohn Baldwin 	struct apic_page *apic_page;
1320f00260cSJohn Baldwin 	struct pir_desc	*pir_desc;
1330f00260cSJohn Baldwin 	uint64_t	guest_msrs[GUEST_MSR_NUM];
1340f00260cSJohn Baldwin 	struct vmxctx	ctx;
1350f00260cSJohn Baldwin 	struct vmxcap	cap;
1360f00260cSJohn Baldwin 	struct vmxstate	state;
1370f00260cSJohn Baldwin 	struct vm_mtrr  mtrr;
1381aa51504SJohn Baldwin 	int		vcpuid;
1390f00260cSJohn Baldwin };
1400f00260cSJohn Baldwin 
141366f6083SPeter Grehan /* virtual machine softc */
142366f6083SPeter Grehan struct vmx {
1431aa51504SJohn Baldwin 	struct vm	*vm;
1440f00260cSJohn Baldwin 	char		*msr_bitmap;
145318224bbSNeel Natu 	uint64_t	eptp;
146953c2c47SNeel Natu 	long		eptgen[MAXCPU];		/* cached pmap->pm_eptgen */
1471aa51504SJohn Baldwin 	pmap_t		pmap;
148366f6083SPeter Grehan };
149366f6083SPeter Grehan 
15073abae44SJohn Baldwin extern bool vmx_have_msr_tsc_aux;
15173abae44SJohn Baldwin 
15257e0119eSJohn Baldwin #define	VMX_CTR0(vcpu, format)						\
15357e0119eSJohn Baldwin 	VCPU_CTR0((vcpu)->vmx->vm, (vcpu)->vcpuid, format)
15457e0119eSJohn Baldwin 
15557e0119eSJohn Baldwin #define	VMX_CTR1(vcpu, format, p1)					\
15657e0119eSJohn Baldwin 	VCPU_CTR1((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1)
15757e0119eSJohn Baldwin 
15857e0119eSJohn Baldwin #define	VMX_CTR2(vcpu, format, p1, p2)					\
15957e0119eSJohn Baldwin 	VCPU_CTR2((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2)
16057e0119eSJohn Baldwin 
16157e0119eSJohn Baldwin #define	VMX_CTR3(vcpu, format, p1, p2, p3)				\
16257e0119eSJohn Baldwin 	VCPU_CTR3((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2, p3)
16357e0119eSJohn Baldwin 
16457e0119eSJohn Baldwin #define	VMX_CTR4(vcpu, format, p1, p2, p3, p4)				\
16557e0119eSJohn Baldwin 	VCPU_CTR4((vcpu)->vmx->vm, (vcpu)->vcpuid, format, p1, p2, p3, p4)
16657e0119eSJohn Baldwin 
1670492757cSNeel Natu #define	VMX_GUEST_VMEXIT	0
1680492757cSNeel Natu #define	VMX_VMRESUME_ERROR	1
1690492757cSNeel Natu #define	VMX_VMLAUNCH_ERROR	2
170953c2c47SNeel Natu int	vmx_enter_guest(struct vmxctx *ctx, struct vmx *vmx, int launched);
171f7d47425SNeel Natu void	vmx_call_isr(uintptr_t entry);
172366f6083SPeter Grehan 
173366f6083SPeter Grehan u_long	vmx_fix_cr0(u_long cr0);
174366f6083SPeter Grehan u_long	vmx_fix_cr4(u_long cr4);
175366f6083SPeter Grehan 
17680cb5d84SJohn Baldwin int	vmx_set_tsc_offset(struct vmx_vcpu *vcpu, uint64_t offset);
177277bdd99STycho Nightingale 
178897bb47eSPeter Grehan extern char	vmx_exit_guest[];
17958a6aaf7STycho Nightingale extern char	vmx_exit_guest_flush_rsb[];
180897bb47eSPeter Grehan 
181366f6083SPeter Grehan #endif
182