xref: /freebsd/lib/libvmmapi/amd64/vmmapi_machdep.c (revision e4656e10d13190d3149e3bb60e01c50f1c210885)
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 
29*e4656e10SMark Johnston #include <sys/types.h>
30*e4656e10SMark Johnston #include <sys/ioctl.h>
31*e4656e10SMark Johnston 
32967264cfSMark Johnston #include <machine/specialreg.h>
33*e4656e10SMark Johnston #include <machine/vmm.h>
34*e4656e10SMark Johnston 
35*e4656e10SMark Johnston #include <string.h>
36967264cfSMark Johnston 
37967264cfSMark Johnston #include "vmmapi.h"
38967264cfSMark Johnston #include "internal.h"
39967264cfSMark Johnston 
40*e4656e10SMark Johnston int
41*e4656e10SMark Johnston vm_set_desc(struct vcpu *vcpu, int reg,
42*e4656e10SMark Johnston 	    uint64_t base, uint32_t limit, uint32_t access)
43*e4656e10SMark Johnston {
44*e4656e10SMark Johnston 	int error;
45*e4656e10SMark Johnston 	struct vm_seg_desc vmsegdesc;
46*e4656e10SMark Johnston 
47*e4656e10SMark Johnston 	bzero(&vmsegdesc, sizeof(vmsegdesc));
48*e4656e10SMark Johnston 	vmsegdesc.regnum = reg;
49*e4656e10SMark Johnston 	vmsegdesc.desc.base = base;
50*e4656e10SMark Johnston 	vmsegdesc.desc.limit = limit;
51*e4656e10SMark Johnston 	vmsegdesc.desc.access = access;
52*e4656e10SMark Johnston 
53*e4656e10SMark Johnston 	error = vcpu_ioctl(vcpu, VM_SET_SEGMENT_DESCRIPTOR, &vmsegdesc);
54*e4656e10SMark Johnston 	return (error);
55*e4656e10SMark Johnston }
56*e4656e10SMark Johnston 
57*e4656e10SMark Johnston int
58*e4656e10SMark Johnston vm_get_desc(struct vcpu *vcpu, int reg, uint64_t *base, uint32_t *limit,
59*e4656e10SMark Johnston     uint32_t *access)
60*e4656e10SMark Johnston {
61*e4656e10SMark Johnston 	int error;
62*e4656e10SMark Johnston 	struct vm_seg_desc vmsegdesc;
63*e4656e10SMark Johnston 
64*e4656e10SMark Johnston 	bzero(&vmsegdesc, sizeof(vmsegdesc));
65*e4656e10SMark Johnston 	vmsegdesc.regnum = reg;
66*e4656e10SMark Johnston 
67*e4656e10SMark Johnston 	error = vcpu_ioctl(vcpu, VM_GET_SEGMENT_DESCRIPTOR, &vmsegdesc);
68*e4656e10SMark Johnston 	if (error == 0) {
69*e4656e10SMark Johnston 		*base = vmsegdesc.desc.base;
70*e4656e10SMark Johnston 		*limit = vmsegdesc.desc.limit;
71*e4656e10SMark Johnston 		*access = vmsegdesc.desc.access;
72*e4656e10SMark Johnston 	}
73*e4656e10SMark Johnston 	return (error);
74*e4656e10SMark Johnston }
75*e4656e10SMark Johnston 
76*e4656e10SMark Johnston int
77*e4656e10SMark Johnston vm_get_seg_desc(struct vcpu *vcpu, int reg, struct seg_desc *seg_desc)
78*e4656e10SMark Johnston {
79*e4656e10SMark Johnston 	int error;
80*e4656e10SMark Johnston 
81*e4656e10SMark Johnston 	error = vm_get_desc(vcpu, reg, &seg_desc->base, &seg_desc->limit,
82*e4656e10SMark Johnston 	    &seg_desc->access);
83*e4656e10SMark Johnston 	return (error);
84*e4656e10SMark Johnston }
85*e4656e10SMark Johnston 
86*e4656e10SMark Johnston int
87*e4656e10SMark Johnston vm_lapic_irq(struct vcpu *vcpu, int vector)
88*e4656e10SMark Johnston {
89*e4656e10SMark Johnston 	struct vm_lapic_irq vmirq;
90*e4656e10SMark Johnston 
91*e4656e10SMark Johnston 	bzero(&vmirq, sizeof(vmirq));
92*e4656e10SMark Johnston 	vmirq.vector = vector;
93*e4656e10SMark Johnston 
94*e4656e10SMark Johnston 	return (vcpu_ioctl(vcpu, VM_LAPIC_IRQ, &vmirq));
95*e4656e10SMark Johnston }
96*e4656e10SMark Johnston 
97*e4656e10SMark Johnston int
98*e4656e10SMark Johnston vm_lapic_local_irq(struct vcpu *vcpu, int vector)
99*e4656e10SMark Johnston {
100*e4656e10SMark Johnston 	struct vm_lapic_irq vmirq;
101*e4656e10SMark Johnston 
102*e4656e10SMark Johnston 	bzero(&vmirq, sizeof(vmirq));
103*e4656e10SMark Johnston 	vmirq.vector = vector;
104*e4656e10SMark Johnston 
105*e4656e10SMark Johnston 	return (vcpu_ioctl(vcpu, VM_LAPIC_LOCAL_IRQ, &vmirq));
106*e4656e10SMark Johnston }
107*e4656e10SMark Johnston 
108*e4656e10SMark Johnston int
109*e4656e10SMark Johnston vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg)
110*e4656e10SMark Johnston {
111*e4656e10SMark Johnston 	struct vm_lapic_msi vmmsi;
112*e4656e10SMark Johnston 
113*e4656e10SMark Johnston 	bzero(&vmmsi, sizeof(vmmsi));
114*e4656e10SMark Johnston 	vmmsi.addr = addr;
115*e4656e10SMark Johnston 	vmmsi.msg = msg;
116*e4656e10SMark Johnston 
117*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_LAPIC_MSI, &vmmsi));
118*e4656e10SMark Johnston }
119*e4656e10SMark Johnston 
120*e4656e10SMark Johnston int
121*e4656e10SMark Johnston vm_apicid2vcpu(struct vmctx *ctx __unused, int apicid)
122*e4656e10SMark Johnston {
123*e4656e10SMark Johnston 	/*
124*e4656e10SMark Johnston 	 * The apic id associated with the 'vcpu' has the same numerical value
125*e4656e10SMark Johnston 	 * as the 'vcpu' itself.
126*e4656e10SMark Johnston 	 */
127*e4656e10SMark Johnston 	return (apicid);
128*e4656e10SMark Johnston }
129*e4656e10SMark Johnston 
130*e4656e10SMark Johnston int
131*e4656e10SMark Johnston vm_ioapic_assert_irq(struct vmctx *ctx, int irq)
132*e4656e10SMark Johnston {
133*e4656e10SMark Johnston 	struct vm_ioapic_irq ioapic_irq;
134*e4656e10SMark Johnston 
135*e4656e10SMark Johnston 	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
136*e4656e10SMark Johnston 	ioapic_irq.irq = irq;
137*e4656e10SMark Johnston 
138*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_IOAPIC_ASSERT_IRQ, &ioapic_irq));
139*e4656e10SMark Johnston }
140*e4656e10SMark Johnston 
141*e4656e10SMark Johnston int
142*e4656e10SMark Johnston vm_ioapic_deassert_irq(struct vmctx *ctx, int irq)
143*e4656e10SMark Johnston {
144*e4656e10SMark Johnston 	struct vm_ioapic_irq ioapic_irq;
145*e4656e10SMark Johnston 
146*e4656e10SMark Johnston 	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
147*e4656e10SMark Johnston 	ioapic_irq.irq = irq;
148*e4656e10SMark Johnston 
149*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_IOAPIC_DEASSERT_IRQ, &ioapic_irq));
150*e4656e10SMark Johnston }
151*e4656e10SMark Johnston 
152*e4656e10SMark Johnston int
153*e4656e10SMark Johnston vm_ioapic_pulse_irq(struct vmctx *ctx, int irq)
154*e4656e10SMark Johnston {
155*e4656e10SMark Johnston 	struct vm_ioapic_irq ioapic_irq;
156*e4656e10SMark Johnston 
157*e4656e10SMark Johnston 	bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq));
158*e4656e10SMark Johnston 	ioapic_irq.irq = irq;
159*e4656e10SMark Johnston 
160*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_IOAPIC_PULSE_IRQ, &ioapic_irq));
161*e4656e10SMark Johnston }
162*e4656e10SMark Johnston 
163*e4656e10SMark Johnston int
164*e4656e10SMark Johnston vm_ioapic_pincount(struct vmctx *ctx, int *pincount)
165*e4656e10SMark Johnston {
166*e4656e10SMark Johnston 
167*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_IOAPIC_PINCOUNT, pincount));
168*e4656e10SMark Johnston }
169*e4656e10SMark Johnston 
170*e4656e10SMark Johnston int
171*e4656e10SMark Johnston vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq)
172*e4656e10SMark Johnston {
173*e4656e10SMark Johnston 	struct vm_isa_irq isa_irq;
174*e4656e10SMark Johnston 
175*e4656e10SMark Johnston 	bzero(&isa_irq, sizeof(struct vm_isa_irq));
176*e4656e10SMark Johnston 	isa_irq.atpic_irq = atpic_irq;
177*e4656e10SMark Johnston 	isa_irq.ioapic_irq = ioapic_irq;
178*e4656e10SMark Johnston 
179*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_ISA_ASSERT_IRQ, &isa_irq));
180*e4656e10SMark Johnston }
181*e4656e10SMark Johnston 
182*e4656e10SMark Johnston int
183*e4656e10SMark Johnston vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq)
184*e4656e10SMark Johnston {
185*e4656e10SMark Johnston 	struct vm_isa_irq isa_irq;
186*e4656e10SMark Johnston 
187*e4656e10SMark Johnston 	bzero(&isa_irq, sizeof(struct vm_isa_irq));
188*e4656e10SMark Johnston 	isa_irq.atpic_irq = atpic_irq;
189*e4656e10SMark Johnston 	isa_irq.ioapic_irq = ioapic_irq;
190*e4656e10SMark Johnston 
191*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_ISA_DEASSERT_IRQ, &isa_irq));
192*e4656e10SMark Johnston }
193*e4656e10SMark Johnston 
194*e4656e10SMark Johnston int
195*e4656e10SMark Johnston vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq)
196*e4656e10SMark Johnston {
197*e4656e10SMark Johnston 	struct vm_isa_irq isa_irq;
198*e4656e10SMark Johnston 
199*e4656e10SMark Johnston 	bzero(&isa_irq, sizeof(struct vm_isa_irq));
200*e4656e10SMark Johnston 	isa_irq.atpic_irq = atpic_irq;
201*e4656e10SMark Johnston 	isa_irq.ioapic_irq = ioapic_irq;
202*e4656e10SMark Johnston 
203*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_ISA_PULSE_IRQ, &isa_irq));
204*e4656e10SMark Johnston }
205*e4656e10SMark Johnston 
206*e4656e10SMark Johnston int
207*e4656e10SMark Johnston vm_isa_set_irq_trigger(struct vmctx *ctx, int atpic_irq,
208*e4656e10SMark Johnston     enum vm_intr_trigger trigger)
209*e4656e10SMark Johnston {
210*e4656e10SMark Johnston 	struct vm_isa_irq_trigger isa_irq_trigger;
211*e4656e10SMark Johnston 
212*e4656e10SMark Johnston 	bzero(&isa_irq_trigger, sizeof(struct vm_isa_irq_trigger));
213*e4656e10SMark Johnston 	isa_irq_trigger.atpic_irq = atpic_irq;
214*e4656e10SMark Johnston 	isa_irq_trigger.trigger = trigger;
215*e4656e10SMark Johnston 
216*e4656e10SMark Johnston 	return (ioctl(ctx->fd, VM_ISA_SET_IRQ_TRIGGER, &isa_irq_trigger));
217*e4656e10SMark Johnston }
218*e4656e10SMark Johnston 
219*e4656e10SMark Johnston int
220*e4656e10SMark Johnston vm_inject_nmi(struct vcpu *vcpu)
221*e4656e10SMark Johnston {
222*e4656e10SMark Johnston 	struct vm_nmi vmnmi;
223*e4656e10SMark Johnston 
224*e4656e10SMark Johnston 	bzero(&vmnmi, sizeof(vmnmi));
225*e4656e10SMark Johnston 
226*e4656e10SMark Johnston 	return (vcpu_ioctl(vcpu, VM_INJECT_NMI, &vmnmi));
227*e4656e10SMark Johnston }
228*e4656e10SMark Johnston 
229967264cfSMark Johnston /*
230967264cfSMark Johnston  * From Intel Vol 3a:
231967264cfSMark Johnston  * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT
232967264cfSMark Johnston  */
233967264cfSMark Johnston int
234967264cfSMark Johnston vcpu_reset(struct vcpu *vcpu)
235967264cfSMark Johnston {
236967264cfSMark Johnston 	int error;
237967264cfSMark Johnston 	uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx;
238967264cfSMark Johnston 	uint32_t desc_access, desc_limit;
239967264cfSMark Johnston 	uint16_t sel;
240967264cfSMark Johnston 
241967264cfSMark Johnston 	zero = 0;
242967264cfSMark Johnston 
243967264cfSMark Johnston 	rflags = 0x2;
244967264cfSMark Johnston 	error = vm_set_register(vcpu, VM_REG_GUEST_RFLAGS, rflags);
245967264cfSMark Johnston 	if (error)
246967264cfSMark Johnston 		goto done;
247967264cfSMark Johnston 
248967264cfSMark Johnston 	rip = 0xfff0;
249967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RIP, rip)) != 0)
250967264cfSMark Johnston 		goto done;
251967264cfSMark Johnston 
252967264cfSMark Johnston 	/*
253967264cfSMark Johnston 	 * According to Intels Software Developer Manual CR0 should be
254967264cfSMark Johnston 	 * initialized with CR0_ET | CR0_NW | CR0_CD but that crashes some
255967264cfSMark Johnston 	 * guests like Windows.
256967264cfSMark Johnston 	 */
257967264cfSMark Johnston 	cr0 = CR0_NE;
258967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR0, cr0)) != 0)
259967264cfSMark Johnston 		goto done;
260967264cfSMark Johnston 
261967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR2, zero)) != 0)
262967264cfSMark Johnston 		goto done;
263967264cfSMark Johnston 
264967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR3, zero)) != 0)
265967264cfSMark Johnston 		goto done;
266967264cfSMark Johnston 
267967264cfSMark Johnston 	cr4 = 0;
268967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR4, cr4)) != 0)
269967264cfSMark Johnston 		goto done;
270967264cfSMark Johnston 
271967264cfSMark Johnston 	/*
272967264cfSMark Johnston 	 * CS: present, r/w, accessed, 16-bit, byte granularity, usable
273967264cfSMark Johnston 	 */
274967264cfSMark Johnston 	desc_base = 0xffff0000;
275967264cfSMark Johnston 	desc_limit = 0xffff;
276967264cfSMark Johnston 	desc_access = 0x0093;
277967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_CS,
278967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
279967264cfSMark Johnston 	if (error)
280967264cfSMark Johnston 		goto done;
281967264cfSMark Johnston 
282967264cfSMark Johnston 	sel = 0xf000;
283967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_CS, sel)) != 0)
284967264cfSMark Johnston 		goto done;
285967264cfSMark Johnston 
286967264cfSMark Johnston 	/*
287967264cfSMark Johnston 	 * SS,DS,ES,FS,GS: present, r/w, accessed, 16-bit, byte granularity
288967264cfSMark Johnston 	 */
289967264cfSMark Johnston 	desc_base = 0;
290967264cfSMark Johnston 	desc_limit = 0xffff;
291967264cfSMark Johnston 	desc_access = 0x0093;
292967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_SS,
293967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
294967264cfSMark Johnston 	if (error)
295967264cfSMark Johnston 		goto done;
296967264cfSMark Johnston 
297967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_DS,
298967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
299967264cfSMark Johnston 	if (error)
300967264cfSMark Johnston 		goto done;
301967264cfSMark Johnston 
302967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_ES,
303967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
304967264cfSMark Johnston 	if (error)
305967264cfSMark Johnston 		goto done;
306967264cfSMark Johnston 
307967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_FS,
308967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
309967264cfSMark Johnston 	if (error)
310967264cfSMark Johnston 		goto done;
311967264cfSMark Johnston 
312967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_GS,
313967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
314967264cfSMark Johnston 	if (error)
315967264cfSMark Johnston 		goto done;
316967264cfSMark Johnston 
317967264cfSMark Johnston 	sel = 0;
318967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_SS, sel)) != 0)
319967264cfSMark Johnston 		goto done;
320967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_DS, sel)) != 0)
321967264cfSMark Johnston 		goto done;
322967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_ES, sel)) != 0)
323967264cfSMark Johnston 		goto done;
324967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_FS, sel)) != 0)
325967264cfSMark Johnston 		goto done;
326967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_GS, sel)) != 0)
327967264cfSMark Johnston 		goto done;
328967264cfSMark Johnston 
329967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_EFER, zero)) != 0)
330967264cfSMark Johnston 		goto done;
331967264cfSMark Johnston 
332967264cfSMark Johnston 	/* General purpose registers */
333967264cfSMark Johnston 	rdx = 0xf00;
334967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RAX, zero)) != 0)
335967264cfSMark Johnston 		goto done;
336967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBX, zero)) != 0)
337967264cfSMark Johnston 		goto done;
338967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RCX, zero)) != 0)
339967264cfSMark Johnston 		goto done;
340967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDX, rdx)) != 0)
341967264cfSMark Johnston 		goto done;
342967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSI, zero)) != 0)
343967264cfSMark Johnston 		goto done;
344967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDI, zero)) != 0)
345967264cfSMark Johnston 		goto done;
346967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBP, zero)) != 0)
347967264cfSMark Johnston 		goto done;
348967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSP, zero)) != 0)
349967264cfSMark Johnston 		goto done;
350967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R8, zero)) != 0)
351967264cfSMark Johnston 		goto done;
352967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R9, zero)) != 0)
353967264cfSMark Johnston 		goto done;
354967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R10, zero)) != 0)
355967264cfSMark Johnston 		goto done;
356967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R11, zero)) != 0)
357967264cfSMark Johnston 		goto done;
358967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R12, zero)) != 0)
359967264cfSMark Johnston 		goto done;
360967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R13, zero)) != 0)
361967264cfSMark Johnston 		goto done;
362967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R14, zero)) != 0)
363967264cfSMark Johnston 		goto done;
364967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_R15, zero)) != 0)
365967264cfSMark Johnston 		goto done;
366967264cfSMark Johnston 
367967264cfSMark Johnston 	/* GDTR, IDTR */
368967264cfSMark Johnston 	desc_base = 0;
369967264cfSMark Johnston 	desc_limit = 0xffff;
370967264cfSMark Johnston 	desc_access = 0;
371967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_GDTR,
372967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
373967264cfSMark Johnston 	if (error != 0)
374967264cfSMark Johnston 		goto done;
375967264cfSMark Johnston 
376967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_IDTR,
377967264cfSMark Johnston 			    desc_base, desc_limit, desc_access);
378967264cfSMark Johnston 	if (error != 0)
379967264cfSMark Johnston 		goto done;
380967264cfSMark Johnston 
381967264cfSMark Johnston 	/* TR */
382967264cfSMark Johnston 	desc_base = 0;
383967264cfSMark Johnston 	desc_limit = 0xffff;
384967264cfSMark Johnston 	desc_access = 0x0000008b;
385967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_TR, 0, 0, desc_access);
386967264cfSMark Johnston 	if (error)
387967264cfSMark Johnston 		goto done;
388967264cfSMark Johnston 
389967264cfSMark Johnston 	sel = 0;
390967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_TR, sel)) != 0)
391967264cfSMark Johnston 		goto done;
392967264cfSMark Johnston 
393967264cfSMark Johnston 	/* LDTR */
394967264cfSMark Johnston 	desc_base = 0;
395967264cfSMark Johnston 	desc_limit = 0xffff;
396967264cfSMark Johnston 	desc_access = 0x00000082;
397967264cfSMark Johnston 	error = vm_set_desc(vcpu, VM_REG_GUEST_LDTR, desc_base,
398967264cfSMark Johnston 			    desc_limit, desc_access);
399967264cfSMark Johnston 	if (error)
400967264cfSMark Johnston 		goto done;
401967264cfSMark Johnston 
402967264cfSMark Johnston 	sel = 0;
403967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_LDTR, 0)) != 0)
404967264cfSMark Johnston 		goto done;
405967264cfSMark Johnston 
406967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR6,
407967264cfSMark Johnston 		 0xffff0ff0)) != 0)
408967264cfSMark Johnston 		goto done;
409967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR7, 0x400)) !=
410967264cfSMark Johnston 	    0)
411967264cfSMark Johnston 		goto done;
412967264cfSMark Johnston 
413967264cfSMark Johnston 	if ((error = vm_set_register(vcpu, VM_REG_GUEST_INTR_SHADOW,
414967264cfSMark Johnston 		 zero)) != 0)
415967264cfSMark Johnston 		goto done;
416967264cfSMark Johnston 
417967264cfSMark Johnston 	error = 0;
418967264cfSMark Johnston done:
419967264cfSMark Johnston 	return (error);
420967264cfSMark Johnston }
421