bhyvectl.c revision 276403
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: stable/10/usr.sbin/bhyvectl/bhyvectl.c 276403 2014-12-30 08:24:14Z neel $
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyvectl/bhyvectl.c 276403 2014-12-30 08:24:14Z neel $");
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 <stdbool.h>
41#include <string.h>
42#include <unistd.h>
43#include <libgen.h>
44#include <libutil.h>
45#include <fcntl.h>
46#include <string.h>
47#include <getopt.h>
48#include <assert.h>
49
50#include <machine/cpufunc.h>
51#include <machine/vmm.h>
52#include <machine/specialreg.h>
53#include <vmmapi.h>
54
55#include "amd/vmcb.h"
56#include "intel/vmcs.h"
57
58#define	MB	(1UL << 20)
59#define	GB	(1UL << 30)
60
61#define	REQ_ARG		required_argument
62#define	NO_ARG		no_argument
63#define	OPT_ARG		optional_argument
64
65static const char *progname;
66
67static void
68usage(bool cpu_intel)
69{
70
71	(void)fprintf(stderr,
72	"Usage: %s --vm=<vmname>\n"
73	"       [--cpu=<vcpu_number>]\n"
74	"       [--create]\n"
75	"       [--destroy]\n"
76	"       [--get-all]\n"
77	"       [--get-stats]\n"
78	"       [--set-desc-ds]\n"
79	"       [--get-desc-ds]\n"
80	"       [--set-desc-es]\n"
81	"       [--get-desc-es]\n"
82	"       [--set-desc-gs]\n"
83	"       [--get-desc-gs]\n"
84	"       [--set-desc-fs]\n"
85	"       [--get-desc-fs]\n"
86	"       [--set-desc-cs]\n"
87	"       [--get-desc-cs]\n"
88	"       [--set-desc-ss]\n"
89	"       [--get-desc-ss]\n"
90	"       [--set-desc-tr]\n"
91	"       [--get-desc-tr]\n"
92	"       [--set-desc-ldtr]\n"
93	"       [--get-desc-ldtr]\n"
94	"       [--set-desc-gdtr]\n"
95	"       [--get-desc-gdtr]\n"
96	"       [--set-desc-idtr]\n"
97	"       [--get-desc-idtr]\n"
98	"       [--run]\n"
99	"       [--capname=<capname>]\n"
100	"       [--getcap]\n"
101	"       [--setcap=<0|1>]\n"
102	"       [--desc-base=<BASE>]\n"
103	"       [--desc-limit=<LIMIT>]\n"
104	"       [--desc-access=<ACCESS>]\n"
105	"       [--set-cr0=<CR0>]\n"
106	"       [--get-cr0]\n"
107	"       [--set-cr3=<CR3>]\n"
108	"       [--get-cr3]\n"
109	"       [--set-cr4=<CR4>]\n"
110	"       [--get-cr4]\n"
111	"       [--set-dr7=<DR7>]\n"
112	"       [--get-dr7]\n"
113	"       [--set-rsp=<RSP>]\n"
114	"       [--get-rsp]\n"
115	"       [--set-rip=<RIP>]\n"
116	"       [--get-rip]\n"
117	"       [--get-rax]\n"
118	"       [--set-rax=<RAX>]\n"
119	"       [--get-rbx]\n"
120	"       [--get-rcx]\n"
121	"       [--get-rdx]\n"
122	"       [--get-rsi]\n"
123	"       [--get-rdi]\n"
124	"       [--get-rbp]\n"
125	"       [--get-r8]\n"
126	"       [--get-r9]\n"
127	"       [--get-r10]\n"
128	"       [--get-r11]\n"
129	"       [--get-r12]\n"
130	"       [--get-r13]\n"
131	"       [--get-r14]\n"
132	"       [--get-r15]\n"
133	"       [--set-rflags=<RFLAGS>]\n"
134	"       [--get-rflags]\n"
135	"       [--set-cs]\n"
136	"       [--get-cs]\n"
137	"       [--set-ds]\n"
138	"       [--get-ds]\n"
139	"       [--set-es]\n"
140	"       [--get-es]\n"
141	"       [--set-fs]\n"
142	"       [--get-fs]\n"
143	"       [--set-gs]\n"
144	"       [--get-gs]\n"
145	"       [--set-ss]\n"
146	"       [--get-ss]\n"
147	"       [--get-tr]\n"
148	"       [--get-ldtr]\n"
149	"       [--set-x2apic-state=<state>]\n"
150	"       [--get-x2apic-state]\n"
151	"       [--unassign-pptdev=<bus/slot/func>]\n"
152	"       [--set-mem=<memory in units of MB>]\n"
153	"       [--get-lowmem]\n"
154	"       [--get-highmem]\n"
155	"       [--get-gpa-pmap]\n"
156	"       [--assert-lapic-lvt=<pin>]\n"
157	"       [--inject-nmi]\n"
158	"       [--force-reset]\n"
159	"       [--force-poweroff]\n"
160	"       [--get-active-cpus]\n"
161	"       [--get-suspended-cpus]\n"
162	"       [--get-intinfo]\n"
163	"       [--get-eptp]\n"
164	"       [--set-exception-bitmap]\n"
165	"       [--get-exception-bitmap]\n"
166	"       [--get-tsc-offset]\n"
167	"       [--get-guest-pat]\n"
168	"       [--get-io-bitmap-address]\n"
169	"       [--get-msr-bitmap]\n"
170	"       [--get-msr-bitmap-address]\n"
171	"       [--get-guest-sysenter]\n"
172	"       [--get-exit-reason]\n",
173	progname);
174
175	if (cpu_intel) {
176		(void)fprintf(stderr,
177		"       [--get-vmcs-pinbased-ctls]\n"
178		"       [--get-vmcs-procbased-ctls]\n"
179		"       [--get-vmcs-procbased-ctls2]\n"
180		"       [--get-vmcs-entry-interruption-info]\n"
181		"       [--set-vmcs-entry-interruption-info=<info>]\n"
182		"       [--get-vmcs-guest-physical-address\n"
183		"       [--get-vmcs-guest-linear-address\n"
184		"       [--get-vmcs-host-pat]\n"
185		"       [--get-vmcs-host-cr0]\n"
186		"       [--get-vmcs-host-cr3]\n"
187		"       [--get-vmcs-host-cr4]\n"
188		"       [--get-vmcs-host-rip]\n"
189		"       [--get-vmcs-host-rsp]\n"
190		"       [--get-vmcs-cr0-mask]\n"
191		"       [--get-vmcs-cr0-shadow]\n"
192		"       [--get-vmcs-cr4-mask]\n"
193		"       [--get-vmcs-cr4-shadow]\n"
194		"       [--get-vmcs-cr3-targets]\n"
195		"       [--get-vmcs-apic-access-address]\n"
196		"       [--get-vmcs-virtual-apic-address]\n"
197		"       [--get-vmcs-tpr-threshold]\n"
198		"       [--get-vmcs-vpid]\n"
199		"       [--get-vmcs-instruction-error]\n"
200		"       [--get-vmcs-exit-ctls]\n"
201		"       [--get-vmcs-entry-ctls]\n"
202		"       [--get-vmcs-link]\n"
203		"       [--get-vmcs-exit-qualification]\n"
204		"       [--get-vmcs-exit-interruption-info]\n"
205		"       [--get-vmcs-exit-interruption-error]\n"
206		"       [--get-vmcs-interruptibility]\n"
207		);
208	} else {
209		(void)fprintf(stderr,
210		"       [--get-vmcb-intercepts]\n"
211		"       [--get-vmcb-asid]\n"
212		"       [--get-vmcb-exit-details]\n"
213		"       [--get-vmcb-tlb-ctrl]\n"
214		"       [--get-vmcb-virq]\n"
215		"       [--get-avic-apic-bar]\n"
216		"       [--get-avic-backing-page]\n"
217		"       [--get-avic-table]\n"
218		);
219	}
220	exit(1);
221}
222
223static int get_stats, getcap, setcap, capval, get_gpa_pmap;
224static int inject_nmi, assert_lapic_lvt;
225static int force_reset, force_poweroff;
226static const char *capname;
227static int create, destroy, get_lowmem, get_highmem;
228static int get_intinfo;
229static int get_active_cpus, get_suspended_cpus;
230static uint64_t memsize;
231static int set_cr0, get_cr0, set_cr3, get_cr3, set_cr4, get_cr4;
232static int set_efer, get_efer;
233static int set_dr7, get_dr7;
234static int set_rsp, get_rsp, set_rip, get_rip, set_rflags, get_rflags;
235static int set_rax, get_rax;
236static int get_rbx, get_rcx, get_rdx, get_rsi, get_rdi, get_rbp;
237static int get_r8, get_r9, get_r10, get_r11, get_r12, get_r13, get_r14, get_r15;
238static int set_desc_ds, get_desc_ds;
239static int set_desc_es, get_desc_es;
240static int set_desc_fs, get_desc_fs;
241static int set_desc_gs, get_desc_gs;
242static int set_desc_cs, get_desc_cs;
243static int set_desc_ss, get_desc_ss;
244static int set_desc_gdtr, get_desc_gdtr;
245static int set_desc_idtr, get_desc_idtr;
246static int set_desc_tr, get_desc_tr;
247static int set_desc_ldtr, get_desc_ldtr;
248static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr;
249static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr;
250static int set_x2apic_state, get_x2apic_state;
251enum x2apic_state x2apic_state;
252static int unassign_pptdev, bus, slot, func;
253static int run;
254
255/*
256 * VMCB specific.
257 */
258static int get_vmcb_intercept, get_vmcb_exit_details, get_vmcb_tlb_ctrl;
259static int get_vmcb_virq, get_avic_table;
260
261/*
262 * VMCS-specific fields
263 */
264static int get_pinbased_ctls, get_procbased_ctls, get_procbased_ctls2;
265static int get_eptp, get_io_bitmap, get_tsc_offset;
266static int get_vmcs_entry_interruption_info, set_vmcs_entry_interruption_info;
267static int get_vmcs_interruptibility;
268uint32_t vmcs_entry_interruption_info;
269static int get_vmcs_gpa, get_vmcs_gla;
270static int get_exception_bitmap, set_exception_bitmap, exception_bitmap;
271static int get_cr0_mask, get_cr0_shadow;
272static int get_cr4_mask, get_cr4_shadow;
273static int get_cr3_targets;
274static int get_apic_access_addr, get_virtual_apic_addr, get_tpr_threshold;
275static int get_msr_bitmap, get_msr_bitmap_address;
276static int get_vpid_asid;
277static int get_inst_err, get_exit_ctls, get_entry_ctls;
278static int get_host_cr0, get_host_cr3, get_host_cr4;
279static int get_host_rip, get_host_rsp;
280static int get_guest_pat, get_host_pat;
281static int get_guest_sysenter, get_vmcs_link;
282static int get_exit_reason, get_vmcs_exit_qualification;
283static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error;
284
285static uint64_t desc_base;
286static uint32_t desc_limit, desc_access;
287
288static int get_all;
289
290static void
291dump_vm_run_exitcode(struct vm_exit *vmexit, int vcpu)
292{
293	printf("vm exit[%d]\n", vcpu);
294	printf("\trip\t\t0x%016lx\n", vmexit->rip);
295	printf("\tinst_length\t%d\n", vmexit->inst_length);
296	switch (vmexit->exitcode) {
297	case VM_EXITCODE_INOUT:
298		printf("\treason\t\tINOUT\n");
299		printf("\tdirection\t%s\n", vmexit->u.inout.in ? "IN" : "OUT");
300		printf("\tbytes\t\t%d\n", vmexit->u.inout.bytes);
301		printf("\tflags\t\t%s%s\n",
302			vmexit->u.inout.string ? "STRING " : "",
303			vmexit->u.inout.rep ? "REP " : "");
304		printf("\tport\t\t0x%04x\n", vmexit->u.inout.port);
305		printf("\teax\t\t0x%08x\n", vmexit->u.inout.eax);
306		break;
307	case VM_EXITCODE_VMX:
308		printf("\treason\t\tVMX\n");
309		printf("\tstatus\t\t%d\n", vmexit->u.vmx.status);
310		printf("\texit_reason\t0x%08x (%u)\n",
311		    vmexit->u.vmx.exit_reason, vmexit->u.vmx.exit_reason);
312		printf("\tqualification\t0x%016lx\n",
313			vmexit->u.vmx.exit_qualification);
314		printf("\tinst_type\t\t%d\n", vmexit->u.vmx.inst_type);
315		printf("\tinst_error\t\t%d\n", vmexit->u.vmx.inst_error);
316		break;
317	case VM_EXITCODE_SVM:
318		printf("\treason\t\tSVM\n");
319		printf("\texit_reason\t\t%#lx\n", vmexit->u.svm.exitcode);
320		printf("\texitinfo1\t\t%#lx\n", vmexit->u.svm.exitinfo1);
321		printf("\texitinfo2\t\t%#lx\n", vmexit->u.svm.exitinfo2);
322		break;
323	default:
324		printf("*** unknown vm run exitcode %d\n", vmexit->exitcode);
325		break;
326	}
327}
328
329/* AMD 6th generation and Intel compatible MSRs */
330#define MSR_AMD6TH_START	0xC0000000
331#define MSR_AMD6TH_END		0xC0001FFF
332/* AMD 7th and 8th generation compatible MSRs */
333#define MSR_AMD7TH_START	0xC0010000
334#define MSR_AMD7TH_END		0xC0011FFF
335
336static const char *
337msr_name(uint32_t msr)
338{
339	static char buf[32];
340
341	switch(msr) {
342	case MSR_TSC:
343		return ("MSR_TSC");
344	case MSR_EFER:
345		return ("MSR_EFER");
346	case MSR_STAR:
347		return ("MSR_STAR");
348	case MSR_LSTAR:
349		return ("MSR_LSTAR");
350	case MSR_CSTAR:
351		return ("MSR_CSTAR");
352	case MSR_SF_MASK:
353		return ("MSR_SF_MASK");
354	case MSR_FSBASE:
355		return ("MSR_FSBASE");
356	case MSR_GSBASE:
357		return ("MSR_GSBASE");
358	case MSR_KGSBASE:
359		return ("MSR_KGSBASE");
360	case MSR_SYSENTER_CS_MSR:
361		return ("MSR_SYSENTER_CS_MSR");
362	case MSR_SYSENTER_ESP_MSR:
363		return ("MSR_SYSENTER_ESP_MSR");
364	case MSR_SYSENTER_EIP_MSR:
365		return ("MSR_SYSENTER_EIP_MSR");
366	case MSR_PAT:
367		return ("MSR_PAT");
368	}
369	snprintf(buf, sizeof(buf), "MSR       %#08x", msr);
370
371	return (buf);
372}
373
374static inline void
375print_msr_pm(uint64_t msr, int vcpu, int readable, int writeable)
376{
377
378	if (readable || writeable) {
379		printf("%-20s[%d]\t\t%c%c\n", msr_name(msr), vcpu,
380			readable ? 'R' : '-', writeable ? 'W' : '-');
381	}
382}
383
384/*
385 * Reference APM vol2, section 15.11 MSR Intercepts.
386 */
387static void
388dump_amd_msr_pm(const char *bitmap, int vcpu)
389{
390	int byte, bit, readable, writeable;
391	uint32_t msr;
392
393	for (msr = 0; msr < 0x2000; msr++) {
394		byte = msr / 4;
395		bit = (msr % 4) * 2;
396
397		/* Look at MSRs in the range 0x00000000 to 0x00001FFF */
398		readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
399		writeable = (bitmap[byte] & (2 << bit)) ?  0 : 1;
400		print_msr_pm(msr, vcpu, readable, writeable);
401
402		/* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */
403		byte += 2048;
404		readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
405		writeable = (bitmap[byte] & (2 << bit)) ?  0 : 1;
406		print_msr_pm(msr + MSR_AMD6TH_START, vcpu, readable,
407				writeable);
408
409		/* MSR 0xC0010000 to 0xC0011FF is only for AMD */
410		byte += 4096;
411		readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
412		writeable = (bitmap[byte] & (2 << bit)) ?  0 : 1;
413		print_msr_pm(msr + MSR_AMD7TH_START, vcpu, readable,
414				writeable);
415	}
416}
417
418/*
419 * Reference Intel SDM Vol3 Section 24.6.9 MSR-Bitmap Address
420 */
421static void
422dump_intel_msr_pm(const char *bitmap, int vcpu)
423{
424	int byte, bit, readable, writeable;
425	uint32_t msr;
426
427	for (msr = 0; msr < 0x2000; msr++) {
428		byte = msr / 8;
429		bit = msr & 0x7;
430
431		/* Look at MSRs in the range 0x00000000 to 0x00001FFF */
432		readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
433		writeable = (bitmap[2048 + byte] & (1 << bit)) ?  0 : 1;
434		print_msr_pm(msr, vcpu, readable, writeable);
435
436		/* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */
437		byte += 1024;
438		readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
439		writeable = (bitmap[2048 + byte] & (1 << bit)) ?  0 : 1;
440		print_msr_pm(msr + MSR_AMD6TH_START, vcpu, readable,
441				writeable);
442	}
443}
444
445static int
446dump_msr_bitmap(int vcpu, uint64_t addr, bool cpu_intel)
447{
448	int error, fd, map_size;
449	const char *bitmap;
450
451	error = -1;
452	bitmap = MAP_FAILED;
453
454	fd = open("/dev/mem", O_RDONLY, 0);
455	if (fd < 0) {
456		perror("Couldn't open /dev/mem");
457		goto done;
458	}
459
460	if (cpu_intel)
461		map_size = PAGE_SIZE;
462	else
463		map_size = 2 * PAGE_SIZE;
464
465	bitmap = mmap(NULL, map_size, PROT_READ, MAP_SHARED, fd, addr);
466	if (bitmap == MAP_FAILED) {
467		perror("mmap failed");
468		goto done;
469	}
470
471	if (cpu_intel)
472		dump_intel_msr_pm(bitmap, vcpu);
473	else
474		dump_amd_msr_pm(bitmap, vcpu);
475
476	error = 0;
477done:
478	if (bitmap != MAP_FAILED)
479		munmap((void *)bitmap, map_size);
480	if (fd >= 0)
481		close(fd);
482
483	return (error);
484}
485
486static int
487vm_get_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t *ret_val)
488{
489
490	return (vm_get_register(ctx, vcpu, VMCS_IDENT(field), ret_val));
491}
492
493static int
494vm_set_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t val)
495{
496
497	return (vm_set_register(ctx, vcpu, VMCS_IDENT(field), val));
498}
499
500static int
501vm_get_vmcb_field(struct vmctx *ctx, int vcpu, int off, int bytes,
502	uint64_t *ret_val)
503{
504
505	return (vm_get_register(ctx, vcpu, VMCB_ACCESS(off, bytes), ret_val));
506}
507
508static int
509vm_set_vmcb_field(struct vmctx *ctx, int vcpu, int off, int bytes,
510	uint64_t val)
511{
512
513	return (vm_set_register(ctx, vcpu, VMCB_ACCESS(off, bytes), val));
514}
515
516enum {
517	VMNAME = 1000,	/* avoid collision with return values from getopt */
518	VCPU,
519	SET_MEM,
520	SET_EFER,
521	SET_CR0,
522	SET_CR3,
523	SET_CR4,
524	SET_DR7,
525	SET_RSP,
526	SET_RIP,
527	SET_RAX,
528	SET_RFLAGS,
529	DESC_BASE,
530	DESC_LIMIT,
531	DESC_ACCESS,
532	SET_CS,
533	SET_DS,
534	SET_ES,
535	SET_FS,
536	SET_GS,
537	SET_SS,
538	SET_TR,
539	SET_LDTR,
540	SET_X2APIC_STATE,
541	SET_EXCEPTION_BITMAP,
542	SET_VMCS_ENTRY_INTERRUPTION_INFO,
543	SET_CAP,
544	CAPNAME,
545	UNASSIGN_PPTDEV,
546	GET_GPA_PMAP,
547	ASSERT_LAPIC_LVT,
548};
549
550static void
551print_cpus(const char *banner, const cpuset_t *cpus)
552{
553	int i, first;
554
555	first = 1;
556	printf("%s:\t", banner);
557	if (!CPU_EMPTY(cpus)) {
558		for (i = 0; i < CPU_SETSIZE; i++) {
559			if (CPU_ISSET(i, cpus)) {
560				printf("%s%d", first ? " " : ", ", i);
561				first = 0;
562			}
563		}
564	} else
565		printf(" (none)");
566	printf("\n");
567}
568
569static void
570print_intinfo(const char *banner, uint64_t info)
571{
572	int type;
573
574	printf("%s:\t", banner);
575	if (info & VM_INTINFO_VALID) {
576		type = info & VM_INTINFO_TYPE;
577		switch (type) {
578		case VM_INTINFO_HWINTR:
579			printf("extint");
580			break;
581		case VM_INTINFO_NMI:
582			printf("nmi");
583			break;
584		case VM_INTINFO_SWINTR:
585			printf("swint");
586			break;
587		default:
588			printf("exception");
589			break;
590		}
591		printf(" vector %d", (int)VM_INTINFO_VECTOR(info));
592		if (info & VM_INTINFO_DEL_ERRCODE)
593			printf(" errcode %#x", (u_int)(info >> 32));
594	} else {
595		printf("n/a");
596	}
597	printf("\n");
598}
599
600static bool
601cpu_vendor_intel(void)
602{
603	u_int regs[4];
604	char cpu_vendor[13];
605
606	do_cpuid(0, regs);
607	((u_int *)&cpu_vendor)[0] = regs[1];
608	((u_int *)&cpu_vendor)[1] = regs[3];
609	((u_int *)&cpu_vendor)[2] = regs[2];
610	cpu_vendor[12] = '\0';
611
612	if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
613		return (false);
614	} else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
615		return (true);
616	} else {
617		fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor);
618		exit(1);
619	}
620}
621
622static int
623get_all_registers(struct vmctx *ctx, int vcpu)
624{
625	uint64_t cr0, cr3, cr4, dr7, rsp, rip, rflags, efer;
626	uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp;
627	uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
628	int error;
629
630	if (get_efer || get_all) {
631		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_EFER, &efer);
632		if (error == 0)
633			printf("efer[%d]\t\t0x%016lx\n", vcpu, efer);
634	}
635
636	if (!error && (get_cr0 || get_all)) {
637		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR0, &cr0);
638		if (error == 0)
639			printf("cr0[%d]\t\t0x%016lx\n", vcpu, cr0);
640	}
641
642	if (!error && (get_cr3 || get_all)) {
643		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR3, &cr3);
644		if (error == 0)
645			printf("cr3[%d]\t\t0x%016lx\n", vcpu, cr3);
646	}
647
648	if (!error && (get_cr4 || get_all)) {
649		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR4, &cr4);
650		if (error == 0)
651			printf("cr4[%d]\t\t0x%016lx\n", vcpu, cr4);
652	}
653
654	if (!error && (get_dr7 || get_all)) {
655		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR7, &dr7);
656		if (error == 0)
657			printf("dr7[%d]\t\t0x%016lx\n", vcpu, dr7);
658	}
659
660	if (!error && (get_rsp || get_all)) {
661		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSP, &rsp);
662		if (error == 0)
663			printf("rsp[%d]\t\t0x%016lx\n", vcpu, rsp);
664	}
665
666	if (!error && (get_rip || get_all)) {
667		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip);
668		if (error == 0)
669			printf("rip[%d]\t\t0x%016lx\n", vcpu, rip);
670	}
671
672	if (!error && (get_rax || get_all)) {
673		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &rax);
674		if (error == 0)
675			printf("rax[%d]\t\t0x%016lx\n", vcpu, rax);
676	}
677
678	if (!error && (get_rbx || get_all)) {
679		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBX, &rbx);
680		if (error == 0)
681			printf("rbx[%d]\t\t0x%016lx\n", vcpu, rbx);
682	}
683
684	if (!error && (get_rcx || get_all)) {
685		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RCX, &rcx);
686		if (error == 0)
687			printf("rcx[%d]\t\t0x%016lx\n", vcpu, rcx);
688	}
689
690	if (!error && (get_rdx || get_all)) {
691		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDX, &rdx);
692		if (error == 0)
693			printf("rdx[%d]\t\t0x%016lx\n", vcpu, rdx);
694	}
695
696	if (!error && (get_rsi || get_all)) {
697		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSI, &rsi);
698		if (error == 0)
699			printf("rsi[%d]\t\t0x%016lx\n", vcpu, rsi);
700	}
701
702	if (!error && (get_rdi || get_all)) {
703		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDI, &rdi);
704		if (error == 0)
705			printf("rdi[%d]\t\t0x%016lx\n", vcpu, rdi);
706	}
707
708	if (!error && (get_rbp || get_all)) {
709		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBP, &rbp);
710		if (error == 0)
711			printf("rbp[%d]\t\t0x%016lx\n", vcpu, rbp);
712	}
713
714	if (!error && (get_r8 || get_all)) {
715		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R8, &r8);
716		if (error == 0)
717			printf("r8[%d]\t\t0x%016lx\n", vcpu, r8);
718	}
719
720	if (!error && (get_r9 || get_all)) {
721		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R9, &r9);
722		if (error == 0)
723			printf("r9[%d]\t\t0x%016lx\n", vcpu, r9);
724	}
725
726	if (!error && (get_r10 || get_all)) {
727		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R10, &r10);
728		if (error == 0)
729			printf("r10[%d]\t\t0x%016lx\n", vcpu, r10);
730	}
731
732	if (!error && (get_r11 || get_all)) {
733		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R11, &r11);
734		if (error == 0)
735			printf("r11[%d]\t\t0x%016lx\n", vcpu, r11);
736	}
737
738	if (!error && (get_r12 || get_all)) {
739		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R12, &r12);
740		if (error == 0)
741			printf("r12[%d]\t\t0x%016lx\n", vcpu, r12);
742	}
743
744	if (!error && (get_r13 || get_all)) {
745		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R13, &r13);
746		if (error == 0)
747			printf("r13[%d]\t\t0x%016lx\n", vcpu, r13);
748	}
749
750	if (!error && (get_r14 || get_all)) {
751		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R14, &r14);
752		if (error == 0)
753			printf("r14[%d]\t\t0x%016lx\n", vcpu, r14);
754	}
755
756	if (!error && (get_r15 || get_all)) {
757		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R15, &r15);
758		if (error == 0)
759			printf("r15[%d]\t\t0x%016lx\n", vcpu, r15);
760	}
761
762	if (!error && (get_rflags || get_all)) {
763		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RFLAGS,
764					&rflags);
765		if (error == 0)
766			printf("rflags[%d]\t0x%016lx\n", vcpu, rflags);
767	}
768
769	return (error);
770}
771
772static int
773get_all_segments(struct vmctx *ctx, int vcpu)
774{
775	int error;
776	uint64_t cs, ds, es, fs, gs, ss, tr, ldtr;
777
778	if (get_desc_ds || get_all) {
779		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_DS,
780				   &desc_base, &desc_limit, &desc_access);
781		if (error == 0) {
782			printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
783			      vcpu, desc_base, desc_limit, desc_access);
784		}
785	}
786
787	if (!error && (get_desc_es || get_all)) {
788		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_ES,
789				    &desc_base, &desc_limit, &desc_access);
790		if (error == 0) {
791			printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
792			       vcpu, desc_base, desc_limit, desc_access);
793		}
794	}
795
796	if (!error && (get_desc_fs || get_all)) {
797		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_FS,
798				    &desc_base, &desc_limit, &desc_access);
799		if (error == 0) {
800			printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
801			       vcpu, desc_base, desc_limit, desc_access);
802		}
803	}
804
805	if (!error && (get_desc_gs || get_all)) {
806		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GS,
807				    &desc_base, &desc_limit, &desc_access);
808		if (error == 0) {
809			printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
810			       vcpu, desc_base, desc_limit, desc_access);
811		}
812	}
813
814	if (!error && (get_desc_ss || get_all)) {
815		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_SS,
816				    &desc_base, &desc_limit, &desc_access);
817		if (error == 0) {
818			printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
819			       vcpu, desc_base, desc_limit, desc_access);
820		}
821	}
822
823	if (!error && (get_desc_cs || get_all)) {
824		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_CS,
825				    &desc_base, &desc_limit, &desc_access);
826		if (error == 0) {
827			printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
828			       vcpu, desc_base, desc_limit, desc_access);
829		}
830	}
831
832	if (!error && (get_desc_tr || get_all)) {
833		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_TR,
834				    &desc_base, &desc_limit, &desc_access);
835		if (error == 0) {
836			printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
837			       vcpu, desc_base, desc_limit, desc_access);
838		}
839	}
840
841	if (!error && (get_desc_ldtr || get_all)) {
842		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_LDTR,
843				    &desc_base, &desc_limit, &desc_access);
844		if (error == 0) {
845			printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
846			       vcpu, desc_base, desc_limit, desc_access);
847		}
848	}
849
850	if (!error && (get_desc_gdtr || get_all)) {
851		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GDTR,
852				    &desc_base, &desc_limit, &desc_access);
853		if (error == 0) {
854			printf("gdtr[%d]\t\t0x%016lx/0x%08x\n",
855			       vcpu, desc_base, desc_limit);
856		}
857	}
858
859	if (!error && (get_desc_idtr || get_all)) {
860		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_IDTR,
861				    &desc_base, &desc_limit, &desc_access);
862		if (error == 0) {
863			printf("idtr[%d]\t\t0x%016lx/0x%08x\n",
864			       vcpu, desc_base, desc_limit);
865		}
866	}
867
868	if (!error && (get_cs || get_all)) {
869		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CS, &cs);
870		if (error == 0)
871			printf("cs[%d]\t\t0x%04lx\n", vcpu, cs);
872	}
873
874	if (!error && (get_ds || get_all)) {
875		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DS, &ds);
876		if (error == 0)
877			printf("ds[%d]\t\t0x%04lx\n", vcpu, ds);
878	}
879
880	if (!error && (get_es || get_all)) {
881		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_ES, &es);
882		if (error == 0)
883			printf("es[%d]\t\t0x%04lx\n", vcpu, es);
884	}
885
886	if (!error && (get_fs || get_all)) {
887		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_FS, &fs);
888		if (error == 0)
889			printf("fs[%d]\t\t0x%04lx\n", vcpu, fs);
890	}
891
892	if (!error && (get_gs || get_all)) {
893		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_GS, &gs);
894		if (error == 0)
895			printf("gs[%d]\t\t0x%04lx\n", vcpu, gs);
896	}
897
898	if (!error && (get_ss || get_all)) {
899		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_SS, &ss);
900		if (error == 0)
901			printf("ss[%d]\t\t0x%04lx\n", vcpu, ss);
902	}
903
904	if (!error && (get_tr || get_all)) {
905		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_TR, &tr);
906		if (error == 0)
907			printf("tr[%d]\t\t0x%04lx\n", vcpu, tr);
908	}
909
910	if (!error && (get_ldtr || get_all)) {
911		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_LDTR, &ldtr);
912		if (error == 0)
913			printf("ldtr[%d]\t\t0x%04lx\n", vcpu, ldtr);
914	}
915
916	return (error);
917}
918
919static int
920get_misc_vmcs(struct vmctx *ctx, int vcpu)
921{
922	uint64_t ctl, cr0, cr3, cr4, rsp, rip, pat, addr, u64;
923	int error;
924
925	if (get_cr0_mask || get_all) {
926		uint64_t cr0mask;
927		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_MASK, &cr0mask);
928		if (error == 0)
929			printf("cr0_mask[%d]\t\t0x%016lx\n", vcpu, cr0mask);
930	}
931
932	if (!error && (get_cr0_shadow || get_all)) {
933		uint64_t cr0shadow;
934		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_SHADOW,
935					  &cr0shadow);
936		if (error == 0)
937			printf("cr0_shadow[%d]\t\t0x%016lx\n", vcpu, cr0shadow);
938	}
939
940	if (!error && (get_cr4_mask || get_all)) {
941		uint64_t cr4mask;
942		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_MASK, &cr4mask);
943		if (error == 0)
944			printf("cr4_mask[%d]\t\t0x%016lx\n", vcpu, cr4mask);
945	}
946
947	if (!error && (get_cr4_shadow || get_all)) {
948		uint64_t cr4shadow;
949		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_SHADOW,
950					  &cr4shadow);
951		if (error == 0)
952			printf("cr4_shadow[%d]\t\t0x%016lx\n", vcpu, cr4shadow);
953	}
954
955	if (!error && (get_cr3_targets || get_all)) {
956		uint64_t target_count, target_addr;
957		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET_COUNT,
958					  &target_count);
959		if (error == 0) {
960			printf("cr3_target_count[%d]\t0x%016lx\n",
961				vcpu, target_count);
962		}
963
964		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET0,
965					  &target_addr);
966		if (error == 0) {
967			printf("cr3_target0[%d]\t\t0x%016lx\n",
968				vcpu, target_addr);
969		}
970
971		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET1,
972					  &target_addr);
973		if (error == 0) {
974			printf("cr3_target1[%d]\t\t0x%016lx\n",
975				vcpu, target_addr);
976		}
977
978		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET2,
979					  &target_addr);
980		if (error == 0) {
981			printf("cr3_target2[%d]\t\t0x%016lx\n",
982				vcpu, target_addr);
983		}
984
985		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET3,
986					  &target_addr);
987		if (error == 0) {
988			printf("cr3_target3[%d]\t\t0x%016lx\n",
989				vcpu, target_addr);
990		}
991	}
992
993	if (!error && (get_pinbased_ctls || get_all)) {
994		error = vm_get_vmcs_field(ctx, vcpu, VMCS_PIN_BASED_CTLS, &ctl);
995		if (error == 0)
996			printf("pinbased_ctls[%d]\t0x%016lx\n", vcpu, ctl);
997	}
998
999	if (!error && (get_procbased_ctls || get_all)) {
1000		error = vm_get_vmcs_field(ctx, vcpu,
1001					  VMCS_PRI_PROC_BASED_CTLS, &ctl);
1002		if (error == 0)
1003			printf("procbased_ctls[%d]\t0x%016lx\n", vcpu, ctl);
1004	}
1005
1006	if (!error && (get_procbased_ctls2 || get_all)) {
1007		error = vm_get_vmcs_field(ctx, vcpu,
1008					  VMCS_SEC_PROC_BASED_CTLS, &ctl);
1009		if (error == 0)
1010			printf("procbased_ctls2[%d]\t0x%016lx\n", vcpu, ctl);
1011	}
1012
1013	if (!error && (get_vmcs_gla || get_all)) {
1014		error = vm_get_vmcs_field(ctx, vcpu,
1015					  VMCS_GUEST_LINEAR_ADDRESS, &u64);
1016		if (error == 0)
1017			printf("gla[%d]\t\t0x%016lx\n", vcpu, u64);
1018	}
1019
1020	if (!error && (get_vmcs_gpa || get_all)) {
1021		error = vm_get_vmcs_field(ctx, vcpu,
1022					  VMCS_GUEST_PHYSICAL_ADDRESS, &u64);
1023		if (error == 0)
1024			printf("gpa[%d]\t\t0x%016lx\n", vcpu, u64);
1025	}
1026
1027	if (!error && (get_vmcs_entry_interruption_info ||
1028		get_all)) {
1029		error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,&u64);
1030		if (error == 0) {
1031			printf("entry_interruption_info[%d]\t0x%016lx\n",
1032				vcpu, u64);
1033		}
1034	}
1035
1036	if (!error && (get_tpr_threshold || get_all)) {
1037		uint64_t threshold;
1038		error = vm_get_vmcs_field(ctx, vcpu, VMCS_TPR_THRESHOLD,
1039					  &threshold);
1040		if (error == 0)
1041			printf("tpr_threshold[%d]\t0x%016lx\n", vcpu, threshold);
1042	}
1043
1044	if (!error && (get_inst_err || get_all)) {
1045		uint64_t insterr;
1046		error = vm_get_vmcs_field(ctx, vcpu, VMCS_INSTRUCTION_ERROR,
1047					  &insterr);
1048		if (error == 0) {
1049			printf("instruction_error[%d]\t0x%016lx\n",
1050				vcpu, insterr);
1051		}
1052	}
1053
1054	if (!error && (get_exit_ctls || get_all)) {
1055		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_CTLS, &ctl);
1056		if (error == 0)
1057			printf("exit_ctls[%d]\t\t0x%016lx\n", vcpu, ctl);
1058	}
1059
1060	if (!error && (get_entry_ctls || get_all)) {
1061		error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_CTLS, &ctl);
1062		if (error == 0)
1063			printf("entry_ctls[%d]\t\t0x%016lx\n", vcpu, ctl);
1064	}
1065
1066	if (!error && (get_host_pat || get_all)) {
1067		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_IA32_PAT, &pat);
1068		if (error == 0)
1069			printf("host_pat[%d]\t\t0x%016lx\n", vcpu, pat);
1070	}
1071
1072	if (!error && (get_host_cr0 || get_all)) {
1073		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR0, &cr0);
1074		if (error == 0)
1075			printf("host_cr0[%d]\t\t0x%016lx\n", vcpu, cr0);
1076	}
1077
1078	if (!error && (get_host_cr3 || get_all)) {
1079		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR3, &cr3);
1080		if (error == 0)
1081			printf("host_cr3[%d]\t\t0x%016lx\n", vcpu, cr3);
1082	}
1083
1084	if (!error && (get_host_cr4 || get_all)) {
1085		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR4, &cr4);
1086		if (error == 0)
1087			printf("host_cr4[%d]\t\t0x%016lx\n", vcpu, cr4);
1088	}
1089
1090	if (!error && (get_host_rip || get_all)) {
1091		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RIP, &rip);
1092		if (error == 0)
1093			printf("host_rip[%d]\t\t0x%016lx\n", vcpu, rip);
1094	}
1095
1096	if (!error && (get_host_rsp || get_all)) {
1097		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RSP, &rsp);
1098		if (error == 0)
1099			printf("host_rsp[%d]\t\t0x%016lx\n", vcpu, rsp);
1100	}
1101
1102	if (!error && (get_vmcs_link || get_all)) {
1103		error = vm_get_vmcs_field(ctx, vcpu, VMCS_LINK_POINTER, &addr);
1104		if (error == 0)
1105			printf("vmcs_pointer[%d]\t0x%016lx\n", vcpu, addr);
1106	}
1107
1108	if (!error && (get_vmcs_exit_interruption_info || get_all)) {
1109		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_INFO, &u64);
1110		if (error == 0) {
1111			printf("vmcs_exit_interruption_info[%d]\t0x%016lx\n",
1112				vcpu, u64);
1113		}
1114	}
1115
1116	if (!error && (get_vmcs_exit_interruption_error || get_all)) {
1117		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_ERRCODE,
1118		    			  &u64);
1119		if (error == 0) {
1120			printf("vmcs_exit_interruption_error[%d]\t0x%016lx\n",
1121				vcpu, u64);
1122		}
1123	}
1124
1125	if (!error && (get_vmcs_interruptibility || get_all)) {
1126		error = vm_get_vmcs_field(ctx, vcpu,
1127					  VMCS_GUEST_INTERRUPTIBILITY, &u64);
1128		if (error == 0) {
1129			printf("vmcs_guest_interruptibility[%d]\t0x%016lx\n",
1130				vcpu, u64);
1131		}
1132	}
1133
1134	if (!error && (get_vmcs_exit_qualification || get_all)) {
1135		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_QUALIFICATION,
1136					  &u64);
1137		if (error == 0)
1138			printf("vmcs_exit_qualification[%d]\t0x%016lx\n",
1139				vcpu, u64);
1140	}
1141
1142	return (error);
1143}
1144
1145static int
1146get_misc_vmcb(struct vmctx *ctx, int vcpu)
1147{
1148	uint64_t ctl, addr;
1149	int error;
1150
1151	if (get_vmcb_intercept || get_all) {
1152		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_CR_INTERCEPT, 4,
1153		    &ctl);
1154		if (error == 0)
1155			printf("cr_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1156
1157		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_DR_INTERCEPT, 4,
1158		    &ctl);
1159		if (error == 0)
1160			printf("dr_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1161
1162		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXC_INTERCEPT, 4,
1163		    &ctl);
1164		if (error == 0)
1165			printf("exc_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1166
1167		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_INST1_INTERCEPT,
1168		    4, &ctl);
1169		if (error == 0)
1170			printf("inst1_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1171
1172		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_INST2_INTERCEPT,
1173		    4, &ctl);
1174		if (error == 0)
1175			printf("inst2_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1176	}
1177
1178	if (!error && (get_vmcb_tlb_ctrl || get_all)) {
1179		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_TLB_CTRL,
1180					  4, &ctl);
1181		if (error == 0)
1182			printf("TLB ctrl[%d]\t0x%016lx\n", vcpu, ctl);
1183	}
1184
1185	if (!error && (get_vmcb_exit_details || get_all)) {
1186		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINFO1,
1187					  8, &ctl);
1188		if (error == 0)
1189			printf("exitinfo1[%d]\t0x%016lx\n", vcpu, ctl);
1190		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINFO2,
1191					  8, &ctl);
1192		if (error == 0)
1193			printf("exitinfo2[%d]\t0x%016lx\n", vcpu, ctl);
1194		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINTINFO,
1195					  8, &ctl);
1196		if (error == 0)
1197			printf("exitintinfo[%d]\t0x%016lx\n", vcpu, ctl);
1198	}
1199
1200	if (!error && (get_vmcb_virq || get_all)) {
1201		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_VIRQ,
1202					  8, &ctl);
1203		if (error == 0)
1204			printf("v_irq/tpr[%d]\t0x%016lx\n", vcpu, ctl);
1205	}
1206
1207	if (!error && (get_apic_access_addr || get_all)) {
1208		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_BAR, 8,
1209					  &addr);
1210		if (error == 0)
1211			printf("AVIC apic_bar[%d]\t0x%016lx\n", vcpu, addr);
1212	}
1213
1214	if (!error && (get_virtual_apic_addr || get_all)) {
1215		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_PAGE, 8,
1216					  &addr);
1217		if (error == 0)
1218			printf("AVIC backing page[%d]\t0x%016lx\n", vcpu, addr);
1219	}
1220
1221	if (!error && (get_avic_table || get_all)) {
1222		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_LT, 8,
1223					  &addr);
1224		if (error == 0)
1225			printf("AVIC logical table[%d]\t0x%016lx\n",
1226				vcpu, addr);
1227		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_PT, 8,
1228					  &addr);
1229		if (error == 0)
1230			printf("AVIC physical table[%d]\t0x%016lx\n",
1231				vcpu, addr);
1232	}
1233
1234	return (error);
1235}
1236
1237static struct option *
1238setup_options(bool cpu_intel)
1239{
1240	const struct option common_opts[] = {
1241		{ "vm",		REQ_ARG,	0,	VMNAME },
1242		{ "cpu",	REQ_ARG,	0,	VCPU },
1243		{ "set-mem",	REQ_ARG,	0,	SET_MEM },
1244		{ "set-efer",	REQ_ARG,	0,	SET_EFER },
1245		{ "set-cr0",	REQ_ARG,	0,	SET_CR0 },
1246		{ "set-cr3",	REQ_ARG,	0,	SET_CR3 },
1247		{ "set-cr4",	REQ_ARG,	0,	SET_CR4 },
1248		{ "set-dr7",	REQ_ARG,	0,	SET_DR7 },
1249		{ "set-rsp",	REQ_ARG,	0,	SET_RSP },
1250		{ "set-rip",	REQ_ARG,	0,	SET_RIP },
1251		{ "set-rax",	REQ_ARG,	0,	SET_RAX },
1252		{ "set-rflags",	REQ_ARG,	0,	SET_RFLAGS },
1253		{ "desc-base",	REQ_ARG,	0,	DESC_BASE },
1254		{ "desc-limit",	REQ_ARG,	0,	DESC_LIMIT },
1255		{ "desc-access",REQ_ARG,	0,	DESC_ACCESS },
1256		{ "set-cs",	REQ_ARG,	0,	SET_CS },
1257		{ "set-ds",	REQ_ARG,	0,	SET_DS },
1258		{ "set-es",	REQ_ARG,	0,	SET_ES },
1259		{ "set-fs",	REQ_ARG,	0,	SET_FS },
1260		{ "set-gs",	REQ_ARG,	0,	SET_GS },
1261		{ "set-ss",	REQ_ARG,	0,	SET_SS },
1262		{ "set-tr",	REQ_ARG,	0,	SET_TR },
1263		{ "set-ldtr",	REQ_ARG,	0,	SET_LDTR },
1264		{ "set-x2apic-state",REQ_ARG,	0,	SET_X2APIC_STATE },
1265		{ "set-exception-bitmap",
1266				REQ_ARG,	0, SET_EXCEPTION_BITMAP },
1267		{ "capname",	REQ_ARG,	0,	CAPNAME },
1268		{ "unassign-pptdev", REQ_ARG,	0,	UNASSIGN_PPTDEV },
1269		{ "setcap",	REQ_ARG,	0,	SET_CAP },
1270		{ "get-gpa-pmap", REQ_ARG,	0,	GET_GPA_PMAP },
1271		{ "assert-lapic-lvt", REQ_ARG,	0,	ASSERT_LAPIC_LVT },
1272		{ "getcap",	NO_ARG,		&getcap,	1 },
1273		{ "get-stats",	NO_ARG,		&get_stats,	1 },
1274		{ "get-desc-ds",NO_ARG,		&get_desc_ds,	1 },
1275		{ "set-desc-ds",NO_ARG,		&set_desc_ds,	1 },
1276		{ "get-desc-es",NO_ARG,		&get_desc_es,	1 },
1277		{ "set-desc-es",NO_ARG,		&set_desc_es,	1 },
1278		{ "get-desc-ss",NO_ARG,		&get_desc_ss,	1 },
1279		{ "set-desc-ss",NO_ARG,		&set_desc_ss,	1 },
1280		{ "get-desc-cs",NO_ARG,		&get_desc_cs,	1 },
1281		{ "set-desc-cs",NO_ARG,		&set_desc_cs,	1 },
1282		{ "get-desc-fs",NO_ARG,		&get_desc_fs,	1 },
1283		{ "set-desc-fs",NO_ARG,		&set_desc_fs,	1 },
1284		{ "get-desc-gs",NO_ARG,		&get_desc_gs,	1 },
1285		{ "set-desc-gs",NO_ARG,		&set_desc_gs,	1 },
1286		{ "get-desc-tr",NO_ARG,		&get_desc_tr,	1 },
1287		{ "set-desc-tr",NO_ARG,		&set_desc_tr,	1 },
1288		{ "set-desc-ldtr", NO_ARG,	&set_desc_ldtr,	1 },
1289		{ "get-desc-ldtr", NO_ARG,	&get_desc_ldtr,	1 },
1290		{ "set-desc-gdtr", NO_ARG,	&set_desc_gdtr, 1 },
1291		{ "get-desc-gdtr", NO_ARG,	&get_desc_gdtr, 1 },
1292		{ "set-desc-idtr", NO_ARG,	&set_desc_idtr, 1 },
1293		{ "get-desc-idtr", NO_ARG,	&get_desc_idtr, 1 },
1294		{ "get-lowmem", NO_ARG,		&get_lowmem,	1 },
1295		{ "get-highmem",NO_ARG,		&get_highmem,	1 },
1296		{ "get-efer",	NO_ARG,		&get_efer,	1 },
1297		{ "get-cr0",	NO_ARG,		&get_cr0,	1 },
1298		{ "get-cr3",	NO_ARG,		&get_cr3,	1 },
1299		{ "get-cr4",	NO_ARG,		&get_cr4,	1 },
1300		{ "get-dr7",	NO_ARG,		&get_dr7,	1 },
1301		{ "get-rsp",	NO_ARG,		&get_rsp,	1 },
1302		{ "get-rip",	NO_ARG,		&get_rip,	1 },
1303		{ "get-rax",	NO_ARG,		&get_rax,	1 },
1304		{ "get-rbx",	NO_ARG,		&get_rbx,	1 },
1305		{ "get-rcx",	NO_ARG,		&get_rcx,	1 },
1306		{ "get-rdx",	NO_ARG,		&get_rdx,	1 },
1307		{ "get-rsi",	NO_ARG,		&get_rsi,	1 },
1308		{ "get-rdi",	NO_ARG,		&get_rdi,	1 },
1309		{ "get-rbp",	NO_ARG,		&get_rbp,	1 },
1310		{ "get-r8",	NO_ARG,		&get_r8,	1 },
1311		{ "get-r9",	NO_ARG,		&get_r9,	1 },
1312		{ "get-r10",	NO_ARG,		&get_r10,	1 },
1313		{ "get-r11",	NO_ARG,		&get_r11,	1 },
1314		{ "get-r12",	NO_ARG,		&get_r12,	1 },
1315		{ "get-r13",	NO_ARG,		&get_r13,	1 },
1316		{ "get-r14",	NO_ARG,		&get_r14,	1 },
1317		{ "get-r15",	NO_ARG,		&get_r15,	1 },
1318		{ "get-rflags",	NO_ARG,		&get_rflags,	1 },
1319		{ "get-cs",	NO_ARG,		&get_cs,	1 },
1320		{ "get-ds",	NO_ARG,		&get_ds,	1 },
1321		{ "get-es",	NO_ARG,		&get_es,	1 },
1322		{ "get-fs",	NO_ARG,		&get_fs,	1 },
1323		{ "get-gs",	NO_ARG,		&get_gs,	1 },
1324		{ "get-ss",	NO_ARG,		&get_ss,	1 },
1325		{ "get-tr",	NO_ARG,		&get_tr,	1 },
1326		{ "get-ldtr",	NO_ARG,		&get_ldtr,	1 },
1327		{ "get-eptp", 	NO_ARG,		&get_eptp,	1 },
1328		{ "get-exception-bitmap",
1329					NO_ARG,	&get_exception_bitmap,  1 },
1330		{ "get-io-bitmap-address",
1331					NO_ARG,	&get_io_bitmap,		1 },
1332		{ "get-tsc-offset", 	NO_ARG, &get_tsc_offset, 	1 },
1333		{ "get-msr-bitmap",
1334					NO_ARG,	&get_msr_bitmap, 	1 },
1335		{ "get-msr-bitmap-address",
1336					NO_ARG,	&get_msr_bitmap_address, 1 },
1337		{ "get-guest-pat",	NO_ARG,	&get_guest_pat,		1 },
1338		{ "get-guest-sysenter",
1339					NO_ARG,	&get_guest_sysenter, 	1 },
1340		{ "get-exit-reason",
1341					NO_ARG,	&get_exit_reason, 	1 },
1342		{ "get-x2apic-state",	NO_ARG,	&get_x2apic_state, 	1 },
1343		{ "get-all",		NO_ARG,	&get_all,		1 },
1344		{ "run",		NO_ARG,	&run,			1 },
1345		{ "create",		NO_ARG,	&create,		1 },
1346		{ "destroy",		NO_ARG,	&destroy,		1 },
1347		{ "inject-nmi",		NO_ARG,	&inject_nmi,		1 },
1348		{ "force-reset",	NO_ARG,	&force_reset,		1 },
1349		{ "force-poweroff", 	NO_ARG,	&force_poweroff, 	1 },
1350		{ "get-active-cpus", 	NO_ARG,	&get_active_cpus, 	1 },
1351		{ "get-suspended-cpus", NO_ARG,	&get_suspended_cpus, 	1 },
1352		{ "get-intinfo", 	NO_ARG,	&get_intinfo,		1 },
1353	};
1354
1355	const struct option intel_opts[] = {
1356		{ "get-vmcs-pinbased-ctls",
1357				NO_ARG,		&get_pinbased_ctls, 1 },
1358		{ "get-vmcs-procbased-ctls",
1359				NO_ARG,		&get_procbased_ctls, 1 },
1360		{ "get-vmcs-procbased-ctls2",
1361				NO_ARG,		&get_procbased_ctls2, 1 },
1362		{ "get-vmcs-guest-linear-address",
1363				NO_ARG,		&get_vmcs_gla,	1 },
1364		{ "get-vmcs-guest-physical-address",
1365				NO_ARG,		&get_vmcs_gpa,	1 },
1366		{ "get-vmcs-entry-interruption-info",
1367				NO_ARG, &get_vmcs_entry_interruption_info, 1},
1368		{ "get-vmcs-cr0-mask", NO_ARG,	&get_cr0_mask,	1 },
1369		{ "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 },
1370		{ "get-vmcs-cr4-mask", 		NO_ARG,	&get_cr4_mask,	  1 },
1371		{ "get-vmcs-cr4-shadow", 	NO_ARG, &get_cr4_shadow,  1 },
1372		{ "get-vmcs-cr3-targets", 	NO_ARG, &get_cr3_targets, 1 },
1373		{ "get-vmcs-tpr-threshold",
1374					NO_ARG,	&get_tpr_threshold, 1 },
1375		{ "get-vmcs-vpid", 	NO_ARG,	&get_vpid_asid,	    1 },
1376		{ "get-vmcs-exit-ctls", NO_ARG,	&get_exit_ctls,	    1 },
1377		{ "get-vmcs-entry-ctls",
1378					NO_ARG,	&get_entry_ctls, 1 },
1379		{ "get-vmcs-instruction-error",
1380					NO_ARG,	&get_inst_err,	1 },
1381		{ "get-vmcs-host-pat",	NO_ARG,	&get_host_pat,	1 },
1382		{ "get-vmcs-host-cr0",
1383					NO_ARG,	&get_host_cr0,	1 },
1384		{ "set-vmcs-entry-interruption-info",
1385				REQ_ARG, 0, SET_VMCS_ENTRY_INTERRUPTION_INFO },
1386		{ "get-vmcs-exit-qualification",
1387				NO_ARG,	&get_vmcs_exit_qualification, 1 },
1388		{ "get-vmcs-interruptibility",
1389				NO_ARG, &get_vmcs_interruptibility, 1 },
1390		{ "get-vmcs-exit-interruption-error",
1391				NO_ARG,	&get_vmcs_exit_interruption_error, 1 },
1392		{ "get-vmcs-exit-interruption-info",
1393				NO_ARG,	&get_vmcs_exit_interruption_info, 1 },
1394		{ "get-vmcs-link", 	NO_ARG,		&get_vmcs_link, 1 },
1395		{ "get-vmcs-host-cr3",
1396					NO_ARG,		&get_host_cr3,	1 },
1397		{ "get-vmcs-host-cr4",
1398				NO_ARG,		&get_host_cr4,	1 },
1399		{ "get-vmcs-host-rip",
1400				NO_ARG,		&get_host_rip,	1 },
1401		{ "get-vmcs-host-rsp",
1402				NO_ARG,		&get_host_rsp,	1 },
1403		{ "get-apic-access-address",
1404				NO_ARG,		&get_apic_access_addr, 1},
1405		{ "get-virtual-apic-address",
1406				NO_ARG,		&get_virtual_apic_addr, 1}
1407	};
1408
1409	const struct option amd_opts[] = {
1410		{ "get-vmcb-intercepts",
1411				NO_ARG,	&get_vmcb_intercept, 	1 },
1412		{ "get-vmcb-asid",
1413				NO_ARG,	&get_vpid_asid,	     	1 },
1414		{ "get-vmcb-exit-details",
1415				NO_ARG, &get_vmcb_exit_details,	1 },
1416		{ "get-vmcb-tlb-ctrl",
1417				NO_ARG, &get_vmcb_tlb_ctrl, 	1 },
1418		{ "get-vmcb-virq",
1419				NO_ARG, &get_vmcb_virq, 	1 },
1420		{ "get-avic-apic-bar",
1421				NO_ARG,	&get_apic_access_addr, 	1 },
1422		{ "get-avic-backing-page",
1423				NO_ARG,	&get_virtual_apic_addr, 1 },
1424		{ "get-avic-table",
1425				NO_ARG,	&get_avic_table, 	1 }
1426	};
1427
1428	const struct option null_opt = {
1429		NULL, 0, NULL, 0
1430	};
1431
1432	struct option *all_opts;
1433	char *cp;
1434	int optlen;
1435
1436	optlen = sizeof(common_opts);
1437
1438	if (cpu_intel)
1439		optlen += sizeof(intel_opts);
1440	else
1441		optlen += sizeof(amd_opts);
1442
1443	optlen += sizeof(null_opt);
1444
1445	all_opts = malloc(optlen);
1446
1447	cp = (char *)all_opts;
1448	memcpy(cp, common_opts, sizeof(common_opts));
1449	cp += sizeof(common_opts);
1450
1451	if (cpu_intel) {
1452		memcpy(cp, intel_opts, sizeof(intel_opts));
1453		cp += sizeof(intel_opts);
1454	} else {
1455		memcpy(cp, amd_opts, sizeof(amd_opts));
1456		cp += sizeof(amd_opts);
1457	}
1458
1459	memcpy(cp, &null_opt, sizeof(null_opt));
1460	cp += sizeof(null_opt);
1461
1462	return (all_opts);
1463}
1464
1465int
1466main(int argc, char *argv[])
1467{
1468	char *vmname;
1469	int error, ch, vcpu, ptenum;
1470	vm_paddr_t gpa, gpa_pmap;
1471	size_t len;
1472	struct vm_exit vmexit;
1473	uint64_t rax, cr0, cr3, cr4, dr7, rsp, rip, rflags, efer, pat;
1474	uint64_t eptp, bm, addr, u64, pteval[4], *pte, info[2];
1475	struct vmctx *ctx;
1476	int wired;
1477	cpuset_t cpus;
1478	bool cpu_intel;
1479	uint64_t cs, ds, es, fs, gs, ss, tr, ldtr;
1480	struct option *opts;
1481
1482	cpu_intel = cpu_vendor_intel();
1483	opts = setup_options(cpu_intel);
1484
1485	vcpu = 0;
1486	vmname = NULL;
1487	assert_lapic_lvt = -1;
1488	progname = basename(argv[0]);
1489
1490	while ((ch = getopt_long(argc, argv, "", opts, NULL)) != -1) {
1491		switch (ch) {
1492		case 0:
1493			break;
1494		case VMNAME:
1495			vmname = optarg;
1496			break;
1497		case VCPU:
1498			vcpu = atoi(optarg);
1499			break;
1500		case SET_MEM:
1501			memsize = atoi(optarg) * MB;
1502			memsize = roundup(memsize, 2 * MB);
1503			break;
1504		case SET_EFER:
1505			efer = strtoul(optarg, NULL, 0);
1506			set_efer = 1;
1507			break;
1508		case SET_CR0:
1509			cr0 = strtoul(optarg, NULL, 0);
1510			set_cr0 = 1;
1511			break;
1512		case SET_CR3:
1513			cr3 = strtoul(optarg, NULL, 0);
1514			set_cr3 = 1;
1515			break;
1516		case SET_CR4:
1517			cr4 = strtoul(optarg, NULL, 0);
1518			set_cr4 = 1;
1519			break;
1520		case SET_DR7:
1521			dr7 = strtoul(optarg, NULL, 0);
1522			set_dr7 = 1;
1523			break;
1524		case SET_RSP:
1525			rsp = strtoul(optarg, NULL, 0);
1526			set_rsp = 1;
1527			break;
1528		case SET_RIP:
1529			rip = strtoul(optarg, NULL, 0);
1530			set_rip = 1;
1531			break;
1532		case SET_RAX:
1533			rax = strtoul(optarg, NULL, 0);
1534			set_rax = 1;
1535			break;
1536		case SET_RFLAGS:
1537			rflags = strtoul(optarg, NULL, 0);
1538			set_rflags = 1;
1539			break;
1540		case DESC_BASE:
1541			desc_base = strtoul(optarg, NULL, 0);
1542			break;
1543		case DESC_LIMIT:
1544			desc_limit = strtoul(optarg, NULL, 0);
1545			break;
1546		case DESC_ACCESS:
1547			desc_access = strtoul(optarg, NULL, 0);
1548			break;
1549		case SET_CS:
1550			cs = strtoul(optarg, NULL, 0);
1551			set_cs = 1;
1552			break;
1553		case SET_DS:
1554			ds = strtoul(optarg, NULL, 0);
1555			set_ds = 1;
1556			break;
1557		case SET_ES:
1558			es = strtoul(optarg, NULL, 0);
1559			set_es = 1;
1560			break;
1561		case SET_FS:
1562			fs = strtoul(optarg, NULL, 0);
1563			set_fs = 1;
1564			break;
1565		case SET_GS:
1566			gs = strtoul(optarg, NULL, 0);
1567			set_gs = 1;
1568			break;
1569		case SET_SS:
1570			ss = strtoul(optarg, NULL, 0);
1571			set_ss = 1;
1572			break;
1573		case SET_TR:
1574			tr = strtoul(optarg, NULL, 0);
1575			set_tr = 1;
1576			break;
1577		case SET_LDTR:
1578			ldtr = strtoul(optarg, NULL, 0);
1579			set_ldtr = 1;
1580			break;
1581		case SET_X2APIC_STATE:
1582			x2apic_state = strtol(optarg, NULL, 0);
1583			set_x2apic_state = 1;
1584			break;
1585		case SET_EXCEPTION_BITMAP:
1586			exception_bitmap = strtoul(optarg, NULL, 0);
1587			set_exception_bitmap = 1;
1588			break;
1589		case SET_VMCS_ENTRY_INTERRUPTION_INFO:
1590			vmcs_entry_interruption_info = strtoul(optarg, NULL, 0);
1591			set_vmcs_entry_interruption_info = 1;
1592			break;
1593		case SET_CAP:
1594			capval = strtoul(optarg, NULL, 0);
1595			setcap = 1;
1596			break;
1597		case GET_GPA_PMAP:
1598			gpa_pmap = strtoul(optarg, NULL, 0);
1599			get_gpa_pmap = 1;
1600			break;
1601		case CAPNAME:
1602			capname = optarg;
1603			break;
1604		case UNASSIGN_PPTDEV:
1605			unassign_pptdev = 1;
1606			if (sscanf(optarg, "%d/%d/%d", &bus, &slot, &func) != 3)
1607				usage(cpu_intel);
1608			break;
1609		case ASSERT_LAPIC_LVT:
1610			assert_lapic_lvt = atoi(optarg);
1611			break;
1612		default:
1613			usage(cpu_intel);
1614		}
1615	}
1616	argc -= optind;
1617	argv += optind;
1618
1619	if (vmname == NULL)
1620		usage(cpu_intel);
1621
1622	error = 0;
1623
1624	if (!error && create)
1625		error = vm_create(vmname);
1626
1627	if (!error) {
1628		ctx = vm_open(vmname);
1629		if (ctx == NULL) {
1630			printf("VM:%s is not created.\n", vmname);
1631			exit (1);
1632		}
1633	}
1634
1635	if (!error && memsize)
1636		error = vm_setup_memory(ctx, memsize, VM_MMAP_NONE);
1637
1638	if (!error && set_efer)
1639		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_EFER, efer);
1640
1641	if (!error && set_cr0)
1642		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR0, cr0);
1643
1644	if (!error && set_cr3)
1645		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR3, cr3);
1646
1647	if (!error && set_cr4)
1648		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR4, cr4);
1649
1650	if (!error && set_dr7)
1651		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR7, dr7);
1652
1653	if (!error && set_rsp)
1654		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RSP, rsp);
1655
1656	if (!error && set_rip)
1657		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, rip);
1658
1659	if (!error && set_rax)
1660		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, rax);
1661
1662	if (!error && set_rflags) {
1663		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RFLAGS,
1664					rflags);
1665	}
1666
1667	if (!error && set_desc_ds) {
1668		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_DS,
1669				    desc_base, desc_limit, desc_access);
1670	}
1671
1672	if (!error && set_desc_es) {
1673		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_ES,
1674				    desc_base, desc_limit, desc_access);
1675	}
1676
1677	if (!error && set_desc_ss) {
1678		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_SS,
1679				    desc_base, desc_limit, desc_access);
1680	}
1681
1682	if (!error && set_desc_cs) {
1683		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_CS,
1684				    desc_base, desc_limit, desc_access);
1685	}
1686
1687	if (!error && set_desc_fs) {
1688		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_FS,
1689				    desc_base, desc_limit, desc_access);
1690	}
1691
1692	if (!error && set_desc_gs) {
1693		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GS,
1694				    desc_base, desc_limit, desc_access);
1695	}
1696
1697	if (!error && set_desc_tr) {
1698		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_TR,
1699				    desc_base, desc_limit, desc_access);
1700	}
1701
1702	if (!error && set_desc_ldtr) {
1703		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_LDTR,
1704				    desc_base, desc_limit, desc_access);
1705	}
1706
1707	if (!error && set_desc_gdtr) {
1708		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GDTR,
1709				    desc_base, desc_limit, 0);
1710	}
1711
1712	if (!error && set_desc_idtr) {
1713		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_IDTR,
1714				    desc_base, desc_limit, 0);
1715	}
1716
1717	if (!error && set_cs)
1718		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CS, cs);
1719
1720	if (!error && set_ds)
1721		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DS, ds);
1722
1723	if (!error && set_es)
1724		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_ES, es);
1725
1726	if (!error && set_fs)
1727		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_FS, fs);
1728
1729	if (!error && set_gs)
1730		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_GS, gs);
1731
1732	if (!error && set_ss)
1733		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_SS, ss);
1734
1735	if (!error && set_tr)
1736		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_TR, tr);
1737
1738	if (!error && set_ldtr)
1739		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_LDTR, ldtr);
1740
1741	if (!error && set_x2apic_state)
1742		error = vm_set_x2apic_state(ctx, vcpu, x2apic_state);
1743
1744	if (!error && unassign_pptdev)
1745		error = vm_unassign_pptdev(ctx, bus, slot, func);
1746
1747	if (!error && set_exception_bitmap) {
1748		if (cpu_intel)
1749			error = vm_set_vmcs_field(ctx, vcpu,
1750						  VMCS_EXCEPTION_BITMAP,
1751						  exception_bitmap);
1752		else
1753			error = vm_set_vmcb_field(ctx, vcpu,
1754						  VMCB_OFF_EXC_INTERCEPT,
1755						  4, exception_bitmap);
1756	}
1757
1758	if (!error && cpu_intel && set_vmcs_entry_interruption_info) {
1759		error = vm_set_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,
1760					  vmcs_entry_interruption_info);
1761	}
1762
1763	if (!error && inject_nmi) {
1764		error = vm_inject_nmi(ctx, vcpu);
1765	}
1766
1767	if (!error && assert_lapic_lvt != -1) {
1768		error = vm_lapic_local_irq(ctx, vcpu, assert_lapic_lvt);
1769	}
1770
1771	if (!error && (get_lowmem || get_all)) {
1772		gpa = 0;
1773		error = vm_get_memory_seg(ctx, gpa, &len, &wired);
1774		if (error == 0)
1775			printf("lowmem\t\t0x%016lx/%ld%s\n", gpa, len,
1776			    wired ? " wired" : "");
1777	}
1778
1779	if (!error && (get_highmem || get_all)) {
1780		gpa = 4 * GB;
1781		error = vm_get_memory_seg(ctx, gpa, &len, &wired);
1782		if (error == 0)
1783			printf("highmem\t\t0x%016lx/%ld%s\n", gpa, len,
1784			    wired ? " wired" : "");
1785	}
1786
1787	if (!error)
1788		error = get_all_registers(ctx, vcpu);
1789
1790	if (!error)
1791		error = get_all_segments(ctx, vcpu);
1792
1793	if (!error) {
1794		if (cpu_intel)
1795			error = get_misc_vmcs(ctx, vcpu);
1796		else
1797			error = get_misc_vmcb(ctx, vcpu);
1798	}
1799
1800	if (!error && (get_x2apic_state || get_all)) {
1801		error = vm_get_x2apic_state(ctx, vcpu, &x2apic_state);
1802		if (error == 0)
1803			printf("x2apic_state[%d]\t%d\n", vcpu, x2apic_state);
1804	}
1805
1806	if (!error && (get_eptp || get_all)) {
1807		if (cpu_intel)
1808			error = vm_get_vmcs_field(ctx, vcpu, VMCS_EPTP, &eptp);
1809		else
1810			error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_NPT_BASE,
1811						   8, &eptp);
1812		if (error == 0)
1813			printf("%s[%d]\t\t0x%016lx\n",
1814				cpu_intel ? "eptp" : "rvi/npt", vcpu, eptp);
1815	}
1816
1817	if (!error && (get_exception_bitmap || get_all)) {
1818		if(cpu_intel)
1819			error = vm_get_vmcs_field(ctx, vcpu,
1820						VMCS_EXCEPTION_BITMAP, &bm);
1821		else
1822			error = vm_get_vmcb_field(ctx, vcpu,
1823						  VMCB_OFF_EXC_INTERCEPT,
1824						  4, &bm);
1825		if (error == 0)
1826			printf("exception_bitmap[%d]\t%#lx\n", vcpu, bm);
1827	}
1828
1829	if (!error && (get_io_bitmap || get_all)) {
1830		if (cpu_intel) {
1831			error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_A,
1832						  &bm);
1833			if (error == 0)
1834				printf("io_bitmap_a[%d]\t%#lx\n", vcpu, bm);
1835			error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_B,
1836						  &bm);
1837			if (error == 0)
1838				printf("io_bitmap_b[%d]\t%#lx\n", vcpu, bm);
1839		} else {
1840			error = vm_get_vmcb_field(ctx, vcpu,
1841						  VMCB_OFF_IO_PERM, 8, &bm);
1842			if (error == 0)
1843				printf("io_bitmap[%d]\t%#lx\n", vcpu, bm);
1844		}
1845	}
1846
1847	if (!error && (get_tsc_offset || get_all)) {
1848		uint64_t tscoff;
1849		if (cpu_intel)
1850			error = vm_get_vmcs_field(ctx, vcpu, VMCS_TSC_OFFSET,
1851						  &tscoff);
1852		else
1853			error = vm_get_vmcb_field(ctx, vcpu,
1854						  VMCB_OFF_TSC_OFFSET,
1855						  8, &tscoff);
1856		if (error == 0)
1857			printf("tsc_offset[%d]\t0x%016lx\n", vcpu, tscoff);
1858	}
1859
1860	if (!error && (get_msr_bitmap_address || get_all)) {
1861		if (cpu_intel)
1862			error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP,
1863						  &addr);
1864		else
1865			error = vm_get_vmcb_field(ctx, vcpu,
1866						  VMCB_OFF_MSR_PERM, 8, &addr);
1867		if (error == 0)
1868			printf("msr_bitmap[%d]\t\t%#lx\n", vcpu, addr);
1869	}
1870
1871	if (!error && (get_msr_bitmap || get_all)) {
1872		if (cpu_intel) {
1873			error = vm_get_vmcs_field(ctx, vcpu,
1874						  VMCS_MSR_BITMAP, &addr);
1875		} else {
1876			error = vm_get_vmcb_field(ctx, vcpu,
1877						  VMCB_OFF_MSR_PERM, 8,
1878						  &addr);
1879		}
1880
1881		if (error == 0)
1882			error = dump_msr_bitmap(vcpu, addr, cpu_intel);
1883	}
1884
1885	if (!error && (get_vpid_asid || get_all)) {
1886		uint64_t vpid;
1887		if (cpu_intel)
1888			error = vm_get_vmcs_field(ctx, vcpu, VMCS_VPID, &vpid);
1889		else
1890			error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_ASID,
1891						  4, &vpid);
1892		if (error == 0)
1893			printf("%s[%d]\t\t0x%04lx\n",
1894				cpu_intel ? "vpid" : "asid", vcpu, vpid);
1895	}
1896
1897	if (!error && (get_guest_pat || get_all)) {
1898		if (cpu_intel)
1899			error = vm_get_vmcs_field(ctx, vcpu,
1900						  VMCS_GUEST_IA32_PAT, &pat);
1901		else
1902			error = vm_get_vmcb_field(ctx, vcpu,
1903						  VMCB_OFF_GUEST_PAT, 8, &pat);
1904		if (error == 0)
1905			printf("guest_pat[%d]\t\t0x%016lx\n", vcpu, pat);
1906	}
1907
1908	if (!error && (get_guest_sysenter || get_all)) {
1909		if (cpu_intel)
1910			error = vm_get_vmcs_field(ctx, vcpu,
1911						  VMCS_GUEST_IA32_SYSENTER_CS,
1912						  &cs);
1913		else
1914			error = vm_get_vmcb_field(ctx, vcpu,
1915						  VMCB_OFF_SYSENTER_CS, 8,
1916						  &cs);
1917
1918		if (error == 0)
1919			printf("guest_sysenter_cs[%d]\t%#lx\n", vcpu, cs);
1920		if (cpu_intel)
1921			error = vm_get_vmcs_field(ctx, vcpu,
1922						  VMCS_GUEST_IA32_SYSENTER_ESP,
1923						  &rsp);
1924		else
1925			error = vm_get_vmcb_field(ctx, vcpu,
1926						  VMCB_OFF_SYSENTER_ESP, 8,
1927						  &rsp);
1928
1929		if (error == 0)
1930			printf("guest_sysenter_sp[%d]\t%#lx\n", vcpu, rsp);
1931		if (cpu_intel)
1932			error = vm_get_vmcs_field(ctx, vcpu,
1933						  VMCS_GUEST_IA32_SYSENTER_EIP,
1934						  &rip);
1935		else
1936			error = vm_get_vmcb_field(ctx, vcpu,
1937						  VMCB_OFF_SYSENTER_EIP, 8,
1938						  &rip);
1939		if (error == 0)
1940			printf("guest_sysenter_ip[%d]\t%#lx\n", vcpu, rip);
1941	}
1942
1943	if (!error && (get_exit_reason || get_all)) {
1944		if (cpu_intel)
1945			error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_REASON,
1946						  &u64);
1947		else
1948			error = vm_get_vmcb_field(ctx, vcpu,
1949						  VMCB_OFF_EXIT_REASON, 8,
1950						  &u64);
1951		if (error == 0)
1952			printf("exit_reason[%d]\t%#lx\n", vcpu, u64);
1953	}
1954
1955	if (!error && setcap) {
1956		int captype;
1957		captype = vm_capability_name2type(capname);
1958		error = vm_set_capability(ctx, vcpu, captype, capval);
1959		if (error != 0 && errno == ENOENT)
1960			printf("Capability \"%s\" is not available\n", capname);
1961	}
1962
1963	if (!error && get_gpa_pmap) {
1964		error = vm_get_gpa_pmap(ctx, gpa_pmap, pteval, &ptenum);
1965		if (error == 0) {
1966			printf("gpa %#lx:", gpa_pmap);
1967			pte = &pteval[0];
1968			while (ptenum-- > 0)
1969				printf(" %#lx", *pte++);
1970			printf("\n");
1971		}
1972	}
1973
1974	if (!error && (getcap || get_all)) {
1975		int captype, val, getcaptype;
1976
1977		if (getcap && capname)
1978			getcaptype = vm_capability_name2type(capname);
1979		else
1980			getcaptype = -1;
1981
1982		for (captype = 0; captype < VM_CAP_MAX; captype++) {
1983			if (getcaptype >= 0 && captype != getcaptype)
1984				continue;
1985			error = vm_get_capability(ctx, vcpu, captype, &val);
1986			if (error == 0) {
1987				printf("Capability \"%s\" is %s on vcpu %d\n",
1988					vm_capability_type2name(captype),
1989					val ? "set" : "not set", vcpu);
1990			} else if (errno == ENOENT) {
1991				error = 0;
1992				printf("Capability \"%s\" is not available\n",
1993					vm_capability_type2name(captype));
1994			} else {
1995				break;
1996			}
1997		}
1998	}
1999
2000	if (!error && (get_active_cpus || get_all)) {
2001		error = vm_active_cpus(ctx, &cpus);
2002		if (!error)
2003			print_cpus("active cpus", &cpus);
2004	}
2005
2006	if (!error && (get_suspended_cpus || get_all)) {
2007		error = vm_suspended_cpus(ctx, &cpus);
2008		if (!error)
2009			print_cpus("suspended cpus", &cpus);
2010	}
2011
2012	if (!error && (get_intinfo || get_all)) {
2013		error = vm_get_intinfo(ctx, vcpu, &info[0], &info[1]);
2014		if (!error) {
2015			print_intinfo("pending", info[0]);
2016			print_intinfo("current", info[1]);
2017		}
2018	}
2019
2020	if (!error && (get_stats || get_all)) {
2021		int i, num_stats;
2022		uint64_t *stats;
2023		struct timeval tv;
2024		const char *desc;
2025
2026		stats = vm_get_stats(ctx, vcpu, &tv, &num_stats);
2027		if (stats != NULL) {
2028			printf("vcpu%d stats:\n", vcpu);
2029			for (i = 0; i < num_stats; i++) {
2030				desc = vm_get_stat_desc(ctx, i);
2031				printf("%-40s\t%ld\n", desc, stats[i]);
2032			}
2033		}
2034	}
2035
2036	if (!error && run) {
2037		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip);
2038		assert(error == 0);
2039
2040		error = vm_run(ctx, vcpu, rip, &vmexit);
2041		if (error == 0)
2042			dump_vm_run_exitcode(&vmexit, vcpu);
2043		else
2044			printf("vm_run error %d\n", error);
2045	}
2046
2047	if (!error && force_reset)
2048		error = vm_suspend(ctx, VM_SUSPEND_RESET);
2049
2050	if (!error && force_poweroff)
2051		error = vm_suspend(ctx, VM_SUSPEND_POWEROFF);
2052
2053	if (error)
2054		printf("errno = %d\n", errno);
2055
2056	if (!error && destroy)
2057		vm_destroy(ctx);
2058
2059	free (opts);
2060	exit(error);
2061}
2062