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