xref: /illumos-gate/usr/src/uts/intel/io/vmm/amd/vmcb.h (revision 32640292)
14c87aefeSPatrick Mooney /*-
2*32640292SAndy Fiddaman  * SPDX-License-Identifier: BSD-2-Clause
34c87aefeSPatrick Mooney  *
44c87aefeSPatrick Mooney  * Copyright (c) 2013 Anish Gupta (akgupt3@gmail.com)
54c87aefeSPatrick Mooney  * All rights reserved.
64c87aefeSPatrick Mooney  *
74c87aefeSPatrick Mooney  * Redistribution and use in source and binary forms, with or without
84c87aefeSPatrick Mooney  * modification, are permitted provided that the following conditions
94c87aefeSPatrick Mooney  * are met:
104c87aefeSPatrick Mooney  * 1. Redistributions of source code must retain the above copyright
114c87aefeSPatrick Mooney  *    notice unmodified, this list of conditions, and the following
124c87aefeSPatrick Mooney  *    disclaimer.
134c87aefeSPatrick Mooney  * 2. Redistributions in binary form must reproduce the above copyright
144c87aefeSPatrick Mooney  *    notice, this list of conditions and the following disclaimer in the
154c87aefeSPatrick Mooney  *    documentation and/or other materials provided with the distribution.
164c87aefeSPatrick Mooney  *
174c87aefeSPatrick Mooney  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
184c87aefeSPatrick Mooney  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
194c87aefeSPatrick Mooney  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
204c87aefeSPatrick Mooney  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
214c87aefeSPatrick Mooney  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
224c87aefeSPatrick Mooney  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234c87aefeSPatrick Mooney  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244c87aefeSPatrick Mooney  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254c87aefeSPatrick Mooney  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
264c87aefeSPatrick Mooney  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274c87aefeSPatrick Mooney  */
284c87aefeSPatrick Mooney 
29a517c69dSPatrick Mooney /*
30a517c69dSPatrick Mooney  * This file and its contents are supplied under the terms of the
31a517c69dSPatrick Mooney  * Common Development and Distribution License ("CDDL"), version 1.0.
32a517c69dSPatrick Mooney  * You may only use this file in accordance with the terms of version
33a517c69dSPatrick Mooney  * 1.0 of the CDDL.
34a517c69dSPatrick Mooney  *
35a517c69dSPatrick Mooney  * A full copy of the text of the CDDL should have accompanied this
36a517c69dSPatrick Mooney  * source.  A copy of the CDDL is also available via the Internet at
37a517c69dSPatrick Mooney  * http://www.illumos.org/license/CDDL.
38a517c69dSPatrick Mooney  *
393d097f7dSPatrick Mooney  * Copyright 2022 Oxide Computer Company
40a517c69dSPatrick Mooney  */
41a517c69dSPatrick Mooney 
424c87aefeSPatrick Mooney #ifndef _VMCB_H_
434c87aefeSPatrick Mooney #define	_VMCB_H_
444c87aefeSPatrick Mooney 
454c87aefeSPatrick Mooney struct svm_softc;
464c87aefeSPatrick Mooney 
472699b94cSPatrick Mooney #define	BIT(n)			(1ULL << n)
484c87aefeSPatrick Mooney 
494c87aefeSPatrick Mooney /*
504c87aefeSPatrick Mooney  * Secure Virtual Machine: AMD64 Programmer's Manual Vol2, Chapter 15
514c87aefeSPatrick Mooney  * Layout of VMCB: AMD64 Programmer's Manual Vol2, Appendix B
524c87aefeSPatrick Mooney  */
534c87aefeSPatrick Mooney 
544c87aefeSPatrick Mooney /* vmcb_ctrl->intercept[] array indices */
554c87aefeSPatrick Mooney #define	VMCB_CR_INTCPT		0
564c87aefeSPatrick Mooney #define	VMCB_DR_INTCPT		1
574c87aefeSPatrick Mooney #define	VMCB_EXC_INTCPT		2
584c87aefeSPatrick Mooney #define	VMCB_CTRL1_INTCPT	3
594c87aefeSPatrick Mooney #define	VMCB_CTRL2_INTCPT	4
604c87aefeSPatrick Mooney 
614c87aefeSPatrick Mooney /* intercept[VMCB_CTRL1_INTCPT] fields */
624c87aefeSPatrick Mooney #define	VMCB_INTCPT_INTR		BIT(0)
634c87aefeSPatrick Mooney #define	VMCB_INTCPT_NMI			BIT(1)
644c87aefeSPatrick Mooney #define	VMCB_INTCPT_SMI			BIT(2)
654c87aefeSPatrick Mooney #define	VMCB_INTCPT_INIT		BIT(3)
664c87aefeSPatrick Mooney #define	VMCB_INTCPT_VINTR		BIT(4)
674c87aefeSPatrick Mooney #define	VMCB_INTCPT_CR0_WRITE		BIT(5)
684c87aefeSPatrick Mooney #define	VMCB_INTCPT_IDTR_READ		BIT(6)
694c87aefeSPatrick Mooney #define	VMCB_INTCPT_GDTR_READ		BIT(7)
704c87aefeSPatrick Mooney #define	VMCB_INTCPT_LDTR_READ		BIT(8)
714c87aefeSPatrick Mooney #define	VMCB_INTCPT_TR_READ		BIT(9)
724c87aefeSPatrick Mooney #define	VMCB_INTCPT_IDTR_WRITE		BIT(10)
734c87aefeSPatrick Mooney #define	VMCB_INTCPT_GDTR_WRITE		BIT(11)
744c87aefeSPatrick Mooney #define	VMCB_INTCPT_LDTR_WRITE		BIT(12)
754c87aefeSPatrick Mooney #define	VMCB_INTCPT_TR_WRITE		BIT(13)
764c87aefeSPatrick Mooney #define	VMCB_INTCPT_RDTSC		BIT(14)
774c87aefeSPatrick Mooney #define	VMCB_INTCPT_RDPMC		BIT(15)
784c87aefeSPatrick Mooney #define	VMCB_INTCPT_PUSHF		BIT(16)
794c87aefeSPatrick Mooney #define	VMCB_INTCPT_POPF		BIT(17)
804c87aefeSPatrick Mooney #define	VMCB_INTCPT_CPUID		BIT(18)
814c87aefeSPatrick Mooney #define	VMCB_INTCPT_RSM			BIT(19)
824c87aefeSPatrick Mooney #define	VMCB_INTCPT_IRET		BIT(20)
834c87aefeSPatrick Mooney #define	VMCB_INTCPT_INTn		BIT(21)
844c87aefeSPatrick Mooney #define	VMCB_INTCPT_INVD		BIT(22)
854c87aefeSPatrick Mooney #define	VMCB_INTCPT_PAUSE		BIT(23)
864c87aefeSPatrick Mooney #define	VMCB_INTCPT_HLT			BIT(24)
878c2fd2ffSPatrick Mooney #define	VMCB_INTCPT_INVLPG		BIT(25)
888c2fd2ffSPatrick Mooney #define	VMCB_INTCPT_INVLPGA		BIT(26)
894c87aefeSPatrick Mooney #define	VMCB_INTCPT_IO			BIT(27)
904c87aefeSPatrick Mooney #define	VMCB_INTCPT_MSR			BIT(28)
914c87aefeSPatrick Mooney #define	VMCB_INTCPT_TASK_SWITCH		BIT(29)
924c87aefeSPatrick Mooney #define	VMCB_INTCPT_FERR_FREEZE		BIT(30)
934c87aefeSPatrick Mooney #define	VMCB_INTCPT_SHUTDOWN		BIT(31)
944c87aefeSPatrick Mooney 
954c87aefeSPatrick Mooney /* intercept[VMCB_CTRL2_INTCPT] fields */
964c87aefeSPatrick Mooney #define	VMCB_INTCPT_VMRUN		BIT(0)
974c87aefeSPatrick Mooney #define	VMCB_INTCPT_VMMCALL		BIT(1)
984c87aefeSPatrick Mooney #define	VMCB_INTCPT_VMLOAD		BIT(2)
994c87aefeSPatrick Mooney #define	VMCB_INTCPT_VMSAVE		BIT(3)
1004c87aefeSPatrick Mooney #define	VMCB_INTCPT_STGI		BIT(4)
1014c87aefeSPatrick Mooney #define	VMCB_INTCPT_CLGI		BIT(5)
1024c87aefeSPatrick Mooney #define	VMCB_INTCPT_SKINIT		BIT(6)
1034c87aefeSPatrick Mooney #define	VMCB_INTCPT_RDTSCP		BIT(7)
1044c87aefeSPatrick Mooney #define	VMCB_INTCPT_ICEBP		BIT(8)
1054c87aefeSPatrick Mooney #define	VMCB_INTCPT_WBINVD		BIT(9)
1064c87aefeSPatrick Mooney #define	VMCB_INTCPT_MONITOR		BIT(10)
1074c87aefeSPatrick Mooney #define	VMCB_INTCPT_MWAIT		BIT(11)
1084c87aefeSPatrick Mooney #define	VMCB_INTCPT_MWAIT_ARMED		BIT(12)
1094c87aefeSPatrick Mooney #define	VMCB_INTCPT_XSETBV		BIT(13)
1104c87aefeSPatrick Mooney 
1114c87aefeSPatrick Mooney /* VMCB TLB control */
1124c87aefeSPatrick Mooney #define	VMCB_TLB_FLUSH_NOTHING		0	/* Flush nothing */
1134c87aefeSPatrick Mooney #define	VMCB_TLB_FLUSH_ALL		1	/* Flush entire TLB */
1144c87aefeSPatrick Mooney #define	VMCB_TLB_FLUSH_GUEST		3	/* Flush all guest entries */
1154c87aefeSPatrick Mooney #define	VMCB_TLB_FLUSH_GUEST_NONGLOBAL	7	/* Flush guest non-PG entries */
1164c87aefeSPatrick Mooney 
1174c87aefeSPatrick Mooney /* VMCB state caching */
1184c87aefeSPatrick Mooney #define	VMCB_CACHE_NONE		0	/* No caching */
1194c87aefeSPatrick Mooney #define	VMCB_CACHE_I		BIT(0)	/* Intercept, TSC off, Pause filter */
1204c87aefeSPatrick Mooney #define	VMCB_CACHE_IOPM		BIT(1)	/* I/O and MSR permission */
1214c87aefeSPatrick Mooney #define	VMCB_CACHE_ASID		BIT(2)	/* ASID */
1224c87aefeSPatrick Mooney #define	VMCB_CACHE_TPR		BIT(3)	/* V_TPR to V_INTR_VECTOR */
1234c87aefeSPatrick Mooney #define	VMCB_CACHE_NP		BIT(4)	/* Nested Paging */
1244c87aefeSPatrick Mooney #define	VMCB_CACHE_CR		BIT(5)	/* CR0, CR3, CR4 & EFER */
1254c87aefeSPatrick Mooney #define	VMCB_CACHE_DR		BIT(6)	/* Debug registers */
1264c87aefeSPatrick Mooney #define	VMCB_CACHE_DT		BIT(7)	/* GDT/IDT */
1274c87aefeSPatrick Mooney #define	VMCB_CACHE_SEG		BIT(8)	/* User segments, CPL */
1284c87aefeSPatrick Mooney #define	VMCB_CACHE_CR2		BIT(9)	/* page fault address */
1294c87aefeSPatrick Mooney #define	VMCB_CACHE_LBR		BIT(10)	/* Last branch */
1304c87aefeSPatrick Mooney 
1314c87aefeSPatrick Mooney /* VMCB control event injection */
1324c87aefeSPatrick Mooney #define	VMCB_EVENTINJ_EC_VALID		BIT(11)	/* Error Code valid */
1334c87aefeSPatrick Mooney #define	VMCB_EVENTINJ_VALID		BIT(31)	/* Event valid */
1344c87aefeSPatrick Mooney 
1354c87aefeSPatrick Mooney /* Event types that can be injected */
1364c87aefeSPatrick Mooney #define	VMCB_EVENTINJ_TYPE_INTR		0
137c74a40a5SPatrick Mooney #define	VMCB_EVENTINJ_TYPE_NMI		(2 << 8)
138c74a40a5SPatrick Mooney #define	VMCB_EVENTINJ_TYPE_EXCEPTION	(3 << 8)
139c74a40a5SPatrick Mooney #define	VMCB_EVENTINJ_TYPE_INTn		(4 << 8)
1404c87aefeSPatrick Mooney 
1414c87aefeSPatrick Mooney /* VMCB exit code, APM vol2 Appendix C */
1427db0d193SPatrick Mooney #define	VMCB_EXIT_CR0_READ		0x00
1437db0d193SPatrick Mooney #define	VMCB_EXIT_CR15_READ		0x0f
1447db0d193SPatrick Mooney #define	VMCB_EXIT_CR0_WRITE		0x10
1457db0d193SPatrick Mooney #define	VMCB_EXIT_CR15_WRITE		0x1f
1463d097f7dSPatrick Mooney #define	VMCB_EXIT_EXCP0			0x40
1473d097f7dSPatrick Mooney #define	VMCB_EXIT_EXCP31		0x5f
1484c87aefeSPatrick Mooney #define	VMCB_EXIT_INTR			0x60
1494c87aefeSPatrick Mooney #define	VMCB_EXIT_NMI			0x61
1508269d05cSPatrick Mooney #define	VMCB_EXIT_SMI			0x62
1518269d05cSPatrick Mooney #define	VMCB_EXIT_INIT			0x63
1524c87aefeSPatrick Mooney #define	VMCB_EXIT_VINTR			0x64
1537db0d193SPatrick Mooney #define	VMCB_EXIT_CR0_SEL_WRITE		0x65
1544c87aefeSPatrick Mooney #define	VMCB_EXIT_PUSHF			0x70
1554c87aefeSPatrick Mooney #define	VMCB_EXIT_POPF			0x71
1564c87aefeSPatrick Mooney #define	VMCB_EXIT_CPUID			0x72
1574c87aefeSPatrick Mooney #define	VMCB_EXIT_IRET			0x74
1588c2fd2ffSPatrick Mooney #define	VMCB_EXIT_INVD			0x76
1594c87aefeSPatrick Mooney #define	VMCB_EXIT_PAUSE			0x77
1604c87aefeSPatrick Mooney #define	VMCB_EXIT_HLT			0x78
1618c2fd2ffSPatrick Mooney #define	VMCB_EXIT_INVLPG		0x79
1628c2fd2ffSPatrick Mooney #define	VMCB_EXIT_INVLPGA		0x7A
1634c87aefeSPatrick Mooney #define	VMCB_EXIT_IO			0x7B
1644c87aefeSPatrick Mooney #define	VMCB_EXIT_MSR			0x7C
1654c87aefeSPatrick Mooney #define	VMCB_EXIT_SHUTDOWN		0x7F
1668c2fd2ffSPatrick Mooney #define	VMCB_EXIT_VMRUN			0x80
1678c2fd2ffSPatrick Mooney #define	VMCB_EXIT_VMMCALL		0x81
1688c2fd2ffSPatrick Mooney #define	VMCB_EXIT_VMLOAD		0x82
1694c87aefeSPatrick Mooney #define	VMCB_EXIT_VMSAVE		0x83
1708c2fd2ffSPatrick Mooney #define	VMCB_EXIT_STGI			0x84
1718c2fd2ffSPatrick Mooney #define	VMCB_EXIT_CLGI			0x85
1728c2fd2ffSPatrick Mooney #define	VMCB_EXIT_SKINIT		0x86
1734f3f3e9aSAndy Fiddaman #define	VMCB_EXIT_WBINVD		0x89
1744c87aefeSPatrick Mooney #define	VMCB_EXIT_MONITOR		0x8A
1754c87aefeSPatrick Mooney #define	VMCB_EXIT_MWAIT			0x8B
1764c87aefeSPatrick Mooney #define	VMCB_EXIT_NPF			0x400
1774c87aefeSPatrick Mooney #define	VMCB_EXIT_INVALID		-1
1784c87aefeSPatrick Mooney 
1797db0d193SPatrick Mooney /*
1807db0d193SPatrick Mooney  * Move to/from CRx
1817db0d193SPatrick Mooney  * Bit definitions to decode EXITINFO1
1827db0d193SPatrick Mooney  */
1837db0d193SPatrick Mooney #define	VMCB_CRx_INFO1_GPR(x)		((x) & 0xf)
1847db0d193SPatrick Mooney #define	VMCB_CRx_INFO1_VALID(x)		((x) & (1UL << 63))
1857db0d193SPatrick Mooney 
1864c87aefeSPatrick Mooney /*
1874c87aefeSPatrick Mooney  * Nested page fault.
1884c87aefeSPatrick Mooney  * Bit definitions to decode EXITINFO1.
1894c87aefeSPatrick Mooney  */
1904c87aefeSPatrick Mooney #define	VMCB_NPF_INFO1_P		BIT(0) /* Nested page present. */
1914c87aefeSPatrick Mooney #define	VMCB_NPF_INFO1_W		BIT(1) /* Access was write. */
1924c87aefeSPatrick Mooney #define	VMCB_NPF_INFO1_U		BIT(2) /* Access was user access. */
1934c87aefeSPatrick Mooney #define	VMCB_NPF_INFO1_RSV		BIT(3) /* Reserved bits present. */
1944c87aefeSPatrick Mooney #define	VMCB_NPF_INFO1_ID		BIT(4) /* Code read. */
1954c87aefeSPatrick Mooney 
1964c87aefeSPatrick Mooney #define	VMCB_NPF_INFO1_GPA		BIT(32) /* Guest physical address. */
1974c87aefeSPatrick Mooney #define	VMCB_NPF_INFO1_GPT		BIT(33) /* Guest page table. */
1984c87aefeSPatrick Mooney 
1994c87aefeSPatrick Mooney /*
2004c87aefeSPatrick Mooney  * EXITINTINFO, Interrupt exit info for all intrecepts.
2014c87aefeSPatrick Mooney  * Section 15.7.2, Intercepts during IDT Interrupt Delivery.
2024c87aefeSPatrick Mooney  */
2032699b94cSPatrick Mooney #define	VMCB_EXITINTINFO_VECTOR(x)	((x) & 0xFF)
2042699b94cSPatrick Mooney #define	VMCB_EXITINTINFO_TYPE(x)	((x) & (0x7 << 8))
2052699b94cSPatrick Mooney #define	VMCB_EXITINTINFO_EC_VALID(x)	(((x) & BIT(11)) != 0)
2062699b94cSPatrick Mooney #define	VMCB_EXITINTINFO_VALID(x)	(((x) & BIT(31)) != 0)
2072699b94cSPatrick Mooney #define	VMCB_EXITINTINFO_EC(x)		(((x) >> 32) & 0xFFFFFFFF)
2084c87aefeSPatrick Mooney 
2094c87aefeSPatrick Mooney /* Offset of various VMCB fields. */
2104c87aefeSPatrick Mooney #define	VMCB_OFF_CTRL(x)		(x)
2114c87aefeSPatrick Mooney #define	VMCB_OFF_STATE(x)		((x) + 0x400)
2124c87aefeSPatrick Mooney 
2134c87aefeSPatrick Mooney #define	VMCB_OFF_CR_INTERCEPT		VMCB_OFF_CTRL(0x0)
2144c87aefeSPatrick Mooney #define	VMCB_OFF_DR_INTERCEPT		VMCB_OFF_CTRL(0x4)
2154c87aefeSPatrick Mooney #define	VMCB_OFF_EXC_INTERCEPT		VMCB_OFF_CTRL(0x8)
2164c87aefeSPatrick Mooney #define	VMCB_OFF_INST1_INTERCEPT	VMCB_OFF_CTRL(0xC)
2174c87aefeSPatrick Mooney #define	VMCB_OFF_INST2_INTERCEPT	VMCB_OFF_CTRL(0x10)
2184c87aefeSPatrick Mooney #define	VMCB_OFF_IO_PERM		VMCB_OFF_CTRL(0x40)
2194c87aefeSPatrick Mooney #define	VMCB_OFF_MSR_PERM		VMCB_OFF_CTRL(0x48)
2204c87aefeSPatrick Mooney #define	VMCB_OFF_TSC_OFFSET		VMCB_OFF_CTRL(0x50)
2214c87aefeSPatrick Mooney #define	VMCB_OFF_ASID			VMCB_OFF_CTRL(0x58)
2224c87aefeSPatrick Mooney #define	VMCB_OFF_TLB_CTRL		VMCB_OFF_CTRL(0x5C)
2234c87aefeSPatrick Mooney #define	VMCB_OFF_VIRQ			VMCB_OFF_CTRL(0x60)
2244c87aefeSPatrick Mooney #define	VMCB_OFF_EXIT_REASON		VMCB_OFF_CTRL(0x70)
2254c87aefeSPatrick Mooney #define	VMCB_OFF_EXITINFO1		VMCB_OFF_CTRL(0x78)
2264c87aefeSPatrick Mooney #define	VMCB_OFF_EXITINFO2		VMCB_OFF_CTRL(0x80)
2274c87aefeSPatrick Mooney #define	VMCB_OFF_EXITINTINFO		VMCB_OFF_CTRL(0x88)
2284c87aefeSPatrick Mooney #define	VMCB_OFF_AVIC_BAR		VMCB_OFF_CTRL(0x98)
2294c87aefeSPatrick Mooney #define	VMCB_OFF_NPT_BASE		VMCB_OFF_CTRL(0xB0)
2304c87aefeSPatrick Mooney #define	VMCB_OFF_AVIC_PAGE		VMCB_OFF_CTRL(0xE0)
2314c87aefeSPatrick Mooney #define	VMCB_OFF_AVIC_LT		VMCB_OFF_CTRL(0xF0)
2324c87aefeSPatrick Mooney #define	VMCB_OFF_AVIC_PT		VMCB_OFF_CTRL(0xF8)
2334c87aefeSPatrick Mooney #define	VMCB_OFF_SYSENTER_CS		VMCB_OFF_STATE(0x228)
2344c87aefeSPatrick Mooney #define	VMCB_OFF_SYSENTER_ESP		VMCB_OFF_STATE(0x230)
2354c87aefeSPatrick Mooney #define	VMCB_OFF_SYSENTER_EIP		VMCB_OFF_STATE(0x238)
2364c87aefeSPatrick Mooney #define	VMCB_OFF_GUEST_PAT		VMCB_OFF_STATE(0x268)
2374c87aefeSPatrick Mooney 
2384c87aefeSPatrick Mooney #ifdef _KERNEL
2394c87aefeSPatrick Mooney /* VMCB save state area segment format */
2404c87aefeSPatrick Mooney struct vmcb_segment {
2414c87aefeSPatrick Mooney 	uint16_t	selector;
2424c87aefeSPatrick Mooney 	uint16_t	attrib;
2434c87aefeSPatrick Mooney 	uint32_t	limit;
2444c87aefeSPatrick Mooney 	uint64_t	base;
245a517c69dSPatrick Mooney };
2462699b94cSPatrick Mooney CTASSERT(sizeof (struct vmcb_segment) == 16);
2474c87aefeSPatrick Mooney 
248096bb5cbSPatrick Mooney /* Convert to/from vmcb segment access to generic (VMX) access */
249096bb5cbSPatrick Mooney #define	VMCB_ATTR2ACCESS(attr)	((((attr) & 0xf00) << 4) | ((attr) & 0xff))
250096bb5cbSPatrick Mooney #define	VMCB_ACCESS2ATTR(acc)	((((acc) & 0xf000) >> 4) | ((acc) & 0xff))
251096bb5cbSPatrick Mooney 
2524c87aefeSPatrick Mooney /* Code segment descriptor attribute in 12 bit format as saved by VMCB. */
2534c87aefeSPatrick Mooney #define	VMCB_CS_ATTRIB_L		BIT(9)	/* Long mode. */
2544c87aefeSPatrick Mooney #define	VMCB_CS_ATTRIB_D		BIT(10)	/* OPerand size bit. */
2554c87aefeSPatrick Mooney 
256a517c69dSPatrick Mooney /* Fields for Virtual Interrupt Control (v_irq) */
257a517c69dSPatrick Mooney #define	V_IRQ		BIT(0)	/* Offset 0x60 bit 8 (0x61 bit 0) */
258a517c69dSPatrick Mooney #define	V_VGIF_VALUE	BIT(1)	/* Offset 0x60 bit 9 (0x61 bit 1) */
259a517c69dSPatrick Mooney 
260a517c69dSPatrick Mooney /* Fields for Virtual Interrupt Control (v_intr_prio) */
261a517c69dSPatrick Mooney #define	V_INTR_PRIO	0xf	/* Offset 0x60 bits 16-19 (0x62 bits 0-3) */
262a517c69dSPatrick Mooney #define	V_IGN_TPR	BIT(4)	/* Offset 0x60 bit 20 (0x62 bit 4) */
263a517c69dSPatrick Mooney 
264a517c69dSPatrick Mooney /* Fields for Virtual Interrupt Control (v_intr_ctrl) */
265a517c69dSPatrick Mooney #define	V_INTR_MASKING	BIT(0)	/* Offset 0x60 bit 24 (0x63 bit 0) */
266a517c69dSPatrick Mooney #define	V_VGIF_ENABLE	BIT(1)	/* Offset 0x60 bit 25 (0x63 bit 1) */
267a517c69dSPatrick Mooney #define	V_AVIC_ENABLE	BIT(7)	/* Offset 0x60 bit 31 (0x63 bit 7) */
268a517c69dSPatrick Mooney 
269a517c69dSPatrick Mooney /* Fields in Interrupt Shadow, offset 0x68 */
270a517c69dSPatrick Mooney #define	VIRTUAL_INTR_SHADOW	BIT(0)
271a517c69dSPatrick Mooney #define	GUEST_INTERRUPT_MASK	BIT(1)
272a517c69dSPatrick Mooney 
273a517c69dSPatrick Mooney /* Fields in Nested Paging, offset 0x90 */
274a517c69dSPatrick Mooney #define	NP_ENABLE		BIT(0)	/* Enable nested paging */
275a517c69dSPatrick Mooney #define	SEV_ENABLE		BIT(1)	/* Enable SEV */
276a517c69dSPatrick Mooney #define	SEV_ES_ENABLE		BIT(2)	/* Enable SEV-ES */
277a517c69dSPatrick Mooney #define	GUEST_MODE_EXEC_TRAP	BIT(3)	/* Guest mode execute trap */
278a517c69dSPatrick Mooney #define	VIRT_TRANSPAR_ENCRYPT	BIT(5)	/* Virtual transparent encryption */
279a517c69dSPatrick Mooney 
280a517c69dSPatrick Mooney /* Fields in Misc virt controls, offset 0xB8 */
281a517c69dSPatrick Mooney #define	LBR_VIRT_ENABLE		BIT(0)	/* Enable LBR virtualization accel */
282a517c69dSPatrick Mooney #define	VIRT_VMSAVE_VMLOAD	BIT(1)	/* Virtualized VMSAVE/VMLOAD */
283a517c69dSPatrick Mooney 
2844c87aefeSPatrick Mooney /*
2854c87aefeSPatrick Mooney  * The VMCB is divided into two areas - the first one contains various
2864c87aefeSPatrick Mooney  * control bits including the intercept vector and the second one contains
2874c87aefeSPatrick Mooney  * the guest state.
2884c87aefeSPatrick Mooney  */
2894c87aefeSPatrick Mooney 
2904c87aefeSPatrick Mooney /* VMCB control area - padded up to 1024 bytes */
2914c87aefeSPatrick Mooney struct vmcb_ctrl {
292a517c69dSPatrick Mooney 	uint32_t intercept[5];	/* 0x00-0x13: all intercepts */
293a517c69dSPatrick Mooney 	uint32_t _pad1[10];	/* 0x14-0x3B: Reserved. */
294a517c69dSPatrick Mooney 	uint32_t pause_ctrl;	/* 0x3C, PAUSE filter thresh/count */
2954c87aefeSPatrick Mooney 	uint64_t iopm_base_pa;	/* 0x40: IOPM_BASE_PA */
2964c87aefeSPatrick Mooney 	uint64_t msrpm_base_pa; /* 0x48: MSRPM_BASE_PA */
2974c87aefeSPatrick Mooney 	uint64_t tsc_offset;	/* 0x50: TSC_OFFSET */
2984c87aefeSPatrick Mooney 	uint32_t asid;		/* 0x58: Guest ASID */
299a517c69dSPatrick Mooney 	uint8_t tlb_ctrl;	/* 0x5C: TLB_CONTROL */
300a517c69dSPatrick Mooney 	uint8_t _pad2[3];	/* 0x5D-0x5F: Reserved. */
301a517c69dSPatrick Mooney 	uint8_t v_tpr;		/* 0x60: Virtual TPR */
302a517c69dSPatrick Mooney 	uint8_t v_irq;		/* 0x61: V_IRQ, V_GIF_VALUE + Reserved */
303a517c69dSPatrick Mooney 	uint8_t v_intr_prio;	/* 0x62: V_INTR_PRIO, V_IGN_TPR */
304a517c69dSPatrick Mooney 	uint8_t v_intr_ctrl;	/* 0x63: V_INTR_MASKING, vGIF and AVIC enable */
305a517c69dSPatrick Mooney 	uint8_t v_intr_vector;	/* 0x64: Virtual interrupt vector */
306a517c69dSPatrick Mooney 	uint8_t _pad3[3];	/* 0x65-0x67: Reserved */
307a517c69dSPatrick Mooney 	uint64_t intr_shadow;	/* 0x68: Interrupt shadow (and more) */
3084c87aefeSPatrick Mooney 	uint64_t exitcode;	/* 0x70, Exitcode */
3094c87aefeSPatrick Mooney 	uint64_t exitinfo1;	/* 0x78, EXITINFO1 */
3104c87aefeSPatrick Mooney 	uint64_t exitinfo2;	/* 0x80, EXITINFO2 */
3114c87aefeSPatrick Mooney 	uint64_t exitintinfo;	/* 0x88, Interrupt exit value. */
312a517c69dSPatrick Mooney 	uint64_t np_ctrl;	/* 0x90, Nested paging control. */
313a517c69dSPatrick Mooney 	uint64_t _pad4[2];	/* 0x98-0xA7 reserved. */
3144c87aefeSPatrick Mooney 	uint64_t eventinj;	/* 0xA8, Event injection. */
315a517c69dSPatrick Mooney 	uint64_t n_cr3;		/* 0xB0, Nested page table. */
316a517c69dSPatrick Mooney 	uint64_t misc_ctrl;	/* 0xB8, Misc virt controls */
3174c87aefeSPatrick Mooney 	uint32_t vmcb_clean;	/* 0xC0: VMCB clean bits for caching */
318a517c69dSPatrick Mooney 	uint32_t _pad5;		/* 0xC4: Reserved */
3194c87aefeSPatrick Mooney 	uint64_t nrip;		/* 0xC8: Guest next nRIP. */
320a517c69dSPatrick Mooney 	uint8_t inst_len;	/* 0xD0: #NPF decode assist */
321a517c69dSPatrick Mooney 	uint8_t inst_bytes[15]; /* 0xD1-0xDF: guest instr bytes */
322a517c69dSPatrick Mooney 	uint64_t avic_page_pa;	/* 0xEO: AVIC backing page */
323a517c69dSPatrick Mooney 	uint64_t _pad6;		/* 0xE8-0xEF: Reserved */
324a517c69dSPatrick Mooney 	uint64_t avic_log_tbl;	/* 0xFO: AVIC logical table */
325a517c69dSPatrick Mooney 	uint64_t avic_phys_tbl;	/* 0xF8: AVIC physical page */
326a517c69dSPatrick Mooney 	uint64_t _pad7;		/* 0x100-0x107: Reserved */
327a517c69dSPatrick Mooney 	uint64_t vmsa_pa;	/* 0x108: VMSA pointer */
328a517c69dSPatrick Mooney 	uint64_t _pad8[94];	/* 0x110-0x3FF: Reserved */
329a517c69dSPatrick Mooney };
3302699b94cSPatrick Mooney CTASSERT(sizeof (struct vmcb_ctrl) == 1024);
331a517c69dSPatrick Mooney CTASSERT(offsetof(struct vmcb_ctrl, vmsa_pa) == 0x108);
3324c87aefeSPatrick Mooney 
3334c87aefeSPatrick Mooney struct vmcb_state {
334a517c69dSPatrick Mooney 	struct vmcb_segment es;		/* 0x00: 32bit base */
335a517c69dSPatrick Mooney 	struct vmcb_segment cs;		/* 0x10: 32bit base */
336a517c69dSPatrick Mooney 	struct vmcb_segment ss;		/* 0x20: 32bit base */
337a517c69dSPatrick Mooney 	struct vmcb_segment ds;		/* 0x30: 32bit base */
338a517c69dSPatrick Mooney 	struct vmcb_segment fs;		/* 0x40 */
339a517c69dSPatrick Mooney 	struct vmcb_segment gs;		/* 0x50 */
340a517c69dSPatrick Mooney 	struct vmcb_segment gdt;	/* 0x60: base + 16bit limit */
341a517c69dSPatrick Mooney 	struct vmcb_segment ldt;	/* 0x70 */
342a517c69dSPatrick Mooney 	struct vmcb_segment idt;	/* 0x80: base + 16bit limit */
343a517c69dSPatrick Mooney 	struct vmcb_segment tr;		/* 0x90 */
344a517c69dSPatrick Mooney 	uint8_t _pad1[43];		/* 0xA0-0xCA: Reserved */
345a517c69dSPatrick Mooney 	uint8_t cpl;			/* 0xCB: CPL (real mode: 0, virt: 3) */
346a517c69dSPatrick Mooney 	uint32_t _pad2;			/* 0xCC-0xCF: Reserved */
347a517c69dSPatrick Mooney 	uint64_t efer;			/* 0xD0 */
348a517c69dSPatrick Mooney 	uint64_t _pad3[14];		/* 0xD8-0x147: Reserved */
349a517c69dSPatrick Mooney 	uint64_t cr4;			/* 0x148 */
350a517c69dSPatrick Mooney 	uint64_t cr3;			/* 0x150 */
351a517c69dSPatrick Mooney 	uint64_t cr0;			/* 0x158 */
352a517c69dSPatrick Mooney 	uint64_t dr7;			/* 0x160 */
353a517c69dSPatrick Mooney 	uint64_t dr6;			/* 0x168 */
354a517c69dSPatrick Mooney 	uint64_t rflags;		/* 0x170 */
355a517c69dSPatrick Mooney 	uint64_t rip;			/* 0x178 */
356a517c69dSPatrick Mooney 	uint64_t _pad4[11];		/* 0x180-0x1D7: Reserved */
357a517c69dSPatrick Mooney 	uint64_t rsp;			/* 0x1D8 */
358a517c69dSPatrick Mooney 	uint64_t _pad5[3];		/* 0x1E0-0x1F7: Reserved */
359a517c69dSPatrick Mooney 	uint64_t rax;			/* 0x1F8 */
360a517c69dSPatrick Mooney 	uint64_t star;			/* 0x200 */
361a517c69dSPatrick Mooney 	uint64_t lstar;			/* 0x208 */
362a517c69dSPatrick Mooney 	uint64_t cstar;			/* 0x210 */
363a517c69dSPatrick Mooney 	uint64_t sfmask;		/* 0x218 */
364a517c69dSPatrick Mooney 	uint64_t kernelgsbase;		/* 0x220 */
365a517c69dSPatrick Mooney 	uint64_t sysenter_cs;		/* 0x228 */
366a517c69dSPatrick Mooney 	uint64_t sysenter_esp;		/* 0x230 */
367a517c69dSPatrick Mooney 	uint64_t sysenter_eip;		/* 0x238 */
368a517c69dSPatrick Mooney 	uint64_t cr2;			/* 0x240 */
369a517c69dSPatrick Mooney 	uint64_t _pad6[4];		/* 0x248-0x267: Reserved */
370a517c69dSPatrick Mooney 	uint64_t g_pat;			/* 0x268 */
371a517c69dSPatrick Mooney 	uint64_t dbgctl;		/* 0x270 */
372a517c69dSPatrick Mooney 	uint64_t br_from;		/* 0x278 */
373a517c69dSPatrick Mooney 	uint64_t br_to;			/* 0x280 */
374a517c69dSPatrick Mooney 	uint64_t int_from;		/* 0x288 */
375a517c69dSPatrick Mooney 	uint64_t int_to;		/* 0x290 */
376a517c69dSPatrick Mooney 	uint64_t _pad7[301];		/* Reserved up to end of VMCB */
377a517c69dSPatrick Mooney };
3782699b94cSPatrick Mooney CTASSERT(sizeof (struct vmcb_state) == 0xC00);
379a517c69dSPatrick Mooney CTASSERT(offsetof(struct vmcb_state, int_to) == 0x290);
3804c87aefeSPatrick Mooney 
381096bb5cbSPatrick Mooney /*
382096bb5cbSPatrick Mooney  * The VMCB aka Virtual Machine Control Block is a 4KB aligned page
383096bb5cbSPatrick Mooney  * in memory that describes the virtual machine.
384096bb5cbSPatrick Mooney  *
385096bb5cbSPatrick Mooney  * The VMCB contains:
386096bb5cbSPatrick Mooney  * - instructions or events in the guest to intercept
387096bb5cbSPatrick Mooney  * - control bits that modify execution environment of the guest
388096bb5cbSPatrick Mooney  * - guest processor state (e.g. general purpose registers)
389096bb5cbSPatrick Mooney  */
3904c87aefeSPatrick Mooney struct vmcb {
3914c87aefeSPatrick Mooney 	struct vmcb_ctrl ctrl;
3924c87aefeSPatrick Mooney 	struct vmcb_state state;
393a517c69dSPatrick Mooney };
3942699b94cSPatrick Mooney CTASSERT(sizeof (struct vmcb) == PAGE_SIZE);
3954c87aefeSPatrick Mooney CTASSERT(offsetof(struct vmcb, state) == 0x400);
3964c87aefeSPatrick Mooney 
397096bb5cbSPatrick Mooney struct vmcb_segment *vmcb_segptr(struct vmcb *vmcb, int type);
398096bb5cbSPatrick Mooney uint64_t *vmcb_regptr(struct vmcb *vmcb, int ident, uint32_t *dirtyp);
39954cf5b63SPatrick Mooney uint64_t *vmcb_msr_ptr(struct vmcb *vmcb, uint32_t ident, uint32_t *dirtyp);
4004c87aefeSPatrick Mooney 
4014c87aefeSPatrick Mooney #endif /* _KERNEL */
4024c87aefeSPatrick Mooney #endif /* _VMCB_H_ */
403