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