summaryrefslogtreecommitdiff
path: root/usr/src/uts/i86pc/io/vmm/amd/vmcb.h
blob: 15b076b5bb5b81d9617bae26b4f12f63e3fb8fea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
/*-
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
 *
 * Copyright (c) 2013 Anish Gupta (akgupt3@gmail.com)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice unmodified, this list of conditions, and the following
 *    disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD$
 */

/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 *
 * Copyright 2021 Oxide Computer Company
 */

#ifndef _VMCB_H_
#define	_VMCB_H_

struct svm_softc;

#define	BIT(n)			(1ULL << n)

/*
 * Secure Virtual Machine: AMD64 Programmer's Manual Vol2, Chapter 15
 * Layout of VMCB: AMD64 Programmer's Manual Vol2, Appendix B
 */

/* vmcb_ctrl->intercept[] array indices */
#define	VMCB_CR_INTCPT		0
#define	VMCB_DR_INTCPT		1
#define	VMCB_EXC_INTCPT		2
#define	VMCB_CTRL1_INTCPT	3
#define	VMCB_CTRL2_INTCPT	4

/* intercept[VMCB_CTRL1_INTCPT] fields */
#define	VMCB_INTCPT_INTR		BIT(0)
#define	VMCB_INTCPT_NMI			BIT(1)
#define	VMCB_INTCPT_SMI			BIT(2)
#define	VMCB_INTCPT_INIT		BIT(3)
#define	VMCB_INTCPT_VINTR		BIT(4)
#define	VMCB_INTCPT_CR0_WRITE		BIT(5)
#define	VMCB_INTCPT_IDTR_READ		BIT(6)
#define	VMCB_INTCPT_GDTR_READ		BIT(7)
#define	VMCB_INTCPT_LDTR_READ		BIT(8)
#define	VMCB_INTCPT_TR_READ		BIT(9)
#define	VMCB_INTCPT_IDTR_WRITE		BIT(10)
#define	VMCB_INTCPT_GDTR_WRITE		BIT(11)
#define	VMCB_INTCPT_LDTR_WRITE		BIT(12)
#define	VMCB_INTCPT_TR_WRITE		BIT(13)
#define	VMCB_INTCPT_RDTSC		BIT(14)
#define	VMCB_INTCPT_RDPMC		BIT(15)
#define	VMCB_INTCPT_PUSHF		BIT(16)
#define	VMCB_INTCPT_POPF		BIT(17)
#define	VMCB_INTCPT_CPUID		BIT(18)
#define	VMCB_INTCPT_RSM			BIT(19)
#define	VMCB_INTCPT_IRET		BIT(20)
#define	VMCB_INTCPT_INTn		BIT(21)
#define	VMCB_INTCPT_INVD		BIT(22)
#define	VMCB_INTCPT_PAUSE		BIT(23)
#define	VMCB_INTCPT_HLT			BIT(24)
#define	VMCB_INTCPT_INVLPG		BIT(25)
#define	VMCB_INTCPT_INVLPGA		BIT(26)
#define	VMCB_INTCPT_IO			BIT(27)
#define	VMCB_INTCPT_MSR			BIT(28)
#define	VMCB_INTCPT_TASK_SWITCH		BIT(29)
#define	VMCB_INTCPT_FERR_FREEZE		BIT(30)
#define	VMCB_INTCPT_SHUTDOWN		BIT(31)

/* intercept[VMCB_CTRL2_INTCPT] fields */
#define	VMCB_INTCPT_VMRUN		BIT(0)
#define	VMCB_INTCPT_VMMCALL		BIT(1)
#define	VMCB_INTCPT_VMLOAD		BIT(2)
#define	VMCB_INTCPT_VMSAVE		BIT(3)
#define	VMCB_INTCPT_STGI		BIT(4)
#define	VMCB_INTCPT_CLGI		BIT(5)
#define	VMCB_INTCPT_SKINIT		BIT(6)
#define	VMCB_INTCPT_RDTSCP		BIT(7)
#define	VMCB_INTCPT_ICEBP		BIT(8)
#define	VMCB_INTCPT_WBINVD		BIT(9)
#define	VMCB_INTCPT_MONITOR		BIT(10)
#define	VMCB_INTCPT_MWAIT		BIT(11)
#define	VMCB_INTCPT_MWAIT_ARMED		BIT(12)
#define	VMCB_INTCPT_XSETBV		BIT(13)

/* VMCB TLB control */
#define	VMCB_TLB_FLUSH_NOTHING		0	/* Flush nothing */
#define	VMCB_TLB_FLUSH_ALL		1	/* Flush entire TLB */
#define	VMCB_TLB_FLUSH_GUEST		3	/* Flush all guest entries */
#define	VMCB_TLB_FLUSH_GUEST_NONGLOBAL	7	/* Flush guest non-PG entries */

/* VMCB state caching */
#define	VMCB_CACHE_NONE		0	/* No caching */
#define	VMCB_CACHE_I		BIT(0)	/* Intercept, TSC off, Pause filter */
#define	VMCB_CACHE_IOPM		BIT(1)	/* I/O and MSR permission */
#define	VMCB_CACHE_ASID		BIT(2)	/* ASID */
#define	VMCB_CACHE_TPR		BIT(3)	/* V_TPR to V_INTR_VECTOR */
#define	VMCB_CACHE_NP		BIT(4)	/* Nested Paging */
#define	VMCB_CACHE_CR		BIT(5)	/* CR0, CR3, CR4 & EFER */
#define	VMCB_CACHE_DR		BIT(6)	/* Debug registers */
#define	VMCB_CACHE_DT		BIT(7)	/* GDT/IDT */
#define	VMCB_CACHE_SEG		BIT(8)	/* User segments, CPL */
#define	VMCB_CACHE_CR2		BIT(9)	/* page fault address */
#define	VMCB_CACHE_LBR		BIT(10)	/* Last branch */

/* VMCB control event injection */
#define	VMCB_EVENTINJ_EC_VALID		BIT(11)	/* Error Code valid */
#define	VMCB_EVENTINJ_VALID		BIT(31)	/* Event valid */

/* Event types that can be injected */
#define	VMCB_EVENTINJ_TYPE_INTR		0
#define	VMCB_EVENTINJ_TYPE_NMI		(2 << 8)
#define	VMCB_EVENTINJ_TYPE_EXCEPTION	(3 << 8)
#define	VMCB_EVENTINJ_TYPE_INTn		(4 << 8)

/* VMCB exit code, APM vol2 Appendix C */
#define	VMCB_EXIT_CR0_READ		0x00
#define	VMCB_EXIT_CR15_READ		0x0f
#define	VMCB_EXIT_CR0_WRITE		0x10
#define	VMCB_EXIT_CR15_WRITE		0x1f
#define	VMCB_EXIT_MC			0x52
#define	VMCB_EXIT_INTR			0x60
#define	VMCB_EXIT_NMI			0x61
#define	VMCB_EXIT_SMI			0x62
#define	VMCB_EXIT_INIT			0x63
#define	VMCB_EXIT_VINTR			0x64
#define	VMCB_EXIT_CR0_SEL_WRITE		0x65
#define	VMCB_EXIT_PUSHF			0x70
#define	VMCB_EXIT_POPF			0x71
#define	VMCB_EXIT_CPUID			0x72
#define	VMCB_EXIT_IRET			0x74
#define	VMCB_EXIT_INVD			0x76
#define	VMCB_EXIT_PAUSE			0x77
#define	VMCB_EXIT_HLT			0x78
#define	VMCB_EXIT_INVLPG		0x79
#define	VMCB_EXIT_INVLPGA		0x7A
#define	VMCB_EXIT_IO			0x7B
#define	VMCB_EXIT_MSR			0x7C
#define	VMCB_EXIT_SHUTDOWN		0x7F
#define	VMCB_EXIT_VMRUN			0x80
#define	VMCB_EXIT_VMMCALL		0x81
#define	VMCB_EXIT_VMLOAD		0x82
#define	VMCB_EXIT_VMSAVE		0x83
#define	VMCB_EXIT_STGI			0x84
#define	VMCB_EXIT_CLGI			0x85
#define	VMCB_EXIT_SKINIT		0x86
#define	VMCB_EXIT_MONITOR		0x8A
#define	VMCB_EXIT_MWAIT			0x8B
#define	VMCB_EXIT_NPF			0x400
#define	VMCB_EXIT_INVALID		-1

/*
 * Move to/from CRx
 * Bit definitions to decode EXITINFO1
 */
#define	VMCB_CRx_INFO1_GPR(x)		((x) & 0xf)
#define	VMCB_CRx_INFO1_VALID(x)		((x) & (1UL << 63))

/*
 * Nested page fault.
 * Bit definitions to decode EXITINFO1.
 */
#define	VMCB_NPF_INFO1_P		BIT(0) /* Nested page present. */
#define	VMCB_NPF_INFO1_W		BIT(1) /* Access was write. */
#define	VMCB_NPF_INFO1_U		BIT(2) /* Access was user access. */
#define	VMCB_NPF_INFO1_RSV		BIT(3) /* Reserved bits present. */
#define	VMCB_NPF_INFO1_ID		BIT(4) /* Code read. */

#define	VMCB_NPF_INFO1_GPA		BIT(32) /* Guest physical address. */
#define	VMCB_NPF_INFO1_GPT		BIT(33) /* Guest page table. */

/*
 * EXITINTINFO, Interrupt exit info for all intrecepts.
 * Section 15.7.2, Intercepts during IDT Interrupt Delivery.
 */
#define	VMCB_EXITINTINFO_VECTOR(x)	((x) & 0xFF)
#define	VMCB_EXITINTINFO_TYPE(x)	((x) & (0x7 << 8))
#define	VMCB_EXITINTINFO_EC_VALID(x)	(((x) & BIT(11)) != 0)
#define	VMCB_EXITINTINFO_VALID(x)	(((x) & BIT(31)) != 0)
#define	VMCB_EXITINTINFO_EC(x)		(((x) >> 32) & 0xFFFFFFFF)

/* Offset of various VMCB fields. */
#define	VMCB_OFF_CTRL(x)		(x)
#define	VMCB_OFF_STATE(x)		((x) + 0x400)

#define	VMCB_OFF_CR_INTERCEPT		VMCB_OFF_CTRL(0x0)
#define	VMCB_OFF_DR_INTERCEPT		VMCB_OFF_CTRL(0x4)
#define	VMCB_OFF_EXC_INTERCEPT		VMCB_OFF_CTRL(0x8)
#define	VMCB_OFF_INST1_INTERCEPT	VMCB_OFF_CTRL(0xC)
#define	VMCB_OFF_INST2_INTERCEPT	VMCB_OFF_CTRL(0x10)
#define	VMCB_OFF_IO_PERM		VMCB_OFF_CTRL(0x40)
#define	VMCB_OFF_MSR_PERM		VMCB_OFF_CTRL(0x48)
#define	VMCB_OFF_TSC_OFFSET		VMCB_OFF_CTRL(0x50)
#define	VMCB_OFF_ASID			VMCB_OFF_CTRL(0x58)
#define	VMCB_OFF_TLB_CTRL		VMCB_OFF_CTRL(0x5C)
#define	VMCB_OFF_VIRQ			VMCB_OFF_CTRL(0x60)
#define	VMCB_OFF_EXIT_REASON		VMCB_OFF_CTRL(0x70)
#define	VMCB_OFF_EXITINFO1		VMCB_OFF_CTRL(0x78)
#define	VMCB_OFF_EXITINFO2		VMCB_OFF_CTRL(0x80)
#define	VMCB_OFF_EXITINTINFO		VMCB_OFF_CTRL(0x88)
#define	VMCB_OFF_AVIC_BAR		VMCB_OFF_CTRL(0x98)
#define	VMCB_OFF_NPT_BASE		VMCB_OFF_CTRL(0xB0)
#define	VMCB_OFF_AVIC_PAGE		VMCB_OFF_CTRL(0xE0)
#define	VMCB_OFF_AVIC_LT		VMCB_OFF_CTRL(0xF0)
#define	VMCB_OFF_AVIC_PT		VMCB_OFF_CTRL(0xF8)
#define	VMCB_OFF_SYSENTER_CS		VMCB_OFF_STATE(0x228)
#define	VMCB_OFF_SYSENTER_ESP		VMCB_OFF_STATE(0x230)
#define	VMCB_OFF_SYSENTER_EIP		VMCB_OFF_STATE(0x238)
#define	VMCB_OFF_GUEST_PAT		VMCB_OFF_STATE(0x268)

#ifdef _KERNEL
/* VMCB save state area segment format */
struct vmcb_segment {
	uint16_t	selector;
	uint16_t	attrib;
	uint32_t	limit;
	uint64_t	base;
};
CTASSERT(sizeof (struct vmcb_segment) == 16);

/* Convert to/from vmcb segment access to generic (VMX) access */
#define	VMCB_ATTR2ACCESS(attr)	((((attr) & 0xf00) << 4) | ((attr) & 0xff))
#define	VMCB_ACCESS2ATTR(acc)	((((acc) & 0xf000) >> 4) | ((acc) & 0xff))

/* Code segment descriptor attribute in 12 bit format as saved by VMCB. */
#define	VMCB_CS_ATTRIB_L		BIT(9)	/* Long mode. */
#define	VMCB_CS_ATTRIB_D		BIT(10)	/* OPerand size bit. */

/* Fields for Virtual Interrupt Control (v_irq) */
#define	V_IRQ		BIT(0)	/* Offset 0x60 bit 8 (0x61 bit 0) */
#define	V_VGIF_VALUE	BIT(1)	/* Offset 0x60 bit 9 (0x61 bit 1) */

/* Fields for Virtual Interrupt Control (v_intr_prio) */
#define	V_INTR_PRIO	0xf	/* Offset 0x60 bits 16-19 (0x62 bits 0-3) */
#define	V_IGN_TPR	BIT(4)	/* Offset 0x60 bit 20 (0x62 bit 4) */

/* Fields for Virtual Interrupt Control (v_intr_ctrl) */
#define	V_INTR_MASKING	BIT(0)	/* Offset 0x60 bit 24 (0x63 bit 0) */
#define	V_VGIF_ENABLE	BIT(1)	/* Offset 0x60 bit 25 (0x63 bit 1) */
#define	V_AVIC_ENABLE	BIT(7)	/* Offset 0x60 bit 31 (0x63 bit 7) */

/* Fields in Interrupt Shadow, offset 0x68 */
#define	VIRTUAL_INTR_SHADOW	BIT(0)
#define	GUEST_INTERRUPT_MASK	BIT(1)

/* Fields in Nested Paging, offset 0x90 */
#define	NP_ENABLE		BIT(0)	/* Enable nested paging */
#define	SEV_ENABLE		BIT(1)	/* Enable SEV */
#define	SEV_ES_ENABLE		BIT(2)	/* Enable SEV-ES */
#define	GUEST_MODE_EXEC_TRAP	BIT(3)	/* Guest mode execute trap */
#define	VIRT_TRANSPAR_ENCRYPT	BIT(5)	/* Virtual transparent encryption */

/* Fields in Misc virt controls, offset 0xB8 */
#define	LBR_VIRT_ENABLE		BIT(0)	/* Enable LBR virtualization accel */
#define	VIRT_VMSAVE_VMLOAD	BIT(1)	/* Virtualized VMSAVE/VMLOAD */

/*
 * The VMCB is divided into two areas - the first one contains various
 * control bits including the intercept vector and the second one contains
 * the guest state.
 */

/* VMCB control area - padded up to 1024 bytes */
struct vmcb_ctrl {
	uint32_t intercept[5];	/* 0x00-0x13: all intercepts */
	uint32_t _pad1[10];	/* 0x14-0x3B: Reserved. */
	uint32_t pause_ctrl;	/* 0x3C, PAUSE filter thresh/count */
	uint64_t iopm_base_pa;	/* 0x40: IOPM_BASE_PA */
	uint64_t msrpm_base_pa; /* 0x48: MSRPM_BASE_PA */
	uint64_t tsc_offset;	/* 0x50: TSC_OFFSET */
	uint32_t asid;		/* 0x58: Guest ASID */
	uint8_t tlb_ctrl;	/* 0x5C: TLB_CONTROL */
	uint8_t _pad2[3];	/* 0x5D-0x5F: Reserved. */
	uint8_t v_tpr;		/* 0x60: Virtual TPR */
	uint8_t v_irq;		/* 0x61: V_IRQ, V_GIF_VALUE + Reserved */
	uint8_t v_intr_prio;	/* 0x62: V_INTR_PRIO, V_IGN_TPR */
	uint8_t v_intr_ctrl;	/* 0x63: V_INTR_MASKING, vGIF and AVIC enable */
	uint8_t v_intr_vector;	/* 0x64: Virtual interrupt vector */
	uint8_t _pad3[3];	/* 0x65-0x67: Reserved */
	uint64_t intr_shadow;	/* 0x68: Interrupt shadow (and more) */
	uint64_t exitcode;	/* 0x70, Exitcode */
	uint64_t exitinfo1;	/* 0x78, EXITINFO1 */
	uint64_t exitinfo2;	/* 0x80, EXITINFO2 */
	uint64_t exitintinfo;	/* 0x88, Interrupt exit value. */
	uint64_t np_ctrl;	/* 0x90, Nested paging control. */
	uint64_t _pad4[2];	/* 0x98-0xA7 reserved. */
	uint64_t eventinj;	/* 0xA8, Event injection. */
	uint64_t n_cr3;		/* 0xB0, Nested page table. */
	uint64_t misc_ctrl;	/* 0xB8, Misc virt controls */
	uint32_t vmcb_clean;	/* 0xC0: VMCB clean bits for caching */
	uint32_t _pad5;		/* 0xC4: Reserved */
	uint64_t nrip;		/* 0xC8: Guest next nRIP. */
	uint8_t inst_len;	/* 0xD0: #NPF decode assist */
	uint8_t inst_bytes[15]; /* 0xD1-0xDF: guest instr bytes */
	uint64_t avic_page_pa;	/* 0xEO: AVIC backing page */
	uint64_t _pad6;		/* 0xE8-0xEF: Reserved */
	uint64_t avic_log_tbl;	/* 0xFO: AVIC logical table */
	uint64_t avic_phys_tbl;	/* 0xF8: AVIC physical page */
	uint64_t _pad7;		/* 0x100-0x107: Reserved */
	uint64_t vmsa_pa;	/* 0x108: VMSA pointer */
	uint64_t _pad8[94];	/* 0x110-0x3FF: Reserved */
};
CTASSERT(sizeof (struct vmcb_ctrl) == 1024);
CTASSERT(offsetof(struct vmcb_ctrl, vmsa_pa) == 0x108);

struct vmcb_state {
	struct vmcb_segment es;		/* 0x00: 32bit base */
	struct vmcb_segment cs;		/* 0x10: 32bit base */
	struct vmcb_segment ss;		/* 0x20: 32bit base */
	struct vmcb_segment ds;		/* 0x30: 32bit base */
	struct vmcb_segment fs;		/* 0x40 */
	struct vmcb_segment gs;		/* 0x50 */
	struct vmcb_segment gdt;	/* 0x60: base + 16bit limit */
	struct vmcb_segment ldt;	/* 0x70 */
	struct vmcb_segment idt;	/* 0x80: base + 16bit limit */
	struct vmcb_segment tr;		/* 0x90 */
	uint8_t _pad1[43];		/* 0xA0-0xCA: Reserved */
	uint8_t cpl;			/* 0xCB: CPL (real mode: 0, virt: 3) */
	uint32_t _pad2;			/* 0xCC-0xCF: Reserved */
	uint64_t efer;			/* 0xD0 */
	uint64_t _pad3[14];		/* 0xD8-0x147: Reserved */
	uint64_t cr4;			/* 0x148 */
	uint64_t cr3;			/* 0x150 */
	uint64_t cr0;			/* 0x158 */
	uint64_t dr7;			/* 0x160 */
	uint64_t dr6;			/* 0x168 */
	uint64_t rflags;		/* 0x170 */
	uint64_t rip;			/* 0x178 */
	uint64_t _pad4[11];		/* 0x180-0x1D7: Reserved */
	uint64_t rsp;			/* 0x1D8 */
	uint64_t _pad5[3];		/* 0x1E0-0x1F7: Reserved */
	uint64_t rax;			/* 0x1F8 */
	uint64_t star;			/* 0x200 */
	uint64_t lstar;			/* 0x208 */
	uint64_t cstar;			/* 0x210 */
	uint64_t sfmask;		/* 0x218 */
	uint64_t kernelgsbase;		/* 0x220 */
	uint64_t sysenter_cs;		/* 0x228 */
	uint64_t sysenter_esp;		/* 0x230 */
	uint64_t sysenter_eip;		/* 0x238 */
	uint64_t cr2;			/* 0x240 */
	uint64_t _pad6[4];		/* 0x248-0x267: Reserved */
	uint64_t g_pat;			/* 0x268 */
	uint64_t dbgctl;		/* 0x270 */
	uint64_t br_from;		/* 0x278 */
	uint64_t br_to;			/* 0x280 */
	uint64_t int_from;		/* 0x288 */
	uint64_t int_to;		/* 0x290 */
	uint64_t _pad7[301];		/* Reserved up to end of VMCB */
};
CTASSERT(sizeof (struct vmcb_state) == 0xC00);
CTASSERT(offsetof(struct vmcb_state, int_to) == 0x290);

/*
 * The VMCB aka Virtual Machine Control Block is a 4KB aligned page
 * in memory that describes the virtual machine.
 *
 * The VMCB contains:
 * - instructions or events in the guest to intercept
 * - control bits that modify execution environment of the guest
 * - guest processor state (e.g. general purpose registers)
 */
struct vmcb {
	struct vmcb_ctrl ctrl;
	struct vmcb_state state;
};
CTASSERT(sizeof (struct vmcb) == PAGE_SIZE);
CTASSERT(offsetof(struct vmcb, state) == 0x400);

struct vmcb_segment *vmcb_segptr(struct vmcb *vmcb, int type);
uint64_t *vmcb_regptr(struct vmcb *vmcb, int ident, uint32_t *dirtyp);

#endif /* _KERNEL */
#endif /* _VMCB_H_ */