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