xref: /freebsd/sys/amd64/vmm/intel/vmx_support.S (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1366f6083SPeter Grehan/*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3ebc3c37cSMarcelo Araujo *
4366f6083SPeter Grehan * Copyright (c) 2011 NetApp, Inc.
50492757cSNeel Natu * Copyright (c) 2013 Neel Natu <neel@freebsd.org>
6366f6083SPeter Grehan * All rights reserved.
7366f6083SPeter Grehan *
8366f6083SPeter Grehan * Redistribution and use in source and binary forms, with or without
9366f6083SPeter Grehan * modification, are permitted provided that the following conditions
10366f6083SPeter Grehan * are met:
11366f6083SPeter Grehan * 1. Redistributions of source code must retain the above copyright
12366f6083SPeter Grehan *    notice, this list of conditions and the following disclaimer.
13366f6083SPeter Grehan * 2. Redistributions in binary form must reproduce the above copyright
14366f6083SPeter Grehan *    notice, this list of conditions and the following disclaimer in the
15366f6083SPeter Grehan *    documentation and/or other materials provided with the distribution.
16366f6083SPeter Grehan *
17366f6083SPeter Grehan * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
18366f6083SPeter Grehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19366f6083SPeter Grehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20366f6083SPeter Grehan * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
21366f6083SPeter Grehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22366f6083SPeter Grehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23366f6083SPeter Grehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24366f6083SPeter Grehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25366f6083SPeter Grehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26366f6083SPeter Grehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27366f6083SPeter Grehan * SUCH DAMAGE.
28366f6083SPeter Grehan */
29366f6083SPeter Grehan
30366f6083SPeter Grehan#include <machine/asmacros.h>
31c30578feSKonstantin Belousov#include <machine/specialreg.h>
32366f6083SPeter Grehan
33b82e2e94SWarner Losh#include "vmx_assym.h"
34366f6083SPeter Grehan
35318224bbSNeel Natu#ifdef SMP
36318224bbSNeel Natu#define	LK	lock ;
37318224bbSNeel Natu#else
38318224bbSNeel Natu#define	LK
39318224bbSNeel Natu#endif
40318224bbSNeel Natu
41897bb47eSPeter Grehan/* Be friendly to DTrace FBT's prologue/epilogue pattern matching */
42897bb47eSPeter Grehan#define VENTER  push %rbp ; mov %rsp,%rbp
43897bb47eSPeter Grehan#define VLEAVE  pop %rbp
44897bb47eSPeter Grehan
45366f6083SPeter Grehan/*
4658a6aaf7STycho Nightingale * Save the guest context.
4758a6aaf7STycho Nightingale */
4858a6aaf7STycho Nightingale#define	VMX_GUEST_SAVE							\
4958a6aaf7STycho Nightingale	movq	%rdi,VMXCTX_GUEST_RDI(%rsp);				\
5058a6aaf7STycho Nightingale	movq	%rsi,VMXCTX_GUEST_RSI(%rsp);				\
5158a6aaf7STycho Nightingale	movq	%rdx,VMXCTX_GUEST_RDX(%rsp);				\
5258a6aaf7STycho Nightingale	movq	%rcx,VMXCTX_GUEST_RCX(%rsp);				\
5358a6aaf7STycho Nightingale	movq	%r8,VMXCTX_GUEST_R8(%rsp);				\
5458a6aaf7STycho Nightingale	movq	%r9,VMXCTX_GUEST_R9(%rsp);				\
5558a6aaf7STycho Nightingale	movq	%rax,VMXCTX_GUEST_RAX(%rsp);				\
5658a6aaf7STycho Nightingale	movq	%rbx,VMXCTX_GUEST_RBX(%rsp);				\
5758a6aaf7STycho Nightingale	movq	%rbp,VMXCTX_GUEST_RBP(%rsp);				\
5858a6aaf7STycho Nightingale	movq	%r10,VMXCTX_GUEST_R10(%rsp);				\
5958a6aaf7STycho Nightingale	movq	%r11,VMXCTX_GUEST_R11(%rsp);				\
6058a6aaf7STycho Nightingale	movq	%r12,VMXCTX_GUEST_R12(%rsp);				\
6158a6aaf7STycho Nightingale	movq	%r13,VMXCTX_GUEST_R13(%rsp);				\
6258a6aaf7STycho Nightingale	movq	%r14,VMXCTX_GUEST_R14(%rsp);				\
6358a6aaf7STycho Nightingale	movq	%r15,VMXCTX_GUEST_R15(%rsp);				\
6458a6aaf7STycho Nightingale	movq	%cr2,%rdi;						\
6558a6aaf7STycho Nightingale	movq	%rdi,VMXCTX_GUEST_CR2(%rsp);				\
6658a6aaf7STycho Nightingale	movq	%rsp,%rdi;
6758a6aaf7STycho Nightingale
6858a6aaf7STycho Nightingale/*
69ad54f374SNeel Natu * Assumes that %rdi holds a pointer to the 'vmxctx'.
70ad54f374SNeel Natu *
71ad54f374SNeel Natu * On "return" all registers are updated to reflect guest state. The two
72ad54f374SNeel Natu * exceptions are %rip and %rsp. These registers are atomically switched
73ad54f374SNeel Natu * by hardware from the guest area of the vmcs.
74ad54f374SNeel Natu *
75ad54f374SNeel Natu * We modify %rsp to point to the 'vmxctx' so we can use it to restore
76ad54f374SNeel Natu * host context in case of an error with 'vmlaunch' or 'vmresume'.
77366f6083SPeter Grehan */
78366f6083SPeter Grehan#define	VMX_GUEST_RESTORE						\
79ad54f374SNeel Natu	movq	%rdi,%rsp;						\
80366f6083SPeter Grehan	movq	VMXCTX_GUEST_CR2(%rdi),%rsi;				\
81366f6083SPeter Grehan	movq	%rsi,%cr2;						\
82366f6083SPeter Grehan	movq	VMXCTX_GUEST_RSI(%rdi),%rsi;				\
83366f6083SPeter Grehan	movq	VMXCTX_GUEST_RDX(%rdi),%rdx;				\
84366f6083SPeter Grehan	movq	VMXCTX_GUEST_RCX(%rdi),%rcx;				\
85366f6083SPeter Grehan	movq	VMXCTX_GUEST_R8(%rdi),%r8;				\
86366f6083SPeter Grehan	movq	VMXCTX_GUEST_R9(%rdi),%r9;				\
87366f6083SPeter Grehan	movq	VMXCTX_GUEST_RAX(%rdi),%rax;				\
88366f6083SPeter Grehan	movq	VMXCTX_GUEST_RBX(%rdi),%rbx;				\
89366f6083SPeter Grehan	movq	VMXCTX_GUEST_RBP(%rdi),%rbp;				\
90366f6083SPeter Grehan	movq	VMXCTX_GUEST_R10(%rdi),%r10;				\
91366f6083SPeter Grehan	movq	VMXCTX_GUEST_R11(%rdi),%r11;				\
92366f6083SPeter Grehan	movq	VMXCTX_GUEST_R12(%rdi),%r12;				\
93366f6083SPeter Grehan	movq	VMXCTX_GUEST_R13(%rdi),%r13;				\
94366f6083SPeter Grehan	movq	VMXCTX_GUEST_R14(%rdi),%r14;				\
95366f6083SPeter Grehan	movq	VMXCTX_GUEST_R15(%rdi),%r15;				\
96366f6083SPeter Grehan	movq	VMXCTX_GUEST_RDI(%rdi),%rdi; /* restore rdi the last */
97366f6083SPeter Grehan
98318224bbSNeel Natu/*
9991fe5fe7STycho Nightingale * Clobber the remaining registers with guest contents so they can't
10091fe5fe7STycho Nightingale * be misused.
10191fe5fe7STycho Nightingale */
10291fe5fe7STycho Nightingale#define	VMX_GUEST_CLOBBER						\
10391fe5fe7STycho Nightingale	xor	%rax, %rax;						\
10491fe5fe7STycho Nightingale	xor	%rcx, %rcx;						\
10591fe5fe7STycho Nightingale	xor	%rdx, %rdx;						\
10691fe5fe7STycho Nightingale	xor	%rsi, %rsi;						\
10791fe5fe7STycho Nightingale	xor	%r8, %r8;						\
10891fe5fe7STycho Nightingale	xor	%r9, %r9;						\
10991fe5fe7STycho Nightingale	xor	%r10, %r10;						\
11091fe5fe7STycho Nightingale	xor	%r11, %r11;
11191fe5fe7STycho Nightingale
11291fe5fe7STycho Nightingale/*
1130492757cSNeel Natu * Save and restore the host context.
1140492757cSNeel Natu *
1150492757cSNeel Natu * Assumes that %rdi holds a pointer to the 'vmxctx'.
116318224bbSNeel Natu */
11781d597b7SNeel Natu#define	VMX_HOST_SAVE							\
1180492757cSNeel Natu	movq    %r15, VMXCTX_HOST_R15(%rdi);				\
1190492757cSNeel Natu	movq    %r14, VMXCTX_HOST_R14(%rdi);				\
1200492757cSNeel Natu	movq    %r13, VMXCTX_HOST_R13(%rdi);				\
1210492757cSNeel Natu	movq    %r12, VMXCTX_HOST_R12(%rdi);				\
1220492757cSNeel Natu	movq    %rbp, VMXCTX_HOST_RBP(%rdi);				\
1230492757cSNeel Natu	movq    %rsp, VMXCTX_HOST_RSP(%rdi);				\
1240492757cSNeel Natu	movq    %rbx, VMXCTX_HOST_RBX(%rdi);				\
1250492757cSNeel Natu
12681d597b7SNeel Natu#define	VMX_HOST_RESTORE						\
1270492757cSNeel Natu	movq	VMXCTX_HOST_R15(%rdi), %r15;				\
1280492757cSNeel Natu	movq	VMXCTX_HOST_R14(%rdi), %r14;				\
1290492757cSNeel Natu	movq	VMXCTX_HOST_R13(%rdi), %r13;				\
1300492757cSNeel Natu	movq	VMXCTX_HOST_R12(%rdi), %r12;				\
1310492757cSNeel Natu	movq	VMXCTX_HOST_RBP(%rdi), %rbp;				\
1320492757cSNeel Natu	movq	VMXCTX_HOST_RSP(%rdi), %rsp;				\
1330492757cSNeel Natu	movq	VMXCTX_HOST_RBX(%rdi), %rbx;				\
134318224bbSNeel Natu
135318224bbSNeel Natu/*
1360492757cSNeel Natu * vmx_enter_guest(struct vmxctx *vmxctx, int launched)
1370492757cSNeel Natu * %rdi: pointer to the 'vmxctx'
138953c2c47SNeel Natu * %rsi: pointer to the 'vmx'
139953c2c47SNeel Natu * %edx: launch state of the VMCS
1400492757cSNeel Natu * Interrupts must be disabled on entry.
141318224bbSNeel Natu */
1420492757cSNeel NatuENTRY(vmx_enter_guest)
143897bb47eSPeter Grehan	VENTER
1440492757cSNeel Natu	/*
1450492757cSNeel Natu	 * Save host state before doing anything else.
1460492757cSNeel Natu	 */
14781d597b7SNeel Natu	VMX_HOST_SAVE
148318224bbSNeel Natu
1490492757cSNeel Natuguest_restore:
150c30578feSKonstantin Belousov	movl	%edx, %r8d
151c1141fbaSKonstantin Belousov	cmpb	$0, guest_l1d_flush_sw(%rip)
152c30578feSKonstantin Belousov	je	after_l1d
153c1141fbaSKonstantin Belousov	call	flush_l1d_sw
154c30578feSKonstantin Belousovafter_l1d:
155c30578feSKonstantin Belousov	cmpl	$0, %r8d
156c30578feSKonstantin Belousov	je	do_launch
1570492757cSNeel Natu	VMX_GUEST_RESTORE
1580492757cSNeel Natu	vmresume
1590492757cSNeel Natu	/*
1600492757cSNeel Natu	 * In the common case 'vmresume' returns back to the host through
1610492757cSNeel Natu	 * 'vmx_exit_guest' with %rsp pointing to 'vmxctx'.
162318224bbSNeel Natu	 *
1630492757cSNeel Natu	 * If there is an error we return VMX_VMRESUME_ERROR to the caller.
164318224bbSNeel Natu	 */
1650492757cSNeel Natu	movq	%rsp, %rdi		/* point %rdi back to 'vmxctx' */
1660492757cSNeel Natu	movl	$VMX_VMRESUME_ERROR, %eax
1670492757cSNeel Natu	jmp	decode_inst_error
168366f6083SPeter Grehan
1690492757cSNeel Natudo_launch:
1700492757cSNeel Natu	VMX_GUEST_RESTORE
1710492757cSNeel Natu	vmlaunch
172366f6083SPeter Grehan	/*
1730492757cSNeel Natu	 * In the common case 'vmlaunch' returns back to the host through
1740492757cSNeel Natu	 * 'vmx_exit_guest' with %rsp pointing to 'vmxctx'.
175366f6083SPeter Grehan	 *
1760492757cSNeel Natu	 * If there is an error we return VMX_VMLAUNCH_ERROR to the caller.
177366f6083SPeter Grehan	 */
1780492757cSNeel Natu	movq	%rsp, %rdi		/* point %rdi back to 'vmxctx' */
1790492757cSNeel Natu	movl	$VMX_VMLAUNCH_ERROR, %eax
1800492757cSNeel Natu	jmp	decode_inst_error
1810492757cSNeel Natu
1820492757cSNeel Natudecode_inst_error:
1830492757cSNeel Natu	movl	$VM_FAIL_VALID, %r11d
1840492757cSNeel Natu	jz	inst_error
1850492757cSNeel Natu	movl	$VM_FAIL_INVALID, %r11d
1860492757cSNeel Natuinst_error:
1870492757cSNeel Natu	movl	%r11d, VMXCTX_INST_FAIL_STATUS(%rdi)
188366f6083SPeter Grehan
189366f6083SPeter Grehan	/*
1900492757cSNeel Natu	 * The return value is already populated in %eax so we cannot use
1910492757cSNeel Natu	 * it as a scratch register beyond this point.
192366f6083SPeter Grehan	 */
1930492757cSNeel Natu
19481d597b7SNeel Natu	VMX_HOST_RESTORE
195897bb47eSPeter Grehan	VLEAVE
196366f6083SPeter Grehan	ret
197366f6083SPeter Grehan
198366f6083SPeter Grehan/*
199897bb47eSPeter Grehan * Non-error VM-exit from the guest. Make this a label so it can
200897bb47eSPeter Grehan * be used by C code when setting up the VMCS.
201897bb47eSPeter Grehan * The VMCS-restored %rsp points to the struct vmxctx
202366f6083SPeter Grehan */
203897bb47eSPeter Grehan	ALIGN_TEXT
20458a6aaf7STycho Nightingale	.globl	vmx_exit_guest_flush_rsb
20558a6aaf7STycho Nightingalevmx_exit_guest_flush_rsb:
20658a6aaf7STycho Nightingale	/*
20758a6aaf7STycho Nightingale	 * Save guest state that is not automatically saved in the vmcs.
20858a6aaf7STycho Nightingale	 */
20958a6aaf7STycho Nightingale	VMX_GUEST_SAVE
21058a6aaf7STycho Nightingale
21158a6aaf7STycho Nightingale	VMX_HOST_RESTORE
21258a6aaf7STycho Nightingale
21358a6aaf7STycho Nightingale	VMX_GUEST_CLOBBER
21458a6aaf7STycho Nightingale
21558a6aaf7STycho Nightingale	/*
21658a6aaf7STycho Nightingale	 * To prevent malicious branch target predictions from
21758a6aaf7STycho Nightingale	 * affecting the host, overwrite all entries in the RSB upon
21858a6aaf7STycho Nightingale	 * exiting a guest.
21958a6aaf7STycho Nightingale	 */
22058a6aaf7STycho Nightingale	mov	$16, %ecx	/* 16 iterations, two calls per loop */
22158a6aaf7STycho Nightingale	mov	%rsp, %rax
22258a6aaf7STycho Nightingale0:	call	2f		/* create an RSB entry. */
22358a6aaf7STycho Nightingale1:	pause
22458a6aaf7STycho Nightingale	call	1b		/* capture rogue speculation. */
22558a6aaf7STycho Nightingale2:	call	2f		/* create an RSB entry. */
22658a6aaf7STycho Nightingale1:	pause
22758a6aaf7STycho Nightingale	call	1b		/* capture rogue speculation. */
22858a6aaf7STycho Nightingale2:	sub	$1, %ecx
22958a6aaf7STycho Nightingale	jnz	0b
23058a6aaf7STycho Nightingale	mov	%rax, %rsp
23158a6aaf7STycho Nightingale
23258a6aaf7STycho Nightingale	/*
23358a6aaf7STycho Nightingale	 * This will return to the caller of 'vmx_enter_guest()' with a return
23458a6aaf7STycho Nightingale	 * value of VMX_GUEST_VMEXIT.
23558a6aaf7STycho Nightingale	 */
23658a6aaf7STycho Nightingale	movl	$VMX_GUEST_VMEXIT, %eax
23758a6aaf7STycho Nightingale	VLEAVE
23858a6aaf7STycho Nightingale	ret
23958a6aaf7STycho Nightingale
240897bb47eSPeter Grehan	.globl	vmx_exit_guest
241897bb47eSPeter Grehanvmx_exit_guest:
242366f6083SPeter Grehan	/*
243366f6083SPeter Grehan	 * Save guest state that is not automatically saved in the vmcs.
244366f6083SPeter Grehan	 */
24558a6aaf7STycho Nightingale	VMX_GUEST_SAVE
246366f6083SPeter Grehan
24781d597b7SNeel Natu	VMX_HOST_RESTORE
248318224bbSNeel Natu
24991fe5fe7STycho Nightingale	VMX_GUEST_CLOBBER
25091fe5fe7STycho Nightingale
251366f6083SPeter Grehan	/*
2520492757cSNeel Natu	 * This will return to the caller of 'vmx_enter_guest()' with a return
2530492757cSNeel Natu	 * value of VMX_GUEST_VMEXIT.
254366f6083SPeter Grehan	 */
2550492757cSNeel Natu	movl	$VMX_GUEST_VMEXIT, %eax
256897bb47eSPeter Grehan	VLEAVE
2570492757cSNeel Natu	ret
258897bb47eSPeter GrehanEND(vmx_enter_guest)
259f7d47425SNeel Natu
260f7d47425SNeel Natu/*
261f7d47425SNeel Natu * %rdi = interrupt handler entry point
262f7d47425SNeel Natu *
263f7d47425SNeel Natu * Calling sequence described in the "Instruction Set Reference" for the "INT"
264f7d47425SNeel Natu * instruction in Intel SDM, Vol 2.
265f7d47425SNeel Natu */
266f7d47425SNeel NatuENTRY(vmx_call_isr)
267897bb47eSPeter Grehan	VENTER
268f7d47425SNeel Natu	mov	%rsp, %r11			/* save %rsp */
269f7d47425SNeel Natu	and	$~0xf, %rsp			/* align on 16-byte boundary */
270f7d47425SNeel Natu	pushq	$KERNEL_SS			/* %ss */
271f7d47425SNeel Natu	pushq	%r11				/* %rsp */
272f7d47425SNeel Natu	pushfq					/* %rflags */
273f7d47425SNeel Natu	pushq	$KERNEL_CS			/* %cs */
274f7d47425SNeel Natu	cli					/* disable interrupts */
275f7d47425SNeel Natu	callq	*%rdi				/* push %rip and call isr */
276897bb47eSPeter Grehan	VLEAVE
277f7d47425SNeel Natu	ret
278f7d47425SNeel NatuEND(vmx_call_isr)
279