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