xref: /illumos-gate/usr/src/cmd/bhyvectl/bhyvectl.c (revision 57f6b2a25cc23b5c46f9c6de51402167ec6754cc)
1 /*-
2  * Copyright (c) 2011 NetApp, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: head/usr.sbin/bhyvectl/bhyvectl.c 273375 2014-10-21 07:10:43Z neel $
27  */
28 /*
29  * This file and its contents are supplied under the terms of the
30  * Common Development and Distribution License ("CDDL"), version 1.0.
31  * You may only use this file in accordance with the terms of version
32  * 1.0 of the CDDL.
33  *
34  * A full copy of the text of the CDDL should have accompanied this
35  * source.  A copy of the CDDL is also available via the Internet at
36  * http://www.illumos.org/license/CDDL.
37  */
38 
39 /*
40  * Copyright 2015 Pluribus Networks Inc.
41  */
42 
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD: head/usr.sbin/bhyvectl/bhyvectl.c 273375 2014-10-21 07:10:43Z neel $");
45 
46 #include <sys/param.h>
47 #include <sys/types.h>
48 #include <sys/sysctl.h>
49 #include <sys/errno.h>
50 #include <sys/mman.h>
51 
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <unistd.h>
55 #include <libgen.h>
56 #include <libutil.h>
57 #include <fcntl.h>
58 #include <string.h>
59 #include <getopt.h>
60 #include <assert.h>
61 
62 #include <machine/vmm.h>
63 #include <vmmapi.h>
64 
65 #include "intel/vmcs.h"
66 
67 #define	MB	(1UL << 20)
68 #define	GB	(1UL << 30)
69 
70 #define	REQ_ARG		required_argument
71 #define	NO_ARG		no_argument
72 #define	OPT_ARG		optional_argument
73 
74 static const char *progname;
75 
76 static void
77 usage(void)
78 {
79 
80 	(void)fprintf(stderr,
81 	"Usage: %s --vm=<vmname>\n"
82 	"       [--cpu=<vcpu_number>]\n"
83 	"       [--create]\n"
84 	"       [--destroy]\n"
85 	"       [--get-all]\n"
86 	"       [--get-stats]\n"
87 	"       [--set-desc-ds]\n"
88 	"       [--get-desc-ds]\n"
89 	"       [--set-desc-es]\n"
90 	"       [--get-desc-es]\n"
91 	"       [--set-desc-gs]\n"
92 	"       [--get-desc-gs]\n"
93 	"       [--set-desc-fs]\n"
94 	"       [--get-desc-fs]\n"
95 	"       [--set-desc-cs]\n"
96 	"       [--get-desc-cs]\n"
97 	"       [--set-desc-ss]\n"
98 	"       [--get-desc-ss]\n"
99 	"       [--set-desc-tr]\n"
100 	"       [--get-desc-tr]\n"
101 	"       [--set-desc-ldtr]\n"
102 	"       [--get-desc-ldtr]\n"
103 	"       [--set-desc-gdtr]\n"
104 	"       [--get-desc-gdtr]\n"
105 	"       [--set-desc-idtr]\n"
106 	"       [--get-desc-idtr]\n"
107 	"       [--run]\n"
108 	"       [--capname=<capname>]\n"
109 	"       [--getcap]\n"
110 	"       [--setcap=<0|1>]\n"
111 	"       [--desc-base=<BASE>]\n"
112 	"       [--desc-limit=<LIMIT>]\n"
113 	"       [--desc-access=<ACCESS>]\n"
114 	"       [--set-cr0=<CR0>]\n"
115 	"       [--get-cr0]\n"
116 	"       [--set-cr3=<CR3>]\n"
117 	"       [--get-cr3]\n"
118 	"       [--set-cr4=<CR4>]\n"
119 	"       [--get-cr4]\n"
120 	"       [--set-dr7=<DR7>]\n"
121 	"       [--get-dr7]\n"
122 	"       [--set-rsp=<RSP>]\n"
123 	"       [--get-rsp]\n"
124 	"       [--set-rip=<RIP>]\n"
125 	"       [--get-rip]\n"
126 	"       [--get-rax]\n"
127 	"       [--set-rax=<RAX>]\n"
128 	"       [--get-rbx]\n"
129 	"       [--get-rcx]\n"
130 	"       [--get-rdx]\n"
131 	"       [--get-rsi]\n"
132 	"       [--get-rdi]\n"
133 	"       [--get-rbp]\n"
134 	"       [--get-r8]\n"
135 	"       [--get-r9]\n"
136 	"       [--get-r10]\n"
137 	"       [--get-r11]\n"
138 	"       [--get-r12]\n"
139 	"       [--get-r13]\n"
140 	"       [--get-r14]\n"
141 	"       [--get-r15]\n"
142 	"       [--set-rflags=<RFLAGS>]\n"
143 	"       [--get-rflags]\n"
144 	"       [--set-cs]\n"
145 	"       [--get-cs]\n"
146 	"       [--set-ds]\n"
147 	"       [--get-ds]\n"
148 	"       [--set-es]\n"
149 	"       [--get-es]\n"
150 	"       [--set-fs]\n"
151 	"       [--get-fs]\n"
152 	"       [--set-gs]\n"
153 	"       [--get-gs]\n"
154 	"       [--set-ss]\n"
155 	"       [--get-ss]\n"
156 	"       [--get-tr]\n"
157 	"       [--get-ldtr]\n"
158 	"       [--get-vmcs-pinbased-ctls]\n"
159 	"       [--get-vmcs-procbased-ctls]\n"
160 	"       [--get-vmcs-procbased-ctls2]\n"
161 	"       [--get-vmcs-entry-interruption-info]\n"
162 	"       [--set-vmcs-entry-interruption-info=<info>]\n"
163 	"       [--get-vmcs-eptp]\n"
164 	"       [--get-vmcs-guest-physical-address\n"
165 	"       [--get-vmcs-guest-linear-address\n"
166 	"       [--set-vmcs-exception-bitmap]\n"
167 	"       [--get-vmcs-exception-bitmap]\n"
168 	"       [--get-vmcs-io-bitmap-address]\n"
169 	"       [--get-vmcs-tsc-offset]\n"
170 	"       [--get-vmcs-guest-pat]\n"
171 	"       [--get-vmcs-host-pat]\n"
172 	"       [--get-vmcs-host-cr0]\n"
173 	"       [--get-vmcs-host-cr3]\n"
174 	"       [--get-vmcs-host-cr4]\n"
175 	"       [--get-vmcs-host-rip]\n"
176 	"       [--get-vmcs-host-rsp]\n"
177 	"       [--get-vmcs-cr0-mask]\n"
178 	"       [--get-vmcs-cr0-shadow]\n"
179 	"       [--get-vmcs-cr4-mask]\n"
180 	"       [--get-vmcs-cr4-shadow]\n"
181 	"       [--get-vmcs-cr3-targets]\n"
182 	"       [--get-vmcs-apic-access-address]\n"
183 	"       [--get-vmcs-virtual-apic-address]\n"
184 	"       [--get-vmcs-tpr-threshold]\n"
185 	"       [--get-vmcs-msr-bitmap]\n"
186 	"       [--get-vmcs-msr-bitmap-address]\n"
187 	"       [--get-vmcs-vpid]\n"
188 	"       [--get-vmcs-ple-gap]\n"
189 	"       [--get-vmcs-ple-window]\n"
190 	"       [--get-vmcs-instruction-error]\n"
191 	"       [--get-vmcs-exit-ctls]\n"
192 	"       [--get-vmcs-entry-ctls]\n"
193 	"       [--get-vmcs-guest-sysenter]\n"
194 	"       [--get-vmcs-link]\n"
195 	"       [--get-vmcs-exit-reason]\n"
196 	"       [--get-vmcs-exit-qualification]\n"
197 	"       [--get-vmcs-exit-interruption-info]\n"
198 	"       [--get-vmcs-exit-interruption-error]\n"
199 	"       [--get-vmcs-interruptibility]\n"
200 	"       [--set-x2apic-state=<state>]\n"
201 	"       [--get-x2apic-state]\n"
202 	"       [--unassign-pptdev=<bus/slot/func>]\n"
203 	"       [--set-mem=<memory in units of MB>]\n"
204 	"       [--get-lowmem]\n"
205 	"       [--get-highmem]\n",
206 	progname);
207 	exit(1);
208 }
209 
210 static int get_stats, getcap, setcap, capval;
211 static const char *capname;
212 static int create, destroy, get_lowmem, get_highmem;
213 static uint64_t memsize;
214 static int set_cr0, get_cr0, set_cr3, get_cr3, set_cr4, get_cr4;
215 static int set_efer, get_efer;
216 static int set_dr7, get_dr7;
217 static int set_rsp, get_rsp, set_rip, get_rip, set_rflags, get_rflags;
218 static int set_rax, get_rax;
219 static int get_rbx, get_rcx, get_rdx, get_rsi, get_rdi, get_rbp;
220 static int get_r8, get_r9, get_r10, get_r11, get_r12, get_r13, get_r14, get_r15;
221 static int set_desc_ds, get_desc_ds;
222 static int set_desc_es, get_desc_es;
223 static int set_desc_fs, get_desc_fs;
224 static int set_desc_gs, get_desc_gs;
225 static int set_desc_cs, get_desc_cs;
226 static int set_desc_ss, get_desc_ss;
227 static int set_desc_gdtr, get_desc_gdtr;
228 static int set_desc_idtr, get_desc_idtr;
229 static int set_desc_tr, get_desc_tr;
230 static int set_desc_ldtr, get_desc_ldtr;
231 static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr;
232 static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr;
233 static int set_x2apic_state, get_x2apic_state;
234 enum x2apic_state x2apic_state;
235 static int unassign_pptdev, bus, slot, func;
236 static int run;
237 
238 /*
239  * VMCS-specific fields
240  */
241 static int get_pinbased_ctls, get_procbased_ctls, get_procbased_ctls2;
242 static int get_eptp, get_io_bitmap, get_tsc_offset;
243 static int get_vmcs_entry_interruption_info, set_vmcs_entry_interruption_info;
244 static int get_vmcs_interruptibility;
245 uint32_t vmcs_entry_interruption_info;
246 static int get_vmcs_gpa, get_vmcs_gla;
247 static int get_exception_bitmap, set_exception_bitmap, exception_bitmap;
248 static int get_cr0_mask, get_cr0_shadow;
249 static int get_cr4_mask, get_cr4_shadow;
250 static int get_cr3_targets;
251 static int get_apic_access_addr, get_virtual_apic_addr, get_tpr_threshold;
252 static int get_msr_bitmap, get_msr_bitmap_address;
253 static int get_vpid, get_ple_gap, get_ple_window;
254 static int get_inst_err, get_exit_ctls, get_entry_ctls;
255 static int get_host_cr0, get_host_cr3, get_host_cr4;
256 static int get_host_rip, get_host_rsp;
257 static int get_guest_pat, get_host_pat;
258 static int get_guest_sysenter, get_vmcs_link;
259 static int get_vmcs_exit_reason, get_vmcs_exit_qualification;
260 static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error;
261 
262 static uint64_t desc_base;
263 static uint32_t desc_limit, desc_access;
264 
265 static int get_all;
266 
267 static void
268 dump_vm_run_exitcode(struct vm_exit *vmexit, int vcpu)
269 {
270 	printf("vm exit[%d]\n", vcpu);
271 	printf("\trip\t\t0x%016lx\n", vmexit->rip);
272 	printf("\tinst_length\t%d\n", vmexit->inst_length);
273 	switch (vmexit->exitcode) {
274 	case VM_EXITCODE_INOUT:
275 		printf("\treason\t\tINOUT\n");
276 		printf("\tdirection\t%s\n", vmexit->u.inout.in ? "IN" : "OUT");
277 		printf("\tbytes\t\t%d\n", vmexit->u.inout.bytes);
278 		printf("\tflags\t\t%s%s\n",
279 			vmexit->u.inout.string ? "STRING " : "",
280 			vmexit->u.inout.rep ? "REP " : "");
281 		printf("\tport\t\t0x%04x\n", vmexit->u.inout.port);
282 		printf("\teax\t\t0x%08x\n", vmexit->u.inout.eax);
283 		break;
284 	case VM_EXITCODE_VMX:
285 		printf("\treason\t\tVMX\n");
286 		printf("\tstatus\t\t%d\n", vmexit->u.vmx.status);
287 		printf("\texit_reason\t0x%08x (%u)\n",
288 		    vmexit->u.vmx.exit_reason, vmexit->u.vmx.exit_reason);
289 		printf("\tqualification\t0x%016lx\n",
290 			vmexit->u.vmx.exit_qualification);
291 		printf("\tinst_type\t\t%d\n", vmexit->u.vmx.inst_type);
292 		printf("\tinst_error\t\t%d\n", vmexit->u.vmx.inst_error);
293 		break;
294 	default:
295 		printf("*** unknown vm run exitcode %d\n", vmexit->exitcode);
296 		break;
297 	}
298 }
299 
300 static int
301 dump_vmcs_msr_bitmap(int vcpu, u_long addr)
302 {
303 	int error, fd, byte, bit, readable, writeable;
304 	u_int msr;
305 	const char *bitmap;
306 
307 	error = -1;
308 	bitmap = MAP_FAILED;
309 
310 	fd = open("/dev/mem", O_RDONLY, 0);
311 	if (fd < 0)
312 		goto done;
313 
314 	bitmap = mmap(NULL, PAGE_SIZE, PROT_READ, 0, fd, addr);
315 	if (bitmap == MAP_FAILED)
316 		goto done;
317 
318 	for (msr = 0; msr < 0x2000; msr++) {
319 		byte = msr / 8;
320 		bit = msr & 0x7;
321 
322 		/* Look at MSRs in the range 0x00000000 to 0x00001FFF */
323 		readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
324 		writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1;
325 		if (readable || writeable) {
326 			printf("msr 0x%08x[%d]\t\t%c%c\n", msr, vcpu,
327 				readable ? 'R' : '-',
328 				writeable ? 'W' : '-');
329 		}
330 
331 		/* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */
332 		byte += 1024;
333 		readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
334 		writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1;
335 		if (readable || writeable) {
336 			printf("msr 0x%08x[%d]\t\t%c%c\n",
337 				0xc0000000 + msr, vcpu,
338 				readable ? 'R' : '-',
339 				writeable ? 'W' : '-');
340 		}
341 	}
342 
343 	error = 0;
344 done:
345 	if (bitmap != MAP_FAILED)
346 		munmap((void *)bitmap, PAGE_SIZE);
347 	if (fd >= 0)
348 		close(fd);
349 	return (error);
350 }
351 
352 static int
353 vm_get_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t *ret_val)
354 {
355 
356 	return (vm_get_register(ctx, vcpu, VMCS_IDENT(field), ret_val));
357 }
358 
359 static int
360 vm_set_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t val)
361 {
362 
363 	return (vm_set_register(ctx, vcpu, VMCS_IDENT(field), val));
364 }
365 
366 enum {
367 	VMNAME = 1000,	/* avoid collision with return values from getopt */
368 	VCPU,
369 	SET_MEM,
370 	SET_EFER,
371 	SET_CR0,
372 	SET_CR3,
373 	SET_CR4,
374 	SET_DR7,
375 	SET_RSP,
376 	SET_RIP,
377 	SET_RAX,
378 	SET_RFLAGS,
379 	DESC_BASE,
380 	DESC_LIMIT,
381 	DESC_ACCESS,
382 	SET_CS,
383 	SET_DS,
384 	SET_ES,
385 	SET_FS,
386 	SET_GS,
387 	SET_SS,
388 	SET_TR,
389 	SET_LDTR,
390 	SET_X2APIC_STATE,
391 	SET_VMCS_EXCEPTION_BITMAP,
392 	SET_VMCS_ENTRY_INTERRUPTION_INFO,
393 	SET_CAP,
394 	CAPNAME,
395 	UNASSIGN_PPTDEV,
396 };
397 
398 int
399 main(int argc, char *argv[])
400 {
401 	char *vmname;
402 	int error, ch, vcpu;
403 	vm_paddr_t gpa;
404 	size_t len;
405 	struct vm_exit vmexit;
406 	uint64_t ctl, eptp, bm, addr, u64;
407 	struct vmctx *ctx;
408 	int wired;
409 
410 	uint64_t cr0, cr3, cr4, dr7, rsp, rip, rflags, efer, pat;
411 	uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp;
412 	uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
413 	uint64_t cs, ds, es, fs, gs, ss, tr, ldtr;
414 
415 	struct option opts[] = {
416 		{ "vm",		REQ_ARG,	0,	VMNAME },
417 		{ "cpu",	REQ_ARG,	0,	VCPU },
418 		{ "set-mem",	REQ_ARG,	0,	SET_MEM },
419 		{ "set-efer",	REQ_ARG,	0,	SET_EFER },
420 		{ "set-cr0",	REQ_ARG,	0,	SET_CR0 },
421 		{ "set-cr3",	REQ_ARG,	0,	SET_CR3 },
422 		{ "set-cr4",	REQ_ARG,	0,	SET_CR4 },
423 		{ "set-dr7",	REQ_ARG,	0,	SET_DR7 },
424 		{ "set-rsp",	REQ_ARG,	0,	SET_RSP },
425 		{ "set-rip",	REQ_ARG,	0,	SET_RIP },
426 		{ "set-rax",	REQ_ARG,	0,	SET_RAX },
427 		{ "set-rflags",	REQ_ARG,	0,	SET_RFLAGS },
428 		{ "desc-base",	REQ_ARG,	0,	DESC_BASE },
429 		{ "desc-limit",	REQ_ARG,	0,	DESC_LIMIT },
430 		{ "desc-access",REQ_ARG,	0,	DESC_ACCESS },
431 		{ "set-cs",	REQ_ARG,	0,	SET_CS },
432 		{ "set-ds",	REQ_ARG,	0,	SET_DS },
433 		{ "set-es",	REQ_ARG,	0,	SET_ES },
434 		{ "set-fs",	REQ_ARG,	0,	SET_FS },
435 		{ "set-gs",	REQ_ARG,	0,	SET_GS },
436 		{ "set-ss",	REQ_ARG,	0,	SET_SS },
437 		{ "set-tr",	REQ_ARG,	0,	SET_TR },
438 		{ "set-ldtr",	REQ_ARG,	0,	SET_LDTR },
439 		{ "set-x2apic-state",REQ_ARG,	0,	SET_X2APIC_STATE },
440 		{ "set-vmcs-exception-bitmap",
441 				REQ_ARG,	0, SET_VMCS_EXCEPTION_BITMAP },
442 		{ "set-vmcs-entry-interruption-info",
443 				REQ_ARG, 0, SET_VMCS_ENTRY_INTERRUPTION_INFO },
444 		{ "capname",	REQ_ARG,	0,	CAPNAME },
445 		{ "unassign-pptdev", REQ_ARG,	0,	UNASSIGN_PPTDEV },
446 		{ "setcap",	REQ_ARG,	0,	SET_CAP },
447 		{ "getcap",	NO_ARG,		&getcap,	1 },
448 		{ "get-stats",	NO_ARG,		&get_stats,	1 },
449 		{ "get-desc-ds",NO_ARG,		&get_desc_ds,	1 },
450 		{ "set-desc-ds",NO_ARG,		&set_desc_ds,	1 },
451 		{ "get-desc-es",NO_ARG,		&get_desc_es,	1 },
452 		{ "set-desc-es",NO_ARG,		&set_desc_es,	1 },
453 		{ "get-desc-ss",NO_ARG,		&get_desc_ss,	1 },
454 		{ "set-desc-ss",NO_ARG,		&set_desc_ss,	1 },
455 		{ "get-desc-cs",NO_ARG,		&get_desc_cs,	1 },
456 		{ "set-desc-cs",NO_ARG,		&set_desc_cs,	1 },
457 		{ "get-desc-fs",NO_ARG,		&get_desc_fs,	1 },
458 		{ "set-desc-fs",NO_ARG,		&set_desc_fs,	1 },
459 		{ "get-desc-gs",NO_ARG,		&get_desc_gs,	1 },
460 		{ "set-desc-gs",NO_ARG,		&set_desc_gs,	1 },
461 		{ "get-desc-tr",NO_ARG,		&get_desc_tr,	1 },
462 		{ "set-desc-tr",NO_ARG,		&set_desc_tr,	1 },
463 		{ "set-desc-ldtr", NO_ARG,	&set_desc_ldtr,	1 },
464 		{ "get-desc-ldtr", NO_ARG,	&get_desc_ldtr,	1 },
465 		{ "set-desc-gdtr", NO_ARG,	&set_desc_gdtr, 1 },
466 		{ "get-desc-gdtr", NO_ARG,	&get_desc_gdtr, 1 },
467 		{ "set-desc-idtr", NO_ARG,	&set_desc_idtr, 1 },
468 		{ "get-desc-idtr", NO_ARG,	&get_desc_idtr, 1 },
469 		{ "get-lowmem", NO_ARG,		&get_lowmem,	1 },
470 		{ "get-highmem",NO_ARG,		&get_highmem,	1 },
471 		{ "get-efer",	NO_ARG,		&get_efer,	1 },
472 		{ "get-cr0",	NO_ARG,		&get_cr0,	1 },
473 		{ "get-cr3",	NO_ARG,		&get_cr3,	1 },
474 		{ "get-cr4",	NO_ARG,		&get_cr4,	1 },
475 		{ "get-dr7",	NO_ARG,		&get_dr7,	1 },
476 		{ "get-rsp",	NO_ARG,		&get_rsp,	1 },
477 		{ "get-rip",	NO_ARG,		&get_rip,	1 },
478 		{ "get-rax",	NO_ARG,		&get_rax,	1 },
479 		{ "get-rbx",	NO_ARG,		&get_rbx,	1 },
480 		{ "get-rcx",	NO_ARG,		&get_rcx,	1 },
481 		{ "get-rdx",	NO_ARG,		&get_rdx,	1 },
482 		{ "get-rsi",	NO_ARG,		&get_rsi,	1 },
483 		{ "get-rdi",	NO_ARG,		&get_rdi,	1 },
484 		{ "get-rbp",	NO_ARG,		&get_rbp,	1 },
485 		{ "get-r8",	NO_ARG,		&get_r8,	1 },
486 		{ "get-r9",	NO_ARG,		&get_r9,	1 },
487 		{ "get-r10",	NO_ARG,		&get_r10,	1 },
488 		{ "get-r11",	NO_ARG,		&get_r11,	1 },
489 		{ "get-r12",	NO_ARG,		&get_r12,	1 },
490 		{ "get-r13",	NO_ARG,		&get_r13,	1 },
491 		{ "get-r14",	NO_ARG,		&get_r14,	1 },
492 		{ "get-r15",	NO_ARG,		&get_r15,	1 },
493 		{ "get-rflags",	NO_ARG,		&get_rflags,	1 },
494 		{ "get-cs",	NO_ARG,		&get_cs,	1 },
495 		{ "get-ds",	NO_ARG,		&get_ds,	1 },
496 		{ "get-es",	NO_ARG,		&get_es,	1 },
497 		{ "get-fs",	NO_ARG,		&get_fs,	1 },
498 		{ "get-gs",	NO_ARG,		&get_gs,	1 },
499 		{ "get-ss",	NO_ARG,		&get_ss,	1 },
500 		{ "get-tr",	NO_ARG,		&get_tr,	1 },
501 		{ "get-ldtr",	NO_ARG,		&get_ldtr,	1 },
502 		{ "get-vmcs-pinbased-ctls",
503 				NO_ARG,		&get_pinbased_ctls, 1 },
504 		{ "get-vmcs-procbased-ctls",
505 				NO_ARG,		&get_procbased_ctls, 1 },
506 		{ "get-vmcs-procbased-ctls2",
507 				NO_ARG,		&get_procbased_ctls2, 1 },
508 		{ "get-vmcs-guest-linear-address",
509 				NO_ARG,		&get_vmcs_gla,	1 },
510 		{ "get-vmcs-guest-physical-address",
511 				NO_ARG,		&get_vmcs_gpa,	1 },
512 		{ "get-vmcs-entry-interruption-info",
513 				NO_ARG, &get_vmcs_entry_interruption_info, 1},
514 		{ "get-vmcs-eptp", NO_ARG,	&get_eptp,	1 },
515 		{ "get-vmcs-exception-bitmap",
516 				NO_ARG,		&get_exception_bitmap, 1 },
517 		{ "get-vmcs-io-bitmap-address",
518 				NO_ARG,		&get_io_bitmap,	1 },
519 		{ "get-vmcs-tsc-offset", NO_ARG,&get_tsc_offset, 1 },
520 		{ "get-vmcs-cr0-mask", NO_ARG,	&get_cr0_mask,	1 },
521 		{ "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 },
522 		{ "get-vmcs-cr4-mask", NO_ARG,	&get_cr4_mask,	1 },
523 		{ "get-vmcs-cr4-shadow", NO_ARG,&get_cr4_shadow, 1 },
524 		{ "get-vmcs-cr3-targets", NO_ARG, &get_cr3_targets, 1},
525 		{ "get-vmcs-apic-access-address",
526 				NO_ARG,		&get_apic_access_addr, 1},
527 		{ "get-vmcs-virtual-apic-address",
528 				NO_ARG,		&get_virtual_apic_addr, 1},
529 		{ "get-vmcs-tpr-threshold",
530 				NO_ARG,		&get_tpr_threshold, 1 },
531 		{ "get-vmcs-msr-bitmap",
532 				NO_ARG,		&get_msr_bitmap, 1 },
533 		{ "get-vmcs-msr-bitmap-address",
534 				NO_ARG,		&get_msr_bitmap_address, 1 },
535 		{ "get-vmcs-vpid", NO_ARG,	&get_vpid,	1 },
536 		{ "get-vmcs-ple-gap", NO_ARG,	&get_ple_gap,	1 },
537 		{ "get-vmcs-ple-window", NO_ARG,&get_ple_window,1 },
538 		{ "get-vmcs-instruction-error",
539 				NO_ARG,		&get_inst_err,	1 },
540 		{ "get-vmcs-exit-ctls", NO_ARG,	&get_exit_ctls,	1 },
541 		{ "get-vmcs-entry-ctls",
542 					NO_ARG,	&get_entry_ctls, 1 },
543 		{ "get-vmcs-guest-pat",	NO_ARG,	&get_guest_pat,	1 },
544 		{ "get-vmcs-host-pat",	NO_ARG,	&get_host_pat,	1 },
545 		{ "get-vmcs-host-cr0",
546 				NO_ARG,		&get_host_cr0,	1 },
547 		{ "get-vmcs-host-cr3",
548 				NO_ARG,		&get_host_cr3,	1 },
549 		{ "get-vmcs-host-cr4",
550 				NO_ARG,		&get_host_cr4,	1 },
551 		{ "get-vmcs-host-rip",
552 				NO_ARG,		&get_host_rip,	1 },
553 		{ "get-vmcs-host-rsp",
554 				NO_ARG,		&get_host_rsp,	1 },
555 		{ "get-vmcs-guest-sysenter",
556 				NO_ARG,		&get_guest_sysenter, 1 },
557 		{ "get-vmcs-link", NO_ARG,	&get_vmcs_link, 1 },
558 		{ "get-vmcs-exit-reason",
559 				NO_ARG,		&get_vmcs_exit_reason, 1 },
560 		{ "get-vmcs-exit-qualification",
561 			NO_ARG,		&get_vmcs_exit_qualification, 1 },
562 		{ "get-vmcs-exit-interruption-info",
563 				NO_ARG,	&get_vmcs_exit_interruption_info, 1},
564 		{ "get-vmcs-exit-interruption-error",
565 				NO_ARG,	&get_vmcs_exit_interruption_error, 1},
566 		{ "get-vmcs-interruptibility",
567 				NO_ARG, &get_vmcs_interruptibility, 1 },
568 		{ "get-x2apic-state",NO_ARG,	&get_x2apic_state, 1 },
569 		{ "get-all",	NO_ARG,		&get_all,	1 },
570 		{ "run",	NO_ARG,		&run,		1 },
571 		{ "create",	NO_ARG,		&create,	1 },
572 		{ "destroy",	NO_ARG,		&destroy,	1 },
573 		{ NULL,		0,		NULL,		0 }
574 	};
575 
576 	vcpu = 0;
577 	progname = basename(argv[0]);
578 
579 	while ((ch = getopt_long(argc, argv, "", opts, NULL)) != -1) {
580 		switch (ch) {
581 		case 0:
582 			break;
583 		case VMNAME:
584 			vmname = optarg;
585 			break;
586 		case VCPU:
587 			vcpu = atoi(optarg);
588 			break;
589 		case SET_MEM:
590 			memsize = atoi(optarg) * MB;
591 			memsize = roundup(memsize, 2 * MB);
592 			break;
593 		case SET_EFER:
594 			efer = strtoul(optarg, NULL, 0);
595 			set_efer = 1;
596 			break;
597 		case SET_CR0:
598 			cr0 = strtoul(optarg, NULL, 0);
599 			set_cr0 = 1;
600 			break;
601 		case SET_CR3:
602 			cr3 = strtoul(optarg, NULL, 0);
603 			set_cr3 = 1;
604 			break;
605 		case SET_CR4:
606 			cr4 = strtoul(optarg, NULL, 0);
607 			set_cr4 = 1;
608 			break;
609 		case SET_DR7:
610 			dr7 = strtoul(optarg, NULL, 0);
611 			set_dr7 = 1;
612 			break;
613 		case SET_RSP:
614 			rsp = strtoul(optarg, NULL, 0);
615 			set_rsp = 1;
616 			break;
617 		case SET_RIP:
618 			rip = strtoul(optarg, NULL, 0);
619 			set_rip = 1;
620 			break;
621 		case SET_RAX:
622 			rax = strtoul(optarg, NULL, 0);
623 			set_rax = 1;
624 			break;
625 		case SET_RFLAGS:
626 			rflags = strtoul(optarg, NULL, 0);
627 			set_rflags = 1;
628 			break;
629 		case DESC_BASE:
630 			desc_base = strtoul(optarg, NULL, 0);
631 			break;
632 		case DESC_LIMIT:
633 			desc_limit = strtoul(optarg, NULL, 0);
634 			break;
635 		case DESC_ACCESS:
636 			desc_access = strtoul(optarg, NULL, 0);
637 			break;
638 		case SET_CS:
639 			cs = strtoul(optarg, NULL, 0);
640 			set_cs = 1;
641 			break;
642 		case SET_DS:
643 			ds = strtoul(optarg, NULL, 0);
644 			set_ds = 1;
645 			break;
646 		case SET_ES:
647 			es = strtoul(optarg, NULL, 0);
648 			set_es = 1;
649 			break;
650 		case SET_FS:
651 			fs = strtoul(optarg, NULL, 0);
652 			set_fs = 1;
653 			break;
654 		case SET_GS:
655 			gs = strtoul(optarg, NULL, 0);
656 			set_gs = 1;
657 			break;
658 		case SET_SS:
659 			ss = strtoul(optarg, NULL, 0);
660 			set_ss = 1;
661 			break;
662 		case SET_TR:
663 			tr = strtoul(optarg, NULL, 0);
664 			set_tr = 1;
665 			break;
666 		case SET_LDTR:
667 			ldtr = strtoul(optarg, NULL, 0);
668 			set_ldtr = 1;
669 			break;
670 		case SET_X2APIC_STATE:
671 			x2apic_state = strtol(optarg, NULL, 0);
672 			set_x2apic_state = 1;
673 			break;
674 		case SET_VMCS_EXCEPTION_BITMAP:
675 			exception_bitmap = strtoul(optarg, NULL, 0);
676 			set_exception_bitmap = 1;
677 			break;
678 		case SET_VMCS_ENTRY_INTERRUPTION_INFO:
679 			vmcs_entry_interruption_info = strtoul(optarg, NULL, 0);
680 			set_vmcs_entry_interruption_info = 1;
681 			break;
682 		case SET_CAP:
683 			capval = strtoul(optarg, NULL, 0);
684 			setcap = 1;
685 			break;
686 		case CAPNAME:
687 			capname = optarg;
688 			break;
689 		case UNASSIGN_PPTDEV:
690 			unassign_pptdev = 1;
691 			if (sscanf(optarg, "%d/%d/%d", &bus, &slot, &func) != 3)
692 				usage();
693 			break;
694 		default:
695 			usage();
696 		}
697 	}
698 	argc -= optind;
699 	argv += optind;
700 
701 	if (vmname == NULL)
702 		usage();
703 
704 	error = 0;
705 
706 	if (!error && create)
707 		error = vm_create(vmname);
708 
709 	if (!error) {
710 		ctx = vm_open(vmname);
711 		if (ctx == NULL)
712 			error = -1;
713 	}
714 
715 	if (!error && memsize)
716 		error = vm_setup_memory(ctx, memsize, VM_MMAP_NONE);
717 
718 	if (!error && set_efer)
719 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_EFER, efer);
720 
721 	if (!error && set_cr0)
722 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR0, cr0);
723 
724 	if (!error && set_cr3)
725 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR3, cr3);
726 
727 	if (!error && set_cr4)
728 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR4, cr4);
729 
730 	if (!error && set_dr7)
731 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR7, dr7);
732 
733 	if (!error && set_rsp)
734 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RSP, rsp);
735 
736 	if (!error && set_rip)
737 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, rip);
738 
739 	if (!error && set_rax)
740 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, rax);
741 
742 	if (!error && set_rflags) {
743 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RFLAGS,
744 					rflags);
745 	}
746 
747 	if (!error && set_desc_ds) {
748 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_DS,
749 				    desc_base, desc_limit, desc_access);
750 	}
751 
752 	if (!error && set_desc_es) {
753 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_ES,
754 				    desc_base, desc_limit, desc_access);
755 	}
756 
757 	if (!error && set_desc_ss) {
758 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_SS,
759 				    desc_base, desc_limit, desc_access);
760 	}
761 
762 	if (!error && set_desc_cs) {
763 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_CS,
764 				    desc_base, desc_limit, desc_access);
765 	}
766 
767 	if (!error && set_desc_fs) {
768 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_FS,
769 				    desc_base, desc_limit, desc_access);
770 	}
771 
772 	if (!error && set_desc_gs) {
773 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GS,
774 				    desc_base, desc_limit, desc_access);
775 	}
776 
777 	if (!error && set_desc_tr) {
778 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_TR,
779 				    desc_base, desc_limit, desc_access);
780 	}
781 
782 	if (!error && set_desc_ldtr) {
783 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_LDTR,
784 				    desc_base, desc_limit, desc_access);
785 	}
786 
787 	if (!error && set_desc_gdtr) {
788 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GDTR,
789 				    desc_base, desc_limit, 0);
790 	}
791 
792 	if (!error && set_desc_idtr) {
793 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_IDTR,
794 				    desc_base, desc_limit, 0);
795 	}
796 
797 	if (!error && set_cs)
798 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CS, cs);
799 
800 	if (!error && set_ds)
801 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DS, ds);
802 
803 	if (!error && set_es)
804 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_ES, es);
805 
806 	if (!error && set_fs)
807 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_FS, fs);
808 
809 	if (!error && set_gs)
810 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_GS, gs);
811 
812 	if (!error && set_ss)
813 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_SS, ss);
814 
815 	if (!error && set_tr)
816 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_TR, tr);
817 
818 	if (!error && set_ldtr)
819 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_LDTR, ldtr);
820 
821 	if (!error && set_x2apic_state)
822 		error = vm_set_x2apic_state(ctx, vcpu, x2apic_state);
823 
824 #ifdef	__FreeBSD__
825 	if (!error && unassign_pptdev)
826 		error = vm_unassign_pptdev(ctx, bus, slot, func);
827 #endif
828 
829 	if (!error && set_exception_bitmap) {
830 		error = vm_set_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP,
831 					  exception_bitmap);
832 	}
833 
834 	if (!error && set_vmcs_entry_interruption_info) {
835 		error = vm_set_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,
836 					  vmcs_entry_interruption_info);
837 	}
838 
839 	if (!error && (get_lowmem || get_all)) {
840 		gpa = 0;
841 		error = vm_get_memory_seg(ctx, gpa, &len, &wired);
842 		if (error == 0)
843 			printf("lowmem\t\t0x%016lx/%ld%s\n", gpa, len,
844 			    wired ? " wired" : "");
845 	}
846 
847 	if (!error && (get_highmem || get_all)) {
848 		gpa = 4 * GB;
849 		error = vm_get_memory_seg(ctx, gpa, &len, &wired);
850 		if (error == 0)
851 			printf("highmem\t\t0x%016lx/%ld%s\n", gpa, len,
852 			    wired ? " wired" : "");
853 	}
854 
855 	if (!error && (get_efer || get_all)) {
856 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_EFER, &efer);
857 		if (error == 0)
858 			printf("efer[%d]\t\t0x%016lx\n", vcpu, efer);
859 	}
860 
861 	if (!error && (get_cr0 || get_all)) {
862 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR0, &cr0);
863 		if (error == 0)
864 			printf("cr0[%d]\t\t0x%016lx\n", vcpu, cr0);
865 	}
866 
867 	if (!error && (get_cr3 || get_all)) {
868 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR3, &cr3);
869 		if (error == 0)
870 			printf("cr3[%d]\t\t0x%016lx\n", vcpu, cr3);
871 	}
872 
873 	if (!error && (get_cr4 || get_all)) {
874 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR4, &cr4);
875 		if (error == 0)
876 			printf("cr4[%d]\t\t0x%016lx\n", vcpu, cr4);
877 	}
878 
879 	if (!error && (get_dr7 || get_all)) {
880 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR7, &dr7);
881 		if (error == 0)
882 			printf("dr7[%d]\t\t0x%016lx\n", vcpu, dr7);
883 	}
884 
885 	if (!error && (get_rsp || get_all)) {
886 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSP, &rsp);
887 		if (error == 0)
888 			printf("rsp[%d]\t\t0x%016lx\n", vcpu, rsp);
889 	}
890 
891 	if (!error && (get_rip || get_all)) {
892 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip);
893 		if (error == 0)
894 			printf("rip[%d]\t\t0x%016lx\n", vcpu, rip);
895 	}
896 
897 	if (!error && (get_rax || get_all)) {
898 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &rax);
899 		if (error == 0)
900 			printf("rax[%d]\t\t0x%016lx\n", vcpu, rax);
901 	}
902 
903 	if (!error && (get_rbx || get_all)) {
904 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBX, &rbx);
905 		if (error == 0)
906 			printf("rbx[%d]\t\t0x%016lx\n", vcpu, rbx);
907 	}
908 
909 	if (!error && (get_rcx || get_all)) {
910 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RCX, &rcx);
911 		if (error == 0)
912 			printf("rcx[%d]\t\t0x%016lx\n", vcpu, rcx);
913 	}
914 
915 	if (!error && (get_rdx || get_all)) {
916 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDX, &rdx);
917 		if (error == 0)
918 			printf("rdx[%d]\t\t0x%016lx\n", vcpu, rdx);
919 	}
920 
921 	if (!error && (get_rsi || get_all)) {
922 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSI, &rsi);
923 		if (error == 0)
924 			printf("rsi[%d]\t\t0x%016lx\n", vcpu, rsi);
925 	}
926 
927 	if (!error && (get_rdi || get_all)) {
928 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDI, &rdi);
929 		if (error == 0)
930 			printf("rdi[%d]\t\t0x%016lx\n", vcpu, rdi);
931 	}
932 
933 	if (!error && (get_rbp || get_all)) {
934 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBP, &rbp);
935 		if (error == 0)
936 			printf("rbp[%d]\t\t0x%016lx\n", vcpu, rbp);
937 	}
938 
939 	if (!error && (get_r8 || get_all)) {
940 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R8, &r8);
941 		if (error == 0)
942 			printf("r8[%d]\t\t0x%016lx\n", vcpu, r8);
943 	}
944 
945 	if (!error && (get_r9 || get_all)) {
946 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R9, &r9);
947 		if (error == 0)
948 			printf("r9[%d]\t\t0x%016lx\n", vcpu, r9);
949 	}
950 
951 	if (!error && (get_r10 || get_all)) {
952 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R10, &r10);
953 		if (error == 0)
954 			printf("r10[%d]\t\t0x%016lx\n", vcpu, r10);
955 	}
956 
957 	if (!error && (get_r11 || get_all)) {
958 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R11, &r11);
959 		if (error == 0)
960 			printf("r11[%d]\t\t0x%016lx\n", vcpu, r11);
961 	}
962 
963 	if (!error && (get_r12 || get_all)) {
964 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R12, &r12);
965 		if (error == 0)
966 			printf("r12[%d]\t\t0x%016lx\n", vcpu, r12);
967 	}
968 
969 	if (!error && (get_r13 || get_all)) {
970 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R13, &r13);
971 		if (error == 0)
972 			printf("r13[%d]\t\t0x%016lx\n", vcpu, r13);
973 	}
974 
975 	if (!error && (get_r14 || get_all)) {
976 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R14, &r14);
977 		if (error == 0)
978 			printf("r14[%d]\t\t0x%016lx\n", vcpu, r14);
979 	}
980 
981 	if (!error && (get_r15 || get_all)) {
982 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R15, &r15);
983 		if (error == 0)
984 			printf("r15[%d]\t\t0x%016lx\n", vcpu, r15);
985 	}
986 
987 	if (!error && (get_rflags || get_all)) {
988 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RFLAGS,
989 					&rflags);
990 		if (error == 0)
991 			printf("rflags[%d]\t0x%016lx\n", vcpu, rflags);
992 	}
993 
994 #ifdef	__FreeBSD__
995 	if (!error && (get_stats || get_all)) {
996 		int i, num_stats;
997 		uint64_t *stats;
998 		struct timeval tv;
999 		const char *desc;
1000 
1001 		stats = vm_get_stats(ctx, vcpu, &tv, &num_stats);
1002 		if (stats != NULL) {
1003 			printf("vcpu%d\n", vcpu);
1004 			for (i = 0; i < num_stats; i++) {
1005 				desc = vm_get_stat_desc(ctx, i);
1006 				printf("%-40s\t%ld\n", desc, stats[i]);
1007 			}
1008 		}
1009 	}
1010 #endif
1011 
1012 	if (!error && (get_desc_ds || get_all)) {
1013 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_DS,
1014 				    &desc_base, &desc_limit, &desc_access);
1015 		if (error == 0) {
1016 			printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1017 			       vcpu, desc_base, desc_limit, desc_access);
1018 		}
1019 	}
1020 
1021 	if (!error && (get_desc_es || get_all)) {
1022 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_ES,
1023 				    &desc_base, &desc_limit, &desc_access);
1024 		if (error == 0) {
1025 			printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1026 			       vcpu, desc_base, desc_limit, desc_access);
1027 		}
1028 	}
1029 
1030 	if (!error && (get_desc_fs || get_all)) {
1031 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_FS,
1032 				    &desc_base, &desc_limit, &desc_access);
1033 		if (error == 0) {
1034 			printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1035 			       vcpu, desc_base, desc_limit, desc_access);
1036 		}
1037 	}
1038 
1039 	if (!error && (get_desc_gs || get_all)) {
1040 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GS,
1041 				    &desc_base, &desc_limit, &desc_access);
1042 		if (error == 0) {
1043 			printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1044 			       vcpu, desc_base, desc_limit, desc_access);
1045 		}
1046 	}
1047 
1048 	if (!error && (get_desc_ss || get_all)) {
1049 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_SS,
1050 				    &desc_base, &desc_limit, &desc_access);
1051 		if (error == 0) {
1052 			printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1053 			       vcpu, desc_base, desc_limit, desc_access);
1054 		}
1055 	}
1056 
1057 	if (!error && (get_desc_cs || get_all)) {
1058 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_CS,
1059 				    &desc_base, &desc_limit, &desc_access);
1060 		if (error == 0) {
1061 			printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1062 			       vcpu, desc_base, desc_limit, desc_access);
1063 		}
1064 	}
1065 
1066 	if (!error && (get_desc_tr || get_all)) {
1067 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_TR,
1068 				    &desc_base, &desc_limit, &desc_access);
1069 		if (error == 0) {
1070 			printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1071 			       vcpu, desc_base, desc_limit, desc_access);
1072 		}
1073 	}
1074 
1075 	if (!error && (get_desc_ldtr || get_all)) {
1076 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_LDTR,
1077 				    &desc_base, &desc_limit, &desc_access);
1078 		if (error == 0) {
1079 			printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1080 			       vcpu, desc_base, desc_limit, desc_access);
1081 		}
1082 	}
1083 
1084 	if (!error && (get_desc_gdtr || get_all)) {
1085 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GDTR,
1086 				    &desc_base, &desc_limit, &desc_access);
1087 		if (error == 0) {
1088 			printf("gdtr[%d]\t\t0x%016lx/0x%08x\n",
1089 			       vcpu, desc_base, desc_limit);
1090 		}
1091 	}
1092 
1093 	if (!error && (get_desc_idtr || get_all)) {
1094 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_IDTR,
1095 				    &desc_base, &desc_limit, &desc_access);
1096 		if (error == 0) {
1097 			printf("idtr[%d]\t\t0x%016lx/0x%08x\n",
1098 			       vcpu, desc_base, desc_limit);
1099 		}
1100 	}
1101 
1102 	if (!error && (get_cs || get_all)) {
1103 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CS, &cs);
1104 		if (error == 0)
1105 			printf("cs[%d]\t\t0x%04lx\n", vcpu, cs);
1106 	}
1107 
1108 	if (!error && (get_ds || get_all)) {
1109 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DS, &ds);
1110 		if (error == 0)
1111 			printf("ds[%d]\t\t0x%04lx\n", vcpu, ds);
1112 	}
1113 
1114 	if (!error && (get_es || get_all)) {
1115 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_ES, &es);
1116 		if (error == 0)
1117 			printf("es[%d]\t\t0x%04lx\n", vcpu, es);
1118 	}
1119 
1120 	if (!error && (get_fs || get_all)) {
1121 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_FS, &fs);
1122 		if (error == 0)
1123 			printf("fs[%d]\t\t0x%04lx\n", vcpu, fs);
1124 	}
1125 
1126 	if (!error && (get_gs || get_all)) {
1127 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_GS, &gs);
1128 		if (error == 0)
1129 			printf("gs[%d]\t\t0x%04lx\n", vcpu, gs);
1130 	}
1131 
1132 	if (!error && (get_ss || get_all)) {
1133 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_SS, &ss);
1134 		if (error == 0)
1135 			printf("ss[%d]\t\t0x%04lx\n", vcpu, ss);
1136 	}
1137 
1138 	if (!error && (get_tr || get_all)) {
1139 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_TR, &tr);
1140 		if (error == 0)
1141 			printf("tr[%d]\t\t0x%04lx\n", vcpu, tr);
1142 	}
1143 
1144 	if (!error && (get_ldtr || get_all)) {
1145 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_LDTR, &ldtr);
1146 		if (error == 0)
1147 			printf("ldtr[%d]\t\t0x%04lx\n", vcpu, ldtr);
1148 	}
1149 
1150 	if (!error && (get_x2apic_state || get_all)) {
1151 		error = vm_get_x2apic_state(ctx, vcpu, &x2apic_state);
1152 		if (error == 0)
1153 			printf("x2apic_state[%d]\t%d\n", vcpu, x2apic_state);
1154 	}
1155 
1156 	if (!error && (get_pinbased_ctls || get_all)) {
1157 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_PIN_BASED_CTLS, &ctl);
1158 		if (error == 0)
1159 			printf("pinbased_ctls[%d]\t0x%08lx\n", vcpu, ctl);
1160 	}
1161 
1162 	if (!error && (get_procbased_ctls || get_all)) {
1163 		error = vm_get_vmcs_field(ctx, vcpu,
1164 					  VMCS_PRI_PROC_BASED_CTLS, &ctl);
1165 		if (error == 0)
1166 			printf("procbased_ctls[%d]\t0x%08lx\n", vcpu, ctl);
1167 	}
1168 
1169 	if (!error && (get_procbased_ctls2 || get_all)) {
1170 		error = vm_get_vmcs_field(ctx, vcpu,
1171 					  VMCS_SEC_PROC_BASED_CTLS, &ctl);
1172 		if (error == 0)
1173 			printf("procbased_ctls2[%d]\t0x%08lx\n", vcpu, ctl);
1174 	}
1175 
1176 	if (!error && (get_vmcs_gla || get_all)) {
1177 		error = vm_get_vmcs_field(ctx, vcpu,
1178 					  VMCS_GUEST_LINEAR_ADDRESS, &u64);
1179 		if (error == 0)
1180 			printf("gla[%d]\t\t0x%016lx\n", vcpu, u64);
1181 	}
1182 
1183 	if (!error && (get_vmcs_gpa || get_all)) {
1184 		error = vm_get_vmcs_field(ctx, vcpu,
1185 					  VMCS_GUEST_PHYSICAL_ADDRESS, &u64);
1186 		if (error == 0)
1187 			printf("gpa[%d]\t\t0x%016lx\n", vcpu, u64);
1188 	}
1189 
1190 	if (!error && (get_vmcs_entry_interruption_info || get_all)) {
1191 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,&u64);
1192 		if (error == 0) {
1193 			printf("entry_interruption_info[%d]\t0x%08lx\n",
1194 				vcpu, u64);
1195 		}
1196 	}
1197 
1198 	if (!error && (get_eptp || get_all)) {
1199 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EPTP, &eptp);
1200 		if (error == 0)
1201 			printf("eptp[%d]\t\t0x%016lx\n", vcpu, eptp);
1202 	}
1203 
1204 	if (!error && (get_exception_bitmap || get_all)) {
1205 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP,
1206 					  &bm);
1207 		if (error == 0)
1208 			printf("exception_bitmap[%d]\t0x%08lx\n", vcpu, bm);
1209 	}
1210 
1211 	if (!error && (get_io_bitmap || get_all)) {
1212 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_A, &bm);
1213 		if (error == 0)
1214 			printf("io_bitmap_a[%d]\t0x%08lx\n", vcpu, bm);
1215 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_B, &bm);
1216 		if (error == 0)
1217 			printf("io_bitmap_b[%d]\t0x%08lx\n", vcpu, bm);
1218 	}
1219 
1220 	if (!error && (get_tsc_offset || get_all)) {
1221 		uint64_t tscoff;
1222 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_TSC_OFFSET, &tscoff);
1223 		if (error == 0)
1224 			printf("tsc_offset[%d]\t0x%016lx\n", vcpu, tscoff);
1225 	}
1226 
1227 	if (!error && (get_cr0_mask || get_all)) {
1228 		uint64_t cr0mask;
1229 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_MASK, &cr0mask);
1230 		if (error == 0)
1231 			printf("cr0_mask[%d]\t\t0x%016lx\n", vcpu, cr0mask);
1232 	}
1233 
1234 	if (!error && (get_cr0_shadow || get_all)) {
1235 		uint64_t cr0shadow;
1236 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_SHADOW,
1237 					  &cr0shadow);
1238 		if (error == 0)
1239 			printf("cr0_shadow[%d]\t\t0x%016lx\n", vcpu, cr0shadow);
1240 	}
1241 
1242 	if (!error && (get_cr4_mask || get_all)) {
1243 		uint64_t cr4mask;
1244 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_MASK, &cr4mask);
1245 		if (error == 0)
1246 			printf("cr4_mask[%d]\t\t0x%016lx\n", vcpu, cr4mask);
1247 	}
1248 
1249 	if (!error && (get_cr4_shadow || get_all)) {
1250 		uint64_t cr4shadow;
1251 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_SHADOW,
1252 					  &cr4shadow);
1253 		if (error == 0)
1254 			printf("cr4_shadow[%d]\t\t0x%016lx\n", vcpu, cr4shadow);
1255 	}
1256 
1257 	if (!error && (get_cr3_targets || get_all)) {
1258 		uint64_t target_count, target_addr;
1259 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET_COUNT,
1260 					  &target_count);
1261 		if (error == 0) {
1262 			printf("cr3_target_count[%d]\t0x%08lx\n",
1263 				vcpu, target_count);
1264 		}
1265 
1266 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET0,
1267 					  &target_addr);
1268 		if (error == 0) {
1269 			printf("cr3_target0[%d]\t\t0x%016lx\n",
1270 				vcpu, target_addr);
1271 		}
1272 
1273 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET1,
1274 					  &target_addr);
1275 		if (error == 0) {
1276 			printf("cr3_target1[%d]\t\t0x%016lx\n",
1277 				vcpu, target_addr);
1278 		}
1279 
1280 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET2,
1281 					  &target_addr);
1282 		if (error == 0) {
1283 			printf("cr3_target2[%d]\t\t0x%016lx\n",
1284 				vcpu, target_addr);
1285 		}
1286 
1287 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET3,
1288 					  &target_addr);
1289 		if (error == 0) {
1290 			printf("cr3_target3[%d]\t\t0x%016lx\n",
1291 				vcpu, target_addr);
1292 		}
1293 	}
1294 
1295 	if (!error && (get_apic_access_addr || get_all)) {
1296 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_APIC_ACCESS, &addr);
1297 		if (error == 0)
1298 			printf("apic_access_addr[%d]\t0x%016lx\n", vcpu, addr);
1299 	}
1300 
1301 	if (!error && (get_virtual_apic_addr || get_all)) {
1302 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_VIRTUAL_APIC, &addr);
1303 		if (error == 0)
1304 			printf("virtual_apic_addr[%d]\t0x%016lx\n", vcpu, addr);
1305 	}
1306 
1307 	if (!error && (get_tpr_threshold || get_all)) {
1308 		uint64_t threshold;
1309 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_TPR_THRESHOLD,
1310 					  &threshold);
1311 		if (error == 0)
1312 			printf("tpr_threshold[%d]\t0x%08lx\n", vcpu, threshold);
1313 	}
1314 
1315 	if (!error && (get_msr_bitmap_address || get_all)) {
1316 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, &addr);
1317 		if (error == 0)
1318 			printf("msr_bitmap[%d]\t\t0x%016lx\n", vcpu, addr);
1319 	}
1320 
1321 	if (!error && (get_msr_bitmap || get_all)) {
1322 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, &addr);
1323 		if (error == 0)
1324 			error = dump_vmcs_msr_bitmap(vcpu, addr);
1325 	}
1326 
1327 	if (!error && (get_vpid || get_all)) {
1328 		uint64_t vpid;
1329 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_VPID, &vpid);
1330 		if (error == 0)
1331 			printf("vpid[%d]\t\t0x%04lx\n", vcpu, vpid);
1332 	}
1333 
1334 	if (!error && (get_ple_window || get_all)) {
1335 		uint64_t window;
1336 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_PLE_WINDOW, &window);
1337 		if (error == 0)
1338 			printf("ple_window[%d]\t\t0x%08lx\n", vcpu, window);
1339 	}
1340 
1341 	if (!error && (get_ple_gap || get_all)) {
1342 		uint64_t gap;
1343 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_PLE_GAP, &gap);
1344 		if (error == 0)
1345 			printf("ple_gap[%d]\t\t0x%08lx\n", vcpu, gap);
1346 	}
1347 
1348 	if (!error && (get_inst_err || get_all)) {
1349 		uint64_t insterr;
1350 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_INSTRUCTION_ERROR,
1351 					  &insterr);
1352 		if (error == 0) {
1353 			printf("instruction_error[%d]\t0x%08lx\n",
1354 				vcpu, insterr);
1355 		}
1356 	}
1357 
1358 	if (!error && (get_exit_ctls || get_all)) {
1359 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_CTLS, &ctl);
1360 		if (error == 0)
1361 			printf("exit_ctls[%d]\t\t0x%08lx\n", vcpu, ctl);
1362 	}
1363 
1364 	if (!error && (get_entry_ctls || get_all)) {
1365 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_CTLS, &ctl);
1366 		if (error == 0)
1367 			printf("entry_ctls[%d]\t\t0x%08lx\n", vcpu, ctl);
1368 	}
1369 
1370 	if (!error && (get_host_pat || get_all)) {
1371 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_IA32_PAT, &pat);
1372 		if (error == 0)
1373 			printf("host_pat[%d]\t\t0x%016lx\n", vcpu, pat);
1374 	}
1375 
1376 	if (!error && (get_guest_pat || get_all)) {
1377 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_IA32_PAT, &pat);
1378 		if (error == 0)
1379 			printf("guest_pat[%d]\t\t0x%016lx\n", vcpu, pat);
1380 	}
1381 
1382 	if (!error && (get_host_cr0 || get_all)) {
1383 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR0, &cr0);
1384 		if (error == 0)
1385 			printf("host_cr0[%d]\t\t0x%016lx\n", vcpu, cr0);
1386 	}
1387 
1388 	if (!error && (get_host_cr3 || get_all)) {
1389 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR3, &cr3);
1390 		if (error == 0)
1391 			printf("host_cr3[%d]\t\t0x%016lx\n", vcpu, cr3);
1392 	}
1393 
1394 	if (!error && (get_host_cr4 || get_all)) {
1395 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR4, &cr4);
1396 		if (error == 0)
1397 			printf("host_cr4[%d]\t\t0x%016lx\n", vcpu, cr4);
1398 	}
1399 
1400 	if (!error && (get_host_rip || get_all)) {
1401 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RIP, &rip);
1402 		if (error == 0)
1403 			printf("host_rip[%d]\t\t0x%016lx\n", vcpu, rip);
1404 	}
1405 
1406 	if (!error && (get_host_rsp || get_all)) {
1407 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RSP, &rsp);
1408 		if (error == 0)
1409 			printf("host_rsp[%d]\t\t0x%016lx\n", vcpu, rsp);
1410 	}
1411 
1412 	if (!error && (get_guest_sysenter || get_all)) {
1413 		error = vm_get_vmcs_field(ctx, vcpu,
1414 					  VMCS_GUEST_IA32_SYSENTER_CS, &cs);
1415 		if (error == 0)
1416 			printf("guest_sysenter_cs[%d]\t0x%08lx\n", vcpu, cs);
1417 
1418 		error = vm_get_vmcs_field(ctx, vcpu,
1419 					  VMCS_GUEST_IA32_SYSENTER_ESP, &rsp);
1420 		if (error == 0)
1421 			printf("guest_sysenter_sp[%d]\t0x%016lx\n", vcpu, rsp);
1422 		error = vm_get_vmcs_field(ctx, vcpu,
1423 					  VMCS_GUEST_IA32_SYSENTER_EIP, &rip);
1424 		if (error == 0)
1425 			printf("guest_sysenter_ip[%d]\t0x%016lx\n", vcpu, rip);
1426 	}
1427 
1428 	if (!error && (get_vmcs_link || get_all)) {
1429 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_LINK_POINTER, &addr);
1430 		if (error == 0)
1431 			printf("vmcs_pointer[%d]\t0x%016lx\n", vcpu, addr);
1432 	}
1433 
1434 	if (!error && (get_vmcs_exit_reason || get_all)) {
1435 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_REASON, &u64);
1436 		if (error == 0)
1437 			printf("vmcs_exit_reason[%d]\t0x%016lx\n", vcpu, u64);
1438 	}
1439 
1440 	if (!error && (get_vmcs_exit_qualification || get_all)) {
1441 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_QUALIFICATION,
1442 					  &u64);
1443 		if (error == 0)
1444 			printf("vmcs_exit_qualification[%d]\t0x%016lx\n",
1445 				vcpu, u64);
1446 	}
1447 
1448 	if (!error && (get_vmcs_exit_interruption_info || get_all)) {
1449 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_INFO, &u64);
1450 		if (error == 0) {
1451 			printf("vmcs_exit_interruption_info[%d]\t0x%08lx\n",
1452 				vcpu, u64);
1453 		}
1454 	}
1455 
1456 	if (!error && (get_vmcs_exit_interruption_error || get_all)) {
1457 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_ERRCODE,
1458 		    &u64);
1459 		if (error == 0) {
1460 			printf("vmcs_exit_interruption_error[%d]\t0x%08lx\n",
1461 				vcpu, u64);
1462 		}
1463 	}
1464 
1465 	if (!error && (get_vmcs_interruptibility || get_all)) {
1466 		error = vm_get_vmcs_field(ctx, vcpu,
1467 					  VMCS_GUEST_INTERRUPTIBILITY, &u64);
1468 		if (error == 0) {
1469 			printf("vmcs_guest_interruptibility[%d]\t0x%08lx\n",
1470 				vcpu, u64);
1471 		}
1472 	}
1473 
1474 	if (!error && setcap) {
1475 		int captype;
1476 		captype = vm_capability_name2type(capname);
1477 		error = vm_set_capability(ctx, vcpu, captype, capval);
1478 		if (error != 0 && errno == ENOENT)
1479 			printf("Capability \"%s\" is not available\n", capname);
1480 	}
1481 
1482 	if (!error && (getcap || get_all)) {
1483 		int captype, val, getcaptype;
1484 
1485 		if (getcap && capname)
1486 			getcaptype = vm_capability_name2type(capname);
1487 		else
1488 			getcaptype = -1;
1489 
1490 		for (captype = 0; captype < VM_CAP_MAX; captype++) {
1491 			if (getcaptype >= 0 && captype != getcaptype)
1492 				continue;
1493 			error = vm_get_capability(ctx, vcpu, captype, &val);
1494 			if (error == 0) {
1495 				printf("Capability \"%s\" is %s on vcpu %d\n",
1496 					vm_capability_type2name(captype),
1497 					val ? "set" : "not set", vcpu);
1498 			} else if (errno == ENOENT) {
1499 				error = 0;
1500 				printf("Capability \"%s\" is not available\n",
1501 					vm_capability_type2name(captype));
1502 			} else {
1503 				break;
1504 			}
1505 		}
1506 	}
1507 
1508 	if (!error && run) {
1509 		error = vm_run(ctx, vcpu, &vmexit);
1510 		if (error == 0)
1511 			dump_vm_run_exitcode(&vmexit, vcpu);
1512 		else
1513 			printf("vm_run error %d\n", error);
1514 	}
1515 
1516 	if (error)
1517 		printf("errno = %d\n", errno);
1518 
1519 	if (!error && destroy)
1520 		error = vm_destroy(ctx);
1521 
1522 	exit(error);
1523 }
1524