xref: /freebsd/lib/libvmmapi/amd64/vmmapi_machdep.c (revision 7f00e46b85e8c60259ad0bdd53593ea246f3e549)
1967264cfSMark Johnston /*-
2967264cfSMark Johnston  * SPDX-License-Identifier: BSD-2-Clause
3967264cfSMark Johnston  *
4967264cfSMark Johnston  * Copyright (c) 2011 NetApp, Inc.
5967264cfSMark Johnston  * All rights reserved.
6967264cfSMark Johnston  *
7967264cfSMark Johnston  * Redistribution and use in source and binary forms, with or without
8967264cfSMark Johnston  * modification, are permitted provided that the following conditions
9967264cfSMark Johnston  * are met:
10967264cfSMark Johnston  * 1. Redistributions of source code must retain the above copyright
11967264cfSMark Johnston  *    notice, this list of conditions and the following disclaimer.
12967264cfSMark Johnston  * 2. Redistributions in binary form must reproduce the above copyright
13967264cfSMark Johnston  *    notice, this list of conditions and the following disclaimer in the
14967264cfSMark Johnston  *    documentation and/or other materials provided with the distribution.
15967264cfSMark Johnston  *
16967264cfSMark Johnston  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17967264cfSMark Johnston  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18967264cfSMark Johnston  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19967264cfSMark Johnston  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20967264cfSMark Johnston  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21967264cfSMark Johnston  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22967264cfSMark Johnston  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23967264cfSMark Johnston  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24967264cfSMark Johnston  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25967264cfSMark Johnston  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26967264cfSMark Johnston  * SUCH DAMAGE.
27967264cfSMark Johnston  */
28967264cfSMark Johnston 
29e4656e10SMark Johnston #include <sys/types.h>
30e4656e10SMark Johnston #include <sys/ioctl.h>
31e4656e10SMark Johnston 
32967264cfSMark Johnston #include <machine/specialreg.h>
33e4656e10SMark Johnston #include <machine/vmm.h>
34*7f00e46bSMark Johnston #include <machine/vmm_dev.h>
35*7f00e46bSMark Johnston #include <machine/vmm_snapshot.h>
36e4656e10SMark Johnston 
37e4656e10SMark Johnston #include <string.h>
38967264cfSMark Johnston 
39967264cfSMark Johnston #include "vmmapi.h"
40967264cfSMark Johnston #include "internal.h"
41967264cfSMark Johnston 
4285efb31dSMark Johnston const char *vm_capstrmap[] = {
4385efb31dSMark Johnston 	[VM_CAP_HALT_EXIT]  = "hlt_exit",
4485efb31dSMark Johnston 	[VM_CAP_MTRAP_EXIT] = "mtrap_exit",
4585efb31dSMark Johnston 	[VM_CAP_PAUSE_EXIT] = "pause_exit",
4685efb31dSMark Johnston 	[VM_CAP_UNRESTRICTED_GUEST] = "unrestricted_guest",
4785efb31dSMark Johnston 	[VM_CAP_ENABLE_INVPCID] = "enable_invpcid",
4885efb31dSMark Johnston 	[VM_CAP_BPT_EXIT] = "bpt_exit",
4985efb31dSMark Johnston 	[VM_CAP_RDPID] = "rdpid",
5085efb31dSMark Johnston 	[VM_CAP_RDTSCP] = "rdtscp",
5185efb31dSMark Johnston 	[VM_CAP_IPI_EXIT] = "ipi_exit",
5285efb31dSMark Johnston 	[VM_CAP_MASK_HWINTR] = "mask_hwintr",
5385efb31dSMark Johnston 	[VM_CAP_RFLAGS_TF] = "rflags_tf",
5485efb31dSMark Johnston 	[VM_CAP_MAX] = NULL,
5585efb31dSMark Johnston };
5685efb31dSMark Johnston 
57*7f00e46bSMark Johnston #define	VM_MD_IOCTLS			\
58*7f00e46bSMark Johnston 	VM_SET_SEGMENT_DESCRIPTOR,	\
59*7f00e46bSMark Johnston 	VM_GET_SEGMENT_DESCRIPTOR,	\
60*7f00e46bSMark Johnston 	VM_SET_KERNEMU_DEV,		\
61*7f00e46bSMark Johnston 	VM_GET_KERNEMU_DEV,		\
62*7f00e46bSMark Johnston 	VM_LAPIC_IRQ,			\
63*7f00e46bSMark Johnston 	VM_LAPIC_LOCAL_IRQ,		\
64*7f00e46bSMark Johnston 	VM_LAPIC_MSI,			\
65*7f00e46bSMark Johnston 	VM_IOAPIC_ASSERT_IRQ,		\
66*7f00e46bSMark Johnston 	VM_IOAPIC_DEASSERT_IRQ,		\
67*7f00e46bSMark Johnston 	VM_IOAPIC_PULSE_IRQ,		\
68*7f00e46bSMark Johnston 	VM_IOAPIC_PINCOUNT,		\
69*7f00e46bSMark Johnston 	VM_ISA_ASSERT_IRQ,		\
70*7f00e46bSMark Johnston 	VM_ISA_DEASSERT_IRQ,		\
71*7f00e46bSMark Johnston 	VM_ISA_PULSE_IRQ,		\
72*7f00e46bSMark Johnston 	VM_ISA_SET_IRQ_TRIGGER,		\
73*7f00e46bSMark Johnston 	VM_INJECT_NMI,			\
74*7f00e46bSMark Johnston 	VM_SET_X2APIC_STATE,		\
75*7f00e46bSMark Johnston 	VM_GET_X2APIC_STATE,		\
76*7f00e46bSMark Johnston 	VM_GET_HPET_CAPABILITIES,	\
77*7f00e46bSMark Johnston 	VM_RTC_WRITE,			\
78*7f00e46bSMark Johnston 	VM_RTC_READ,			\
79*7f00e46bSMark Johnston 	VM_RTC_SETTIME,			\
80*7f00e46bSMark Johnston 	VM_RTC_GETTIME
81*7f00e46bSMark Johnston 
82*7f00e46bSMark Johnston const cap_ioctl_t vm_ioctl_cmds[] = {
83*7f00e46bSMark Johnston 	VM_COMMON_IOCTLS,
84*7f00e46bSMark Johnston 	VM_PPT_IOCTLS,
85*7f00e46bSMark Johnston 	VM_MD_IOCTLS,
86*7f00e46bSMark Johnston };
87*7f00e46bSMark Johnston size_t vm_ioctl_ncmds = nitems(vm_ioctl_cmds);
88*7f00e46bSMark Johnston 
89e4656e10SMark Johnston int
90e4656e10SMark Johnston vm_set_desc(struct vcpu *vcpu, int reg,
91e4656e10SMark Johnston 	    uint64_t base, uint32_t limit, uint32_t access)
92e4656e10SMark Johnston {
93e4656e10SMark Johnston 	int error;
94e4656e10SMark Johnston 	struct vm_seg_desc vmsegdesc;
95e4656e10SMark Johnston 
96e4656e10SMark Johnston 	bzero(&vmsegdesc, sizeof(vmsegdesc));
97e4656e10SMark Johnston 	vmsegdesc.regnum = reg;
98e4656e10SMark Johnston 	vmsegdesc.desc.base = base;
99e4656e10SMark Johnston 	vmsegdesc.desc.limit = limit;
100e4656e10SMark Johnston 	vmsegdesc.desc.access = access;
101e4656e10SMark Johnston 
102e4656e10SMark Johnston 	error = vcpu_ioctl(vcpu, VM_SET_SEGMENT_DESCRIPTOR, &vmsegdesc);
103e4656e10SMark Johnston 	return (error);
104e4656e10SMark Johnston }
105e4656e10SMark Johnston 
106e4656e10SMark Johnston int
107e4656e10SMark Johnston vm_get_desc(struct vcpu *vcpu, int reg, uint64_t *base, uint32_t *limit,
108e4656e10SMark Johnston     uint32_t *access)
109e4656e10SMark Johnston {
110e4656e10SMark Johnston 	int error;
111e4656e10SMark Johnston 	struct vm_seg_desc vmsegdesc;
112e4656e10SMark Johnston 
113e4656e10SMark Johnston 	bzero(&vmsegdesc, sizeof(vmsegdesc));
114e4656e10SMark Johnston 	vmsegdesc.regnum = reg;
115e4656e10SMark Johnston 
116e4656e10SMark Johnston 	error = vcpu_ioctl(vcpu, VM_GET_SEGMENT_DESCRIPTOR, &vmsegdesc);
117e4656e10SMark Johnston 	if (error == 0) {
118e4656e10SMark Johnston 		*base = vmsegdesc.desc.base;
119e4656e10SMark Johnston 		*limit = vmsegdesc.desc.limit;
120e4656e10SMark Johnston 		*access = vmsegdesc.desc.access;
121e4656e10SMark Johnston 	}
122e4656e10SMark Johnston 	return (error);
123e4656e10SMark Johnston }
124e4656e10SMark Johnston 
125e4656e10SMark Johnston int
126e4656e10SMark Johnston vm_get_seg_desc(struct vcpu *vcpu, int reg, struct seg_desc *seg_desc)
127e4656e10SMark Johnston {
128e4656e10SMark Johnston 	int error;
129e4656e10SMark Johnston 
130e4656e10SMark Johnston 	error = vm_get_desc(vcpu, reg, &seg_desc->base, &seg_desc->limit,
131e4656e10SMark Johnston 	    &seg_desc->access);
132e4656e10SMark Johnston 	return (error);
133e4656e10SMark Johnston }
134e4656e10SMark Johnston 
135e4656e10SMark Johnston int
136e4656e10SMark Johnston vm_lapic_irq(struct vcpu *vcpu, int vector)
137e4656e10SMark Johnston {
138e4656e10SMark Johnston 	struct vm_lapic_irq vmirq;
139e4656e10SMark Johnston 
140e4656e10SMark Johnston 	bzero(&vmirq, sizeof(vmirq));
141e4656e10SMark Johnston 	vmirq.vector = vector;
142e4656e10SMark Johnston 
143e4656e10SMark Johnston 	return (vcpu_ioctl(vcpu, VM_LAPIC_IRQ, &vmirq));
144e4656e10SMark Johnston }
145e4656e10SMark Johnston 
146e4656e10SMark Johnston int
147e4656e10SMark Johnston vm_lapic_local_irq(struct vcpu *vcpu, int vector)
148e4656e10SMark Johnston {
149e4656e10SMark Johnston 	struct vm_lapic_irq vmirq;
150e4656e10SMark Johnston 
151e4656e10SMark Johnston 	bzero(&vmirq, sizeof(vmirq));
152e4656e10SMark Johnston 	vmirq.vector = vector;
153e4656e10SMark Johnston 
154e4656e10SMark Johnston 	return (vcpu_ioctl(vcpu, VM_LAPIC_LOCAL_IRQ, &vmirq));
155e4656e10SMark Johnston }
156e4656e10SMark Johnston 
157e4656e10SMark Johnston int
158e4656e10SMark Johnston vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg)
159e4656e10SMark Johnston {
160e4656e10SMark Johnston 	struct vm_lapic_msi vmmsi;
161e4656e10SMark Johnston 
162e4656e10SMark Johnston 	bzero(&vmmsi, sizeof(vmmsi));
163e4656e10SMark Johnston 	vmmsi.addr = addr;
164e4656e10SMark Johnston 	vmmsi.msg = msg;
165e4656e10SMark Johnston 
166e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_LAPIC_MSI, &vmmsi));
167e4656e10SMark Johnston }
168e4656e10SMark Johnston 
169e4656e10SMark Johnston int
170e4656e10SMark Johnston vm_apicid2vcpu(struct vmctx *ctx __unused, int apicid)
171e4656e10SMark Johnston {
172e4656e10SMark Johnston 	/*
173e4656e10SMark Johnston 	 * The apic id associated with the 'vcpu' has the same numerical value
174e4656e10SMark Johnston 	 * as the 'vcpu' itself.
175e4656e10SMark Johnston 	 */
176e4656e10SMark Johnston 	return (apicid);
177e4656e10SMark Johnston }
178e4656e10SMark Johnston 
179e4656e10SMark Johnston int
180e4656e10SMark Johnston vm_ioapic_assert_irq(struct vmctx *ctx, int irq)
181e4656e10SMark Johnston {
182e4656e10SMark Johnston 	struct vm_ioapic_irq ioapic_irq;
183e4656e10SMark Johnston 
184e4656e10SMark Johnston 	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
185e4656e10SMark Johnston 	ioapic_irq.irq = irq;
186e4656e10SMark Johnston 
187e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_IOAPIC_ASSERT_IRQ, &ioapic_irq));
188e4656e10SMark Johnston }
189e4656e10SMark Johnston 
190e4656e10SMark Johnston int
191e4656e10SMark Johnston vm_ioapic_deassert_irq(struct vmctx *ctx, int irq)
192e4656e10SMark Johnston {
193e4656e10SMark Johnston 	struct vm_ioapic_irq ioapic_irq;
194e4656e10SMark Johnston 
195e4656e10SMark Johnston 	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
196e4656e10SMark Johnston 	ioapic_irq.irq = irq;
197e4656e10SMark Johnston 
198e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_IOAPIC_DEASSERT_IRQ, &ioapic_irq));
199e4656e10SMark Johnston }
200e4656e10SMark Johnston 
201e4656e10SMark Johnston int
202e4656e10SMark Johnston vm_ioapic_pulse_irq(struct vmctx *ctx, int irq)
203e4656e10SMark Johnston {
204e4656e10SMark Johnston 	struct vm_ioapic_irq ioapic_irq;
205e4656e10SMark Johnston 
206e4656e10SMark Johnston 	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
207e4656e10SMark Johnston 	ioapic_irq.irq = irq;
208e4656e10SMark Johnston 
209e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_IOAPIC_PULSE_IRQ, &ioapic_irq));
210e4656e10SMark Johnston }
211e4656e10SMark Johnston 
212e4656e10SMark Johnston int
213e4656e10SMark Johnston vm_ioapic_pincount(struct vmctx *ctx, int *pincount)
214e4656e10SMark Johnston {
215e4656e10SMark Johnston 
216e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_IOAPIC_PINCOUNT, pincount));
217e4656e10SMark Johnston }
218e4656e10SMark Johnston 
219e4656e10SMark Johnston int
220e4656e10SMark Johnston vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq)
221e4656e10SMark Johnston {
222e4656e10SMark Johnston 	struct vm_isa_irq isa_irq;
223e4656e10SMark Johnston 
224e4656e10SMark Johnston 	bzero(&isa_irq, sizeof(struct vm_isa_irq));
225e4656e10SMark Johnston 	isa_irq.atpic_irq = atpic_irq;
226e4656e10SMark Johnston 	isa_irq.ioapic_irq = ioapic_irq;
227e4656e10SMark Johnston 
228e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_ISA_ASSERT_IRQ, &isa_irq));
229e4656e10SMark Johnston }
230e4656e10SMark Johnston 
231e4656e10SMark Johnston int
232e4656e10SMark Johnston vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq)
233e4656e10SMark Johnston {
234e4656e10SMark Johnston 	struct vm_isa_irq isa_irq;
235e4656e10SMark Johnston 
236e4656e10SMark Johnston 	bzero(&isa_irq, sizeof(struct vm_isa_irq));
237e4656e10SMark Johnston 	isa_irq.atpic_irq = atpic_irq;
238e4656e10SMark Johnston 	isa_irq.ioapic_irq = ioapic_irq;
239e4656e10SMark Johnston 
240e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_ISA_DEASSERT_IRQ, &isa_irq));
241e4656e10SMark Johnston }
242e4656e10SMark Johnston 
243e4656e10SMark Johnston int
244e4656e10SMark Johnston vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq)
245e4656e10SMark Johnston {
246e4656e10SMark Johnston 	struct vm_isa_irq isa_irq;
247e4656e10SMark Johnston 
248e4656e10SMark Johnston 	bzero(&isa_irq, sizeof(struct vm_isa_irq));
249e4656e10SMark Johnston 	isa_irq.atpic_irq = atpic_irq;
250e4656e10SMark Johnston 	isa_irq.ioapic_irq = ioapic_irq;
251e4656e10SMark Johnston 
252e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_ISA_PULSE_IRQ, &isa_irq));
253e4656e10SMark Johnston }
254e4656e10SMark Johnston 
255e4656e10SMark Johnston int
256e4656e10SMark Johnston vm_isa_set_irq_trigger(struct vmctx *ctx, int atpic_irq,
257e4656e10SMark Johnston     enum vm_intr_trigger trigger)
258e4656e10SMark Johnston {
259e4656e10SMark Johnston 	struct vm_isa_irq_trigger isa_irq_trigger;
260e4656e10SMark Johnston 
261e4656e10SMark Johnston 	bzero(&isa_irq_trigger, sizeof(struct vm_isa_irq_trigger));
262e4656e10SMark Johnston 	isa_irq_trigger.atpic_irq = atpic_irq;
263e4656e10SMark Johnston 	isa_irq_trigger.trigger = trigger;
264e4656e10SMark Johnston 
265e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_ISA_SET_IRQ_TRIGGER, &isa_irq_trigger));
266e4656e10SMark Johnston }
267e4656e10SMark Johnston 
268e4656e10SMark Johnston int
269e4656e10SMark Johnston vm_inject_nmi(struct vcpu *vcpu)
270e4656e10SMark Johnston {
271e4656e10SMark Johnston 	struct vm_nmi vmnmi;
272e4656e10SMark Johnston 
273e4656e10SMark Johnston 	bzero(&vmnmi, sizeof(vmnmi));
274e4656e10SMark Johnston 
275e4656e10SMark Johnston 	return (vcpu_ioctl(vcpu, VM_INJECT_NMI, &vmnmi));
276e4656e10SMark Johnston }
277e4656e10SMark Johnston 
278967264cfSMark Johnston /*
279967264cfSMark Johnston  * From Intel Vol 3a:
280967264cfSMark Johnston  * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT
281967264cfSMark Johnston  */
282967264cfSMark Johnston int
283967264cfSMark Johnston vcpu_reset(struct vcpu *vcpu)
284967264cfSMark Johnston {
285967264cfSMark Johnston 	int error;
286967264cfSMark Johnston 	uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx;
287967264cfSMark Johnston 	uint32_t desc_access, desc_limit;
288967264cfSMark Johnston 	uint16_t sel;
289967264cfSMark Johnston 
290967264cfSMark Johnston 	zero = 0;
291967264cfSMark Johnston 
292967264cfSMark Johnston 	rflags = 0x2;
293967264cfSMark Johnston 	error = vm_set_register(vcpu, VM_REG_GUEST_RFLAGS, rflags);
294967264cfSMark Johnston 	if (error)
295967264cfSMark Johnston 		goto done;
296967264cfSMark Johnston 
297967264cfSMark Johnston 	rip = 0xfff0;
298967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RIP, rip)) != 0)
299967264cfSMark Johnston 		goto done;
300967264cfSMark Johnston 
301967264cfSMark Johnston 	/*
302967264cfSMark Johnston 	 * According to Intels Software Developer Manual CR0 should be
303967264cfSMark Johnston 	 * initialized with CR0_ET | CR0_NW | CR0_CD but that crashes some
304967264cfSMark Johnston 	 * guests like Windows.
305967264cfSMark Johnston 	 */
306967264cfSMark Johnston 	cr0 = CR0_NE;
307967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR0, cr0)) != 0)
308967264cfSMark Johnston 		goto done;
309967264cfSMark Johnston 
310967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR2, zero)) != 0)
311967264cfSMark Johnston 		goto done;
312967264cfSMark Johnston 
313967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR3, zero)) != 0)
314967264cfSMark Johnston 		goto done;
315967264cfSMark Johnston 
316967264cfSMark Johnston 	cr4 = 0;
317967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR4, cr4)) != 0)
318967264cfSMark Johnston 		goto done;
319967264cfSMark Johnston 
320967264cfSMark Johnston 	/*
321967264cfSMark Johnston 	 * CS: present, r/w, accessed, 16-bit, byte granularity, usable
322967264cfSMark Johnston 	 */
323967264cfSMark Johnston 	desc_base = 0xffff0000;
324967264cfSMark Johnston 	desc_limit = 0xffff;
325967264cfSMark Johnston 	desc_access = 0x0093;
326967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_CS,
327967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
328967264cfSMark Johnston 	if (error)
329967264cfSMark Johnston 		goto done;
330967264cfSMark Johnston 
331967264cfSMark Johnston 	sel = 0xf000;
332967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CS, sel)) != 0)
333967264cfSMark Johnston 		goto done;
334967264cfSMark Johnston 
335967264cfSMark Johnston 	/*
336967264cfSMark Johnston 	 * SS,DS,ES,FS,GS: present, r/w, accessed, 16-bit, byte granularity
337967264cfSMark Johnston 	 */
338967264cfSMark Johnston 	desc_base = 0;
339967264cfSMark Johnston 	desc_limit = 0xffff;
340967264cfSMark Johnston 	desc_access = 0x0093;
341967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_SS,
342967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
343967264cfSMark Johnston 	if (error)
344967264cfSMark Johnston 		goto done;
345967264cfSMark Johnston 
346967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_DS,
347967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
348967264cfSMark Johnston 	if (error)
349967264cfSMark Johnston 		goto done;
350967264cfSMark Johnston 
351967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_ES,
352967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
353967264cfSMark Johnston 	if (error)
354967264cfSMark Johnston 		goto done;
355967264cfSMark Johnston 
356967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_FS,
357967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
358967264cfSMark Johnston 	if (error)
359967264cfSMark Johnston 		goto done;
360967264cfSMark Johnston 
361967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_GS,
362967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
363967264cfSMark Johnston 	if (error)
364967264cfSMark Johnston 		goto done;
365967264cfSMark Johnston 
366967264cfSMark Johnston 	sel = 0;
367967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_SS, sel)) != 0)
368967264cfSMark Johnston 		goto done;
369967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_DS, sel)) != 0)
370967264cfSMark Johnston 		goto done;
371967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_ES, sel)) != 0)
372967264cfSMark Johnston 		goto done;
373967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_FS, sel)) != 0)
374967264cfSMark Johnston 		goto done;
375967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_GS, sel)) != 0)
376967264cfSMark Johnston 		goto done;
377967264cfSMark Johnston 
378967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_EFER, zero)) != 0)
379967264cfSMark Johnston 		goto done;
380967264cfSMark Johnston 
381967264cfSMark Johnston 	/* General purpose registers */
382967264cfSMark Johnston 	rdx = 0xf00;
383967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RAX, zero)) != 0)
384967264cfSMark Johnston 		goto done;
385967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBX, zero)) != 0)
386967264cfSMark Johnston 		goto done;
387967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RCX, zero)) != 0)
388967264cfSMark Johnston 		goto done;
389967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDX, rdx)) != 0)
390967264cfSMark Johnston 		goto done;
391967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSI, zero)) != 0)
392967264cfSMark Johnston 		goto done;
393967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDI, zero)) != 0)
394967264cfSMark Johnston 		goto done;
395967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBP, zero)) != 0)
396967264cfSMark Johnston 		goto done;
397967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSP, zero)) != 0)
398967264cfSMark Johnston 		goto done;
399967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R8, zero)) != 0)
400967264cfSMark Johnston 		goto done;
401967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R9, zero)) != 0)
402967264cfSMark Johnston 		goto done;
403967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R10, zero)) != 0)
404967264cfSMark Johnston 		goto done;
405967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R11, zero)) != 0)
406967264cfSMark Johnston 		goto done;
407967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R12, zero)) != 0)
408967264cfSMark Johnston 		goto done;
409967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R13, zero)) != 0)
410967264cfSMark Johnston 		goto done;
411967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R14, zero)) != 0)
412967264cfSMark Johnston 		goto done;
413967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R15, zero)) != 0)
414967264cfSMark Johnston 		goto done;
415967264cfSMark Johnston 
416967264cfSMark Johnston 	/* GDTR, IDTR */
417967264cfSMark Johnston 	desc_base = 0;
418967264cfSMark Johnston 	desc_limit = 0xffff;
419967264cfSMark Johnston 	desc_access = 0;
420967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_GDTR,
421967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
422967264cfSMark Johnston 	if (error != 0)
423967264cfSMark Johnston 		goto done;
424967264cfSMark Johnston 
425967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_IDTR,
426967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
427967264cfSMark Johnston 	if (error != 0)
428967264cfSMark Johnston 		goto done;
429967264cfSMark Johnston 
430967264cfSMark Johnston 	/* TR */
431967264cfSMark Johnston 	desc_base = 0;
432967264cfSMark Johnston 	desc_limit = 0xffff;
433967264cfSMark Johnston 	desc_access = 0x0000008b;
434967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_TR, 0, 0, desc_access);
435967264cfSMark Johnston 	if (error)
436967264cfSMark Johnston 		goto done;
437967264cfSMark Johnston 
438967264cfSMark Johnston 	sel = 0;
439967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_TR, sel)) != 0)
440967264cfSMark Johnston 		goto done;
441967264cfSMark Johnston 
442967264cfSMark Johnston 	/* LDTR */
443967264cfSMark Johnston 	desc_base = 0;
444967264cfSMark Johnston 	desc_limit = 0xffff;
445967264cfSMark Johnston 	desc_access = 0x00000082;
446967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_LDTR, desc_base,
447967264cfSMark Johnston 			    desc_limit, desc_access);
448967264cfSMark Johnston 	if (error)
449967264cfSMark Johnston 		goto done;
450967264cfSMark Johnston 
451967264cfSMark Johnston 	sel = 0;
452967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_LDTR, 0)) != 0)
453967264cfSMark Johnston 		goto done;
454967264cfSMark Johnston 
455967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR6,
456967264cfSMark Johnston 		 0xffff0ff0)) != 0)
457967264cfSMark Johnston 		goto done;
458967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR7, 0x400)) !=
459967264cfSMark Johnston 	    0)
460967264cfSMark Johnston 		goto done;
461967264cfSMark Johnston 
462967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_INTR_SHADOW,
463967264cfSMark Johnston 		 zero)) != 0)
464967264cfSMark Johnston 		goto done;
465967264cfSMark Johnston 
466967264cfSMark Johnston 	error = 0;
467967264cfSMark Johnston done:
468967264cfSMark Johnston 	return (error);
469967264cfSMark Johnston }
470