xref: /illumos-gate/usr/src/cmd/bhyvectl/bhyvectl.c (revision 3d097f7d)
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 #ifdef __FreeBSD__
690 static void
691 print_intinfo(const char *banner, uint64_t info)
692 {
693 	int type;
694 
695 	printf("%s:\t", banner);
696 	if (info & VM_INTINFO_VALID) {
697 		type = info & VM_INTINFO_TYPE;
698 		switch (type) {
699 		case VM_INTINFO_HWINTR:
700 			printf("extint");
701 			break;
702 		case VM_INTINFO_NMI:
703 			printf("nmi");
704 			break;
705 		case VM_INTINFO_SWINTR:
706 			printf("swint");
707 			break;
708 		default:
709 			printf("exception");
710 			break;
711 		}
712 		printf(" vector %d", (int)VM_INTINFO_VECTOR(info));
713 		if (info & VM_INTINFO_DEL_ERRCODE)
714 			printf(" errcode %#x", (u_int)(info >> 32));
715 	} else {
716 		printf("n/a");
717 	}
718 	printf("\n");
719 }
720 #else /* __FreeBSD__ */
721 static void
722 print_intinfo(const char *banner, uint64_t info)
723 {
724 	printf("%s:\t", banner);
725 	if (VM_INTINFO_PENDING(info)) {
726 		switch (VM_INTINFO_TYPE(info)) {
727 		case VM_INTINFO_HWINTR:
728 			printf("extint");
729 			break;
730 		case VM_INTINFO_NMI:
731 			printf("nmi");
732 			break;
733 		case VM_INTINFO_SWINTR:
734 			printf("swint");
735 			break;
736 		default:
737 			printf("exception");
738 			break;
739 		}
740 		printf(" vector %hhd", VM_INTINFO_VECTOR(info));
741 		if (VM_INTINFO_HAS_ERRCODE(info)) {
742 			printf(" errcode %#x", VM_INTINFO_ERRCODE(info));
743 		}
744 	} else {
745 		printf("n/a");
746 	}
747 	printf("\n");
748 }
749 #endif /* __FreeBSD__ */
750 
751 static bool
752 cpu_vendor_intel(void)
753 {
754 	u_int regs[4];
755 	char cpu_vendor[13];
756 
757 	do_cpuid(0, regs);
758 	((u_int *)&cpu_vendor)[0] = regs[1];
759 	((u_int *)&cpu_vendor)[1] = regs[3];
760 	((u_int *)&cpu_vendor)[2] = regs[2];
761 	cpu_vendor[12] = '\0';
762 
763 	if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
764 		return (false);
765 	} else if (strcmp(cpu_vendor, "HygonGenuine") == 0) {
766 		return (false);
767 	} else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
768 		return (true);
769 	} else {
770 		fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor);
771 		exit(1);
772 	}
773 }
774 
775 static int
776 get_all_registers(struct vmctx *ctx, int vcpu)
777 {
778 	uint64_t cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7;
779 	uint64_t rsp, rip, rflags, efer;
780 	uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp;
781 	uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
782 	int error = 0;
783 
784 	if (!error && (get_efer || get_all)) {
785 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_EFER, &efer);
786 		if (error == 0)
787 			printf("efer[%d]\t\t0x%016lx\n", vcpu, efer);
788 	}
789 
790 	if (!error && (get_cr0 || get_all)) {
791 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR0, &cr0);
792 		if (error == 0)
793 			printf("cr0[%d]\t\t0x%016lx\n", vcpu, cr0);
794 	}
795 
796 	if (!error && (get_cr2 || get_all)) {
797 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR2, &cr2);
798 		if (error == 0)
799 			printf("cr2[%d]\t\t0x%016lx\n", vcpu, cr2);
800 	}
801 
802 	if (!error && (get_cr3 || get_all)) {
803 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR3, &cr3);
804 		if (error == 0)
805 			printf("cr3[%d]\t\t0x%016lx\n", vcpu, cr3);
806 	}
807 
808 	if (!error && (get_cr4 || get_all)) {
809 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR4, &cr4);
810 		if (error == 0)
811 			printf("cr4[%d]\t\t0x%016lx\n", vcpu, cr4);
812 	}
813 
814 	if (!error && (get_dr0 || get_all)) {
815 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR0, &dr0);
816 		if (error == 0)
817 			printf("dr0[%d]\t\t0x%016lx\n", vcpu, dr0);
818 	}
819 
820 	if (!error && (get_dr1 || get_all)) {
821 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR1, &dr1);
822 		if (error == 0)
823 			printf("dr1[%d]\t\t0x%016lx\n", vcpu, dr1);
824 	}
825 
826 	if (!error && (get_dr2 || get_all)) {
827 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR2, &dr2);
828 		if (error == 0)
829 			printf("dr2[%d]\t\t0x%016lx\n", vcpu, dr2);
830 	}
831 
832 	if (!error && (get_dr3 || get_all)) {
833 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR3, &dr3);
834 		if (error == 0)
835 			printf("dr3[%d]\t\t0x%016lx\n", vcpu, dr3);
836 	}
837 
838 	if (!error && (get_dr6 || get_all)) {
839 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR6, &dr6);
840 		if (error == 0)
841 			printf("dr6[%d]\t\t0x%016lx\n", vcpu, dr6);
842 	}
843 
844 	if (!error && (get_dr7 || get_all)) {
845 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR7, &dr7);
846 		if (error == 0)
847 			printf("dr7[%d]\t\t0x%016lx\n", vcpu, dr7);
848 	}
849 
850 	if (!error && (get_rsp || get_all)) {
851 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSP, &rsp);
852 		if (error == 0)
853 			printf("rsp[%d]\t\t0x%016lx\n", vcpu, rsp);
854 	}
855 
856 	if (!error && (get_rip || get_all)) {
857 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip);
858 		if (error == 0)
859 			printf("rip[%d]\t\t0x%016lx\n", vcpu, rip);
860 	}
861 
862 	if (!error && (get_rax || get_all)) {
863 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &rax);
864 		if (error == 0)
865 			printf("rax[%d]\t\t0x%016lx\n", vcpu, rax);
866 	}
867 
868 	if (!error && (get_rbx || get_all)) {
869 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBX, &rbx);
870 		if (error == 0)
871 			printf("rbx[%d]\t\t0x%016lx\n", vcpu, rbx);
872 	}
873 
874 	if (!error && (get_rcx || get_all)) {
875 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RCX, &rcx);
876 		if (error == 0)
877 			printf("rcx[%d]\t\t0x%016lx\n", vcpu, rcx);
878 	}
879 
880 	if (!error && (get_rdx || get_all)) {
881 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDX, &rdx);
882 		if (error == 0)
883 			printf("rdx[%d]\t\t0x%016lx\n", vcpu, rdx);
884 	}
885 
886 	if (!error && (get_rsi || get_all)) {
887 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSI, &rsi);
888 		if (error == 0)
889 			printf("rsi[%d]\t\t0x%016lx\n", vcpu, rsi);
890 	}
891 
892 	if (!error && (get_rdi || get_all)) {
893 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDI, &rdi);
894 		if (error == 0)
895 			printf("rdi[%d]\t\t0x%016lx\n", vcpu, rdi);
896 	}
897 
898 	if (!error && (get_rbp || get_all)) {
899 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBP, &rbp);
900 		if (error == 0)
901 			printf("rbp[%d]\t\t0x%016lx\n", vcpu, rbp);
902 	}
903 
904 	if (!error && (get_r8 || get_all)) {
905 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R8, &r8);
906 		if (error == 0)
907 			printf("r8[%d]\t\t0x%016lx\n", vcpu, r8);
908 	}
909 
910 	if (!error && (get_r9 || get_all)) {
911 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R9, &r9);
912 		if (error == 0)
913 			printf("r9[%d]\t\t0x%016lx\n", vcpu, r9);
914 	}
915 
916 	if (!error && (get_r10 || get_all)) {
917 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R10, &r10);
918 		if (error == 0)
919 			printf("r10[%d]\t\t0x%016lx\n", vcpu, r10);
920 	}
921 
922 	if (!error && (get_r11 || get_all)) {
923 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R11, &r11);
924 		if (error == 0)
925 			printf("r11[%d]\t\t0x%016lx\n", vcpu, r11);
926 	}
927 
928 	if (!error && (get_r12 || get_all)) {
929 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R12, &r12);
930 		if (error == 0)
931 			printf("r12[%d]\t\t0x%016lx\n", vcpu, r12);
932 	}
933 
934 	if (!error && (get_r13 || get_all)) {
935 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R13, &r13);
936 		if (error == 0)
937 			printf("r13[%d]\t\t0x%016lx\n", vcpu, r13);
938 	}
939 
940 	if (!error && (get_r14 || get_all)) {
941 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R14, &r14);
942 		if (error == 0)
943 			printf("r14[%d]\t\t0x%016lx\n", vcpu, r14);
944 	}
945 
946 	if (!error && (get_r15 || get_all)) {
947 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R15, &r15);
948 		if (error == 0)
949 			printf("r15[%d]\t\t0x%016lx\n", vcpu, r15);
950 	}
951 
952 	if (!error && (get_rflags || get_all)) {
953 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RFLAGS,
954 					&rflags);
955 		if (error == 0)
956 			printf("rflags[%d]\t0x%016lx\n", vcpu, rflags);
957 	}
958 
959 	return (error);
960 }
961 
962 static int
963 get_all_segments(struct vmctx *ctx, int vcpu)
964 {
965 	uint64_t cs, ds, es, fs, gs, ss, tr, ldtr;
966 	int error = 0;
967 
968 	if (!error && (get_desc_ds || get_all)) {
969 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_DS,
970 				   &desc_base, &desc_limit, &desc_access);
971 		if (error == 0) {
972 			printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
973 			      vcpu, desc_base, desc_limit, desc_access);
974 		}
975 	}
976 
977 	if (!error && (get_desc_es || get_all)) {
978 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_ES,
979 				    &desc_base, &desc_limit, &desc_access);
980 		if (error == 0) {
981 			printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
982 			       vcpu, desc_base, desc_limit, desc_access);
983 		}
984 	}
985 
986 	if (!error && (get_desc_fs || get_all)) {
987 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_FS,
988 				    &desc_base, &desc_limit, &desc_access);
989 		if (error == 0) {
990 			printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
991 			       vcpu, desc_base, desc_limit, desc_access);
992 		}
993 	}
994 
995 	if (!error && (get_desc_gs || get_all)) {
996 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GS,
997 				    &desc_base, &desc_limit, &desc_access);
998 		if (error == 0) {
999 			printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1000 			       vcpu, desc_base, desc_limit, desc_access);
1001 		}
1002 	}
1003 
1004 	if (!error && (get_desc_ss || get_all)) {
1005 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_SS,
1006 				    &desc_base, &desc_limit, &desc_access);
1007 		if (error == 0) {
1008 			printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1009 			       vcpu, desc_base, desc_limit, desc_access);
1010 		}
1011 	}
1012 
1013 	if (!error && (get_desc_cs || get_all)) {
1014 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_CS,
1015 				    &desc_base, &desc_limit, &desc_access);
1016 		if (error == 0) {
1017 			printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1018 			       vcpu, desc_base, desc_limit, desc_access);
1019 		}
1020 	}
1021 
1022 	if (!error && (get_desc_tr || get_all)) {
1023 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_TR,
1024 				    &desc_base, &desc_limit, &desc_access);
1025 		if (error == 0) {
1026 			printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1027 			       vcpu, desc_base, desc_limit, desc_access);
1028 		}
1029 	}
1030 
1031 	if (!error && (get_desc_ldtr || get_all)) {
1032 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_LDTR,
1033 				    &desc_base, &desc_limit, &desc_access);
1034 		if (error == 0) {
1035 			printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
1036 			       vcpu, desc_base, desc_limit, desc_access);
1037 		}
1038 	}
1039 
1040 	if (!error && (get_desc_gdtr || get_all)) {
1041 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GDTR,
1042 				    &desc_base, &desc_limit, &desc_access);
1043 		if (error == 0) {
1044 			printf("gdtr[%d]\t\t0x%016lx/0x%08x\n",
1045 			       vcpu, desc_base, desc_limit);
1046 		}
1047 	}
1048 
1049 	if (!error && (get_desc_idtr || get_all)) {
1050 		error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_IDTR,
1051 				    &desc_base, &desc_limit, &desc_access);
1052 		if (error == 0) {
1053 			printf("idtr[%d]\t\t0x%016lx/0x%08x\n",
1054 			       vcpu, desc_base, desc_limit);
1055 		}
1056 	}
1057 
1058 	if (!error && (get_cs || get_all)) {
1059 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CS, &cs);
1060 		if (error == 0)
1061 			printf("cs[%d]\t\t0x%04lx\n", vcpu, cs);
1062 	}
1063 
1064 	if (!error && (get_ds || get_all)) {
1065 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DS, &ds);
1066 		if (error == 0)
1067 			printf("ds[%d]\t\t0x%04lx\n", vcpu, ds);
1068 	}
1069 
1070 	if (!error && (get_es || get_all)) {
1071 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_ES, &es);
1072 		if (error == 0)
1073 			printf("es[%d]\t\t0x%04lx\n", vcpu, es);
1074 	}
1075 
1076 	if (!error && (get_fs || get_all)) {
1077 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_FS, &fs);
1078 		if (error == 0)
1079 			printf("fs[%d]\t\t0x%04lx\n", vcpu, fs);
1080 	}
1081 
1082 	if (!error && (get_gs || get_all)) {
1083 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_GS, &gs);
1084 		if (error == 0)
1085 			printf("gs[%d]\t\t0x%04lx\n", vcpu, gs);
1086 	}
1087 
1088 	if (!error && (get_ss || get_all)) {
1089 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_SS, &ss);
1090 		if (error == 0)
1091 			printf("ss[%d]\t\t0x%04lx\n", vcpu, ss);
1092 	}
1093 
1094 	if (!error && (get_tr || get_all)) {
1095 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_TR, &tr);
1096 		if (error == 0)
1097 			printf("tr[%d]\t\t0x%04lx\n", vcpu, tr);
1098 	}
1099 
1100 	if (!error && (get_ldtr || get_all)) {
1101 		error = vm_get_register(ctx, vcpu, VM_REG_GUEST_LDTR, &ldtr);
1102 		if (error == 0)
1103 			printf("ldtr[%d]\t\t0x%04lx\n", vcpu, ldtr);
1104 	}
1105 
1106 	return (error);
1107 }
1108 
1109 static int
1110 get_misc_vmcs(struct vmctx *ctx, int vcpu)
1111 {
1112 	uint64_t ctl, cr0, cr3, cr4, rsp, rip, pat, addr, u64;
1113 	int error = 0;
1114 
1115 	if (!error && (get_cr0_mask || get_all)) {
1116 		uint64_t cr0mask;
1117 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_MASK, &cr0mask);
1118 		if (error == 0)
1119 			printf("cr0_mask[%d]\t\t0x%016lx\n", vcpu, cr0mask);
1120 	}
1121 
1122 	if (!error && (get_cr0_shadow || get_all)) {
1123 		uint64_t cr0shadow;
1124 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_SHADOW,
1125 					  &cr0shadow);
1126 		if (error == 0)
1127 			printf("cr0_shadow[%d]\t\t0x%016lx\n", vcpu, cr0shadow);
1128 	}
1129 
1130 	if (!error && (get_cr4_mask || get_all)) {
1131 		uint64_t cr4mask;
1132 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_MASK, &cr4mask);
1133 		if (error == 0)
1134 			printf("cr4_mask[%d]\t\t0x%016lx\n", vcpu, cr4mask);
1135 	}
1136 
1137 	if (!error && (get_cr4_shadow || get_all)) {
1138 		uint64_t cr4shadow;
1139 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_SHADOW,
1140 					  &cr4shadow);
1141 		if (error == 0)
1142 			printf("cr4_shadow[%d]\t\t0x%016lx\n", vcpu, cr4shadow);
1143 	}
1144 
1145 	if (!error && (get_cr3_targets || get_all)) {
1146 		uint64_t target_count, target_addr;
1147 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET_COUNT,
1148 					  &target_count);
1149 		if (error == 0) {
1150 			printf("cr3_target_count[%d]\t0x%016lx\n",
1151 				vcpu, target_count);
1152 		}
1153 
1154 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET0,
1155 					  &target_addr);
1156 		if (error == 0) {
1157 			printf("cr3_target0[%d]\t\t0x%016lx\n",
1158 				vcpu, target_addr);
1159 		}
1160 
1161 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET1,
1162 					  &target_addr);
1163 		if (error == 0) {
1164 			printf("cr3_target1[%d]\t\t0x%016lx\n",
1165 				vcpu, target_addr);
1166 		}
1167 
1168 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET2,
1169 					  &target_addr);
1170 		if (error == 0) {
1171 			printf("cr3_target2[%d]\t\t0x%016lx\n",
1172 				vcpu, target_addr);
1173 		}
1174 
1175 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET3,
1176 					  &target_addr);
1177 		if (error == 0) {
1178 			printf("cr3_target3[%d]\t\t0x%016lx\n",
1179 				vcpu, target_addr);
1180 		}
1181 	}
1182 
1183 	if (!error && (get_pinbased_ctls || get_all)) {
1184 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_PIN_BASED_CTLS, &ctl);
1185 		if (error == 0)
1186 			printf("pinbased_ctls[%d]\t0x%016lx\n", vcpu, ctl);
1187 	}
1188 
1189 	if (!error && (get_procbased_ctls || get_all)) {
1190 		error = vm_get_vmcs_field(ctx, vcpu,
1191 					  VMCS_PRI_PROC_BASED_CTLS, &ctl);
1192 		if (error == 0)
1193 			printf("procbased_ctls[%d]\t0x%016lx\n", vcpu, ctl);
1194 	}
1195 
1196 	if (!error && (get_procbased_ctls2 || get_all)) {
1197 		error = vm_get_vmcs_field(ctx, vcpu,
1198 					  VMCS_SEC_PROC_BASED_CTLS, &ctl);
1199 		if (error == 0)
1200 			printf("procbased_ctls2[%d]\t0x%016lx\n", vcpu, ctl);
1201 	}
1202 
1203 	if (!error && (get_vmcs_gla || get_all)) {
1204 		error = vm_get_vmcs_field(ctx, vcpu,
1205 					  VMCS_GUEST_LINEAR_ADDRESS, &u64);
1206 		if (error == 0)
1207 			printf("gla[%d]\t\t0x%016lx\n", vcpu, u64);
1208 	}
1209 
1210 	if (!error && (get_vmcs_gpa || get_all)) {
1211 		error = vm_get_vmcs_field(ctx, vcpu,
1212 					  VMCS_GUEST_PHYSICAL_ADDRESS, &u64);
1213 		if (error == 0)
1214 			printf("gpa[%d]\t\t0x%016lx\n", vcpu, u64);
1215 	}
1216 
1217 	if (!error && (get_vmcs_entry_interruption_info ||
1218 		get_all)) {
1219 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,&u64);
1220 		if (error == 0) {
1221 			printf("entry_interruption_info[%d]\t0x%016lx\n",
1222 				vcpu, u64);
1223 		}
1224 	}
1225 
1226 	if (!error && (get_tpr_threshold || get_all)) {
1227 		uint64_t threshold;
1228 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_TPR_THRESHOLD,
1229 					  &threshold);
1230 		if (error == 0)
1231 			printf("tpr_threshold[%d]\t0x%016lx\n", vcpu, threshold);
1232 	}
1233 
1234 	if (!error && (get_inst_err || get_all)) {
1235 		uint64_t insterr;
1236 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_INSTRUCTION_ERROR,
1237 					  &insterr);
1238 		if (error == 0) {
1239 			printf("instruction_error[%d]\t0x%016lx\n",
1240 				vcpu, insterr);
1241 		}
1242 	}
1243 
1244 	if (!error && (get_exit_ctls || get_all)) {
1245 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_CTLS, &ctl);
1246 		if (error == 0)
1247 			printf("exit_ctls[%d]\t\t0x%016lx\n", vcpu, ctl);
1248 	}
1249 
1250 	if (!error && (get_entry_ctls || get_all)) {
1251 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_CTLS, &ctl);
1252 		if (error == 0)
1253 			printf("entry_ctls[%d]\t\t0x%016lx\n", vcpu, ctl);
1254 	}
1255 
1256 	if (!error && (get_host_pat || get_all)) {
1257 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_IA32_PAT, &pat);
1258 		if (error == 0)
1259 			printf("host_pat[%d]\t\t0x%016lx\n", vcpu, pat);
1260 	}
1261 
1262 	if (!error && (get_host_cr0 || get_all)) {
1263 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR0, &cr0);
1264 		if (error == 0)
1265 			printf("host_cr0[%d]\t\t0x%016lx\n", vcpu, cr0);
1266 	}
1267 
1268 	if (!error && (get_host_cr3 || get_all)) {
1269 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR3, &cr3);
1270 		if (error == 0)
1271 			printf("host_cr3[%d]\t\t0x%016lx\n", vcpu, cr3);
1272 	}
1273 
1274 	if (!error && (get_host_cr4 || get_all)) {
1275 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR4, &cr4);
1276 		if (error == 0)
1277 			printf("host_cr4[%d]\t\t0x%016lx\n", vcpu, cr4);
1278 	}
1279 
1280 	if (!error && (get_host_rip || get_all)) {
1281 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RIP, &rip);
1282 		if (error == 0)
1283 			printf("host_rip[%d]\t\t0x%016lx\n", vcpu, rip);
1284 	}
1285 
1286 	if (!error && (get_host_rsp || get_all)) {
1287 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RSP, &rsp);
1288 		if (error == 0)
1289 			printf("host_rsp[%d]\t\t0x%016lx\n", vcpu, rsp);
1290 	}
1291 
1292 	if (!error && (get_vmcs_link || get_all)) {
1293 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_LINK_POINTER, &addr);
1294 		if (error == 0)
1295 			printf("vmcs_pointer[%d]\t0x%016lx\n", vcpu, addr);
1296 	}
1297 
1298 	if (!error && (get_vmcs_exit_interruption_info || get_all)) {
1299 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_INFO, &u64);
1300 		if (error == 0) {
1301 			printf("vmcs_exit_interruption_info[%d]\t0x%016lx\n",
1302 				vcpu, u64);
1303 		}
1304 	}
1305 
1306 	if (!error && (get_vmcs_exit_interruption_error || get_all)) {
1307 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_ERRCODE,
1308 		    			  &u64);
1309 		if (error == 0) {
1310 			printf("vmcs_exit_interruption_error[%d]\t0x%016lx\n",
1311 				vcpu, u64);
1312 		}
1313 	}
1314 
1315 	if (!error && (get_vmcs_interruptibility || get_all)) {
1316 		error = vm_get_vmcs_field(ctx, vcpu,
1317 					  VMCS_GUEST_INTERRUPTIBILITY, &u64);
1318 		if (error == 0) {
1319 			printf("vmcs_guest_interruptibility[%d]\t0x%016lx\n",
1320 				vcpu, u64);
1321 		}
1322 	}
1323 
1324 	if (!error && (get_vmcs_exit_inst_length || get_all)) {
1325 		error = vm_get_vmcs_field(ctx, vcpu,
1326 		    VMCS_EXIT_INSTRUCTION_LENGTH, &u64);
1327 		if (error == 0)
1328 			printf("vmcs_exit_inst_length[%d]\t0x%08x\n", vcpu,
1329 			    (uint32_t)u64);
1330 	}
1331 
1332 	if (!error && (get_vmcs_exit_qualification || get_all)) {
1333 		error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_QUALIFICATION,
1334 					  &u64);
1335 		if (error == 0)
1336 			printf("vmcs_exit_qualification[%d]\t0x%016lx\n",
1337 				vcpu, u64);
1338 	}
1339 
1340 	return (error);
1341 }
1342 
1343 static int
1344 get_misc_vmcb(struct vmctx *ctx, int vcpu)
1345 {
1346 	uint64_t ctl, addr;
1347 	int error = 0;
1348 
1349 	if (!error && (get_vmcb_intercept || get_all)) {
1350 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_CR_INTERCEPT, 4,
1351 		    &ctl);
1352 		if (error == 0)
1353 			printf("cr_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1354 
1355 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_DR_INTERCEPT, 4,
1356 		    &ctl);
1357 		if (error == 0)
1358 			printf("dr_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1359 
1360 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXC_INTERCEPT, 4,
1361 		    &ctl);
1362 		if (error == 0)
1363 			printf("exc_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1364 
1365 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_INST1_INTERCEPT,
1366 		    4, &ctl);
1367 		if (error == 0)
1368 			printf("inst1_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1369 
1370 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_INST2_INTERCEPT,
1371 		    4, &ctl);
1372 		if (error == 0)
1373 			printf("inst2_intercept[%d]\t0x%08x\n", vcpu, (int)ctl);
1374 	}
1375 
1376 	if (!error && (get_vmcb_tlb_ctrl || get_all)) {
1377 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_TLB_CTRL,
1378 					  4, &ctl);
1379 		if (error == 0)
1380 			printf("TLB ctrl[%d]\t0x%016lx\n", vcpu, ctl);
1381 	}
1382 
1383 	if (!error && (get_vmcb_exit_details || get_all)) {
1384 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINFO1,
1385 					  8, &ctl);
1386 		if (error == 0)
1387 			printf("exitinfo1[%d]\t0x%016lx\n", vcpu, ctl);
1388 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINFO2,
1389 					  8, &ctl);
1390 		if (error == 0)
1391 			printf("exitinfo2[%d]\t0x%016lx\n", vcpu, ctl);
1392 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINTINFO,
1393 					  8, &ctl);
1394 		if (error == 0)
1395 			printf("exitintinfo[%d]\t0x%016lx\n", vcpu, ctl);
1396 	}
1397 
1398 	if (!error && (get_vmcb_virq || get_all)) {
1399 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_VIRQ,
1400 					  8, &ctl);
1401 		if (error == 0)
1402 			printf("v_irq/tpr[%d]\t0x%016lx\n", vcpu, ctl);
1403 	}
1404 
1405 	if (!error && (get_apic_access_addr || get_all)) {
1406 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_BAR, 8,
1407 					  &addr);
1408 		if (error == 0)
1409 			printf("AVIC apic_bar[%d]\t0x%016lx\n", vcpu, addr);
1410 	}
1411 
1412 	if (!error && (get_virtual_apic_addr || get_all)) {
1413 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_PAGE, 8,
1414 					  &addr);
1415 		if (error == 0)
1416 			printf("AVIC backing page[%d]\t0x%016lx\n", vcpu, addr);
1417 	}
1418 
1419 	if (!error && (get_avic_table || get_all)) {
1420 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_LT, 8,
1421 					  &addr);
1422 		if (error == 0)
1423 			printf("AVIC logical table[%d]\t0x%016lx\n",
1424 				vcpu, addr);
1425 		error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_PT, 8,
1426 					  &addr);
1427 		if (error == 0)
1428 			printf("AVIC physical table[%d]\t0x%016lx\n",
1429 				vcpu, addr);
1430 	}
1431 
1432 	return (error);
1433 }
1434 
1435 static struct option *
1436 setup_options(bool cpu_intel)
1437 {
1438 	const struct option common_opts[] = {
1439 		{ "vm",		REQ_ARG,	0,	VMNAME },
1440 		{ "cpu",	REQ_ARG,	0,	VCPU },
1441 		{ "set-mem",	REQ_ARG,	0,	SET_MEM },
1442 		{ "set-efer",	REQ_ARG,	0,	SET_EFER },
1443 		{ "set-cr0",	REQ_ARG,	0,	SET_CR0 },
1444 		{ "set-cr2",	REQ_ARG,	0,	SET_CR2 },
1445 		{ "set-cr3",	REQ_ARG,	0,	SET_CR3 },
1446 		{ "set-cr4",	REQ_ARG,	0,	SET_CR4 },
1447 		{ "set-dr0",	REQ_ARG,	0,	SET_DR0 },
1448 		{ "set-dr1",	REQ_ARG,	0,	SET_DR1 },
1449 		{ "set-dr2",	REQ_ARG,	0,	SET_DR2 },
1450 		{ "set-dr3",	REQ_ARG,	0,	SET_DR3 },
1451 		{ "set-dr6",	REQ_ARG,	0,	SET_DR6 },
1452 		{ "set-dr7",	REQ_ARG,	0,	SET_DR7 },
1453 		{ "set-rsp",	REQ_ARG,	0,	SET_RSP },
1454 		{ "set-rip",	REQ_ARG,	0,	SET_RIP },
1455 		{ "set-rax",	REQ_ARG,	0,	SET_RAX },
1456 		{ "set-rflags",	REQ_ARG,	0,	SET_RFLAGS },
1457 		{ "desc-base",	REQ_ARG,	0,	DESC_BASE },
1458 		{ "desc-limit",	REQ_ARG,	0,	DESC_LIMIT },
1459 		{ "desc-access",REQ_ARG,	0,	DESC_ACCESS },
1460 		{ "set-cs",	REQ_ARG,	0,	SET_CS },
1461 		{ "set-ds",	REQ_ARG,	0,	SET_DS },
1462 		{ "set-es",	REQ_ARG,	0,	SET_ES },
1463 		{ "set-fs",	REQ_ARG,	0,	SET_FS },
1464 		{ "set-gs",	REQ_ARG,	0,	SET_GS },
1465 		{ "set-ss",	REQ_ARG,	0,	SET_SS },
1466 		{ "set-tr",	REQ_ARG,	0,	SET_TR },
1467 		{ "set-ldtr",	REQ_ARG,	0,	SET_LDTR },
1468 		{ "set-x2apic-state",REQ_ARG,	0,	SET_X2APIC_STATE },
1469 		{ "set-exception-bitmap",
1470 				REQ_ARG,	0, SET_EXCEPTION_BITMAP },
1471 		{ "capname",	REQ_ARG,	0,	CAPNAME },
1472 		{ "unassign-pptdev", REQ_ARG,	0,	UNASSIGN_PPTDEV },
1473 		{ "setcap",	REQ_ARG,	0,	SET_CAP },
1474 		{ "get-gpa-pmap", REQ_ARG,	0,	GET_GPA_PMAP },
1475 		{ "assert-lapic-lvt", REQ_ARG,	0,	ASSERT_LAPIC_LVT },
1476 		{ "get-rtc-time", NO_ARG,	&get_rtc_time,	1 },
1477 		{ "set-rtc-time", REQ_ARG,	0,	SET_RTC_TIME },
1478 		{ "rtc-nvram-offset", REQ_ARG,	0,	RTC_NVRAM_OFFSET },
1479 		{ "get-rtc-nvram", NO_ARG,	&get_rtc_nvram,	1 },
1480 		{ "set-rtc-nvram", REQ_ARG,	0,	SET_RTC_NVRAM },
1481 		{ "getcap",	NO_ARG,		&getcap,	1 },
1482 		{ "get-stats",	NO_ARG,		&get_stats,	1 },
1483 		{ "get-desc-ds",NO_ARG,		&get_desc_ds,	1 },
1484 		{ "set-desc-ds",NO_ARG,		&set_desc_ds,	1 },
1485 		{ "get-desc-es",NO_ARG,		&get_desc_es,	1 },
1486 		{ "set-desc-es",NO_ARG,		&set_desc_es,	1 },
1487 		{ "get-desc-ss",NO_ARG,		&get_desc_ss,	1 },
1488 		{ "set-desc-ss",NO_ARG,		&set_desc_ss,	1 },
1489 		{ "get-desc-cs",NO_ARG,		&get_desc_cs,	1 },
1490 		{ "set-desc-cs",NO_ARG,		&set_desc_cs,	1 },
1491 		{ "get-desc-fs",NO_ARG,		&get_desc_fs,	1 },
1492 		{ "set-desc-fs",NO_ARG,		&set_desc_fs,	1 },
1493 		{ "get-desc-gs",NO_ARG,		&get_desc_gs,	1 },
1494 		{ "set-desc-gs",NO_ARG,		&set_desc_gs,	1 },
1495 		{ "get-desc-tr",NO_ARG,		&get_desc_tr,	1 },
1496 		{ "set-desc-tr",NO_ARG,		&set_desc_tr,	1 },
1497 		{ "set-desc-ldtr", NO_ARG,	&set_desc_ldtr,	1 },
1498 		{ "get-desc-ldtr", NO_ARG,	&get_desc_ldtr,	1 },
1499 		{ "set-desc-gdtr", NO_ARG,	&set_desc_gdtr, 1 },
1500 		{ "get-desc-gdtr", NO_ARG,	&get_desc_gdtr, 1 },
1501 		{ "set-desc-idtr", NO_ARG,	&set_desc_idtr, 1 },
1502 		{ "get-desc-idtr", NO_ARG,	&get_desc_idtr, 1 },
1503 		{ "get-memmap",	NO_ARG,		&get_memmap,	1 },
1504 		{ "get-memseg", NO_ARG,		&get_memseg,	1 },
1505 		{ "get-efer",	NO_ARG,		&get_efer,	1 },
1506 		{ "get-cr0",	NO_ARG,		&get_cr0,	1 },
1507 		{ "get-cr2",	NO_ARG,		&get_cr2,	1 },
1508 		{ "get-cr3",	NO_ARG,		&get_cr3,	1 },
1509 		{ "get-cr4",	NO_ARG,		&get_cr4,	1 },
1510 		{ "get-dr0",	NO_ARG,		&get_dr0,	1 },
1511 		{ "get-dr1",	NO_ARG,		&get_dr1,	1 },
1512 		{ "get-dr2",	NO_ARG,		&get_dr2,	1 },
1513 		{ "get-dr3",	NO_ARG,		&get_dr3,	1 },
1514 		{ "get-dr6",	NO_ARG,		&get_dr6,	1 },
1515 		{ "get-dr7",	NO_ARG,		&get_dr7,	1 },
1516 		{ "get-rsp",	NO_ARG,		&get_rsp,	1 },
1517 		{ "get-rip",	NO_ARG,		&get_rip,	1 },
1518 		{ "get-rax",	NO_ARG,		&get_rax,	1 },
1519 		{ "get-rbx",	NO_ARG,		&get_rbx,	1 },
1520 		{ "get-rcx",	NO_ARG,		&get_rcx,	1 },
1521 		{ "get-rdx",	NO_ARG,		&get_rdx,	1 },
1522 		{ "get-rsi",	NO_ARG,		&get_rsi,	1 },
1523 		{ "get-rdi",	NO_ARG,		&get_rdi,	1 },
1524 		{ "get-rbp",	NO_ARG,		&get_rbp,	1 },
1525 		{ "get-r8",	NO_ARG,		&get_r8,	1 },
1526 		{ "get-r9",	NO_ARG,		&get_r9,	1 },
1527 		{ "get-r10",	NO_ARG,		&get_r10,	1 },
1528 		{ "get-r11",	NO_ARG,		&get_r11,	1 },
1529 		{ "get-r12",	NO_ARG,		&get_r12,	1 },
1530 		{ "get-r13",	NO_ARG,		&get_r13,	1 },
1531 		{ "get-r14",	NO_ARG,		&get_r14,	1 },
1532 		{ "get-r15",	NO_ARG,		&get_r15,	1 },
1533 		{ "get-rflags",	NO_ARG,		&get_rflags,	1 },
1534 		{ "get-cs",	NO_ARG,		&get_cs,	1 },
1535 		{ "get-ds",	NO_ARG,		&get_ds,	1 },
1536 		{ "get-es",	NO_ARG,		&get_es,	1 },
1537 		{ "get-fs",	NO_ARG,		&get_fs,	1 },
1538 		{ "get-gs",	NO_ARG,		&get_gs,	1 },
1539 		{ "get-ss",	NO_ARG,		&get_ss,	1 },
1540 		{ "get-tr",	NO_ARG,		&get_tr,	1 },
1541 		{ "get-ldtr",	NO_ARG,		&get_ldtr,	1 },
1542 		{ "get-eptp", 	NO_ARG,		&get_eptp,	1 },
1543 		{ "get-exception-bitmap",
1544 					NO_ARG,	&get_exception_bitmap,  1 },
1545 		{ "get-io-bitmap-address",
1546 					NO_ARG,	&get_io_bitmap,		1 },
1547 		{ "get-tsc-offset", 	NO_ARG, &get_tsc_offset, 	1 },
1548 		{ "get-msr-bitmap",
1549 					NO_ARG,	&get_msr_bitmap, 	1 },
1550 		{ "get-msr-bitmap-address",
1551 					NO_ARG,	&get_msr_bitmap_address, 1 },
1552 		{ "get-guest-pat",	NO_ARG,	&get_guest_pat,		1 },
1553 		{ "get-guest-sysenter",
1554 					NO_ARG,	&get_guest_sysenter, 	1 },
1555 		{ "get-exit-reason",
1556 					NO_ARG,	&get_exit_reason, 	1 },
1557 		{ "get-x2apic-state",	NO_ARG,	&get_x2apic_state, 	1 },
1558 		{ "get-all",		NO_ARG,	&get_all,		1 },
1559 		{ "run",		NO_ARG,	&run,			1 },
1560 		{ "create",		NO_ARG,	&create,		1 },
1561 		{ "destroy",		NO_ARG,	&destroy,		1 },
1562 		{ "inject-nmi",		NO_ARG,	&inject_nmi,		1 },
1563 		{ "force-reset",	NO_ARG,	&force_reset,		1 },
1564 		{ "force-poweroff", 	NO_ARG,	&force_poweroff, 	1 },
1565 		{ "get-active-cpus", 	NO_ARG,	&get_active_cpus, 	1 },
1566 		{ "get-suspended-cpus", NO_ARG,	&get_suspended_cpus, 	1 },
1567 		{ "get-intinfo", 	NO_ARG,	&get_intinfo,		1 },
1568 		{ "get-cpu-topology",	NO_ARG, &get_cpu_topology,	1 },
1569 #ifndef __FreeBSD__
1570 		{ "pmtmr-port",		REQ_ARG,	0,	PMTMR_PORT },
1571 		{ "wrlock-cycle",	NO_ARG,	&wrlock_cycle,	1 },
1572 		{ "get-fpu",	NO_ARG,		&get_fpu,	1 },
1573 #endif
1574 	};
1575 
1576 	const struct option intel_opts[] = {
1577 		{ "get-vmcs-pinbased-ctls",
1578 				NO_ARG,		&get_pinbased_ctls, 1 },
1579 		{ "get-vmcs-procbased-ctls",
1580 				NO_ARG,		&get_procbased_ctls, 1 },
1581 		{ "get-vmcs-procbased-ctls2",
1582 				NO_ARG,		&get_procbased_ctls2, 1 },
1583 		{ "get-vmcs-guest-linear-address",
1584 				NO_ARG,		&get_vmcs_gla,	1 },
1585 		{ "get-vmcs-guest-physical-address",
1586 				NO_ARG,		&get_vmcs_gpa,	1 },
1587 		{ "get-vmcs-entry-interruption-info",
1588 				NO_ARG, &get_vmcs_entry_interruption_info, 1},
1589 		{ "get-vmcs-cr0-mask", NO_ARG,	&get_cr0_mask,	1 },
1590 		{ "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 },
1591 		{ "get-vmcs-cr4-mask", 		NO_ARG,	&get_cr4_mask,	  1 },
1592 		{ "get-vmcs-cr4-shadow", 	NO_ARG, &get_cr4_shadow,  1 },
1593 		{ "get-vmcs-cr3-targets", 	NO_ARG, &get_cr3_targets, 1 },
1594 		{ "get-vmcs-tpr-threshold",
1595 					NO_ARG,	&get_tpr_threshold, 1 },
1596 		{ "get-vmcs-vpid", 	NO_ARG,	&get_vpid_asid,	    1 },
1597 		{ "get-vmcs-exit-ctls", NO_ARG,	&get_exit_ctls,	    1 },
1598 		{ "get-vmcs-entry-ctls",
1599 					NO_ARG,	&get_entry_ctls, 1 },
1600 		{ "get-vmcs-instruction-error",
1601 					NO_ARG,	&get_inst_err,	1 },
1602 		{ "get-vmcs-host-pat",	NO_ARG,	&get_host_pat,	1 },
1603 		{ "get-vmcs-host-cr0",
1604 					NO_ARG,	&get_host_cr0,	1 },
1605 		{ "set-vmcs-entry-interruption-info",
1606 				REQ_ARG, 0, SET_VMCS_ENTRY_INTERRUPTION_INFO },
1607 		{ "get-vmcs-exit-qualification",
1608 				NO_ARG,	&get_vmcs_exit_qualification, 1 },
1609 		{ "get-vmcs-exit-inst-length",
1610 				NO_ARG,	&get_vmcs_exit_inst_length, 1 },
1611 		{ "get-vmcs-interruptibility",
1612 				NO_ARG, &get_vmcs_interruptibility, 1 },
1613 		{ "get-vmcs-exit-interruption-error",
1614 				NO_ARG,	&get_vmcs_exit_interruption_error, 1 },
1615 		{ "get-vmcs-exit-interruption-info",
1616 				NO_ARG,	&get_vmcs_exit_interruption_info, 1 },
1617 		{ "get-vmcs-link", 	NO_ARG,		&get_vmcs_link, 1 },
1618 		{ "get-vmcs-host-cr3",
1619 					NO_ARG,		&get_host_cr3,	1 },
1620 		{ "get-vmcs-host-cr4",
1621 				NO_ARG,		&get_host_cr4,	1 },
1622 		{ "get-vmcs-host-rip",
1623 				NO_ARG,		&get_host_rip,	1 },
1624 		{ "get-vmcs-host-rsp",
1625 				NO_ARG,		&get_host_rsp,	1 },
1626 		{ "get-apic-access-address",
1627 				NO_ARG,		&get_apic_access_addr, 1},
1628 		{ "get-virtual-apic-address",
1629 				NO_ARG,		&get_virtual_apic_addr, 1}
1630 	};
1631 
1632 	const struct option amd_opts[] = {
1633 		{ "get-vmcb-intercepts",
1634 				NO_ARG,	&get_vmcb_intercept, 	1 },
1635 		{ "get-vmcb-asid",
1636 				NO_ARG,	&get_vpid_asid,	     	1 },
1637 		{ "get-vmcb-exit-details",
1638 				NO_ARG, &get_vmcb_exit_details,	1 },
1639 		{ "get-vmcb-tlb-ctrl",
1640 				NO_ARG, &get_vmcb_tlb_ctrl, 	1 },
1641 		{ "get-vmcb-virq",
1642 				NO_ARG, &get_vmcb_virq, 	1 },
1643 		{ "get-avic-apic-bar",
1644 				NO_ARG,	&get_apic_access_addr, 	1 },
1645 		{ "get-avic-backing-page",
1646 				NO_ARG,	&get_virtual_apic_addr, 1 },
1647 		{ "get-avic-table",
1648 				NO_ARG,	&get_avic_table, 	1 }
1649 	};
1650 
1651 	const struct option null_opt = {
1652 		NULL, 0, NULL, 0
1653 	};
1654 
1655 	struct option *all_opts;
1656 	char *cp;
1657 	int optlen;
1658 
1659 	optlen = sizeof(common_opts);
1660 
1661 	if (cpu_intel)
1662 		optlen += sizeof(intel_opts);
1663 	else
1664 		optlen += sizeof(amd_opts);
1665 
1666 	optlen += sizeof(null_opt);
1667 
1668 	all_opts = malloc(optlen);
1669 
1670 	cp = (char *)all_opts;
1671 	memcpy(cp, common_opts, sizeof(common_opts));
1672 	cp += sizeof(common_opts);
1673 
1674 	if (cpu_intel) {
1675 		memcpy(cp, intel_opts, sizeof(intel_opts));
1676 		cp += sizeof(intel_opts);
1677 	} else {
1678 		memcpy(cp, amd_opts, sizeof(amd_opts));
1679 		cp += sizeof(amd_opts);
1680 	}
1681 
1682 	memcpy(cp, &null_opt, sizeof(null_opt));
1683 	cp += sizeof(null_opt);
1684 
1685 	return (all_opts);
1686 }
1687 
1688 static const char *
1689 wday_str(int idx)
1690 {
1691 	static const char *weekdays[] = {
1692 		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
1693 	};
1694 
1695 	if (idx >= 0 && idx < 7)
1696 		return (weekdays[idx]);
1697 	else
1698 		return ("UNK");
1699 }
1700 
1701 static const char *
1702 mon_str(int idx)
1703 {
1704 	static const char *months[] = {
1705 		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
1706 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1707 	};
1708 
1709 	if (idx >= 0 && idx < 12)
1710 		return (months[idx]);
1711 	else
1712 		return ("UNK");
1713 }
1714 
1715 static int
1716 show_memmap(struct vmctx *ctx)
1717 {
1718 	char name[SPECNAMELEN + 1], numbuf[8];
1719 	vm_ooffset_t segoff;
1720 	vm_paddr_t gpa;
1721 	size_t maplen, seglen;
1722 	int error, flags, prot, segid, delim;
1723 
1724 	printf("Address     Length      Segment     Offset      ");
1725 	printf("Prot  Flags\n");
1726 
1727 	gpa = 0;
1728 	while (1) {
1729 		error = vm_mmap_getnext(ctx, &gpa, &segid, &segoff, &maplen,
1730 		    &prot, &flags);
1731 		if (error)
1732 			return (errno == ENOENT ? 0 : error);
1733 
1734 		error = vm_get_memseg(ctx, segid, &seglen, name, sizeof(name));
1735 		if (error)
1736 			return (error);
1737 
1738 		printf("%-12lX", gpa);
1739 		humanize_number(numbuf, sizeof(numbuf), maplen, "B",
1740 		    HN_AUTOSCALE, HN_NOSPACE);
1741 		printf("%-12s", numbuf);
1742 
1743 		printf("%-12s", name[0] ? name : "sysmem");
1744 		printf("%-12lX", segoff);
1745 		printf("%c%c%c   ", prot & PROT_READ ? 'R' : '-',
1746 		    prot & PROT_WRITE ? 'W' : '-',
1747 		    prot & PROT_EXEC ? 'X' : '-');
1748 
1749 		delim = '\0';
1750 		if (flags & VM_MEMMAP_F_WIRED) {
1751 			printf("%cwired", delim);
1752 			delim = '/';
1753 		}
1754 		if (flags & VM_MEMMAP_F_IOMMU) {
1755 			printf("%ciommu", delim);
1756 			delim = '/';
1757 		}
1758 		printf("\n");
1759 
1760 		gpa += maplen;
1761 	}
1762 }
1763 
1764 static int
1765 show_memseg(struct vmctx *ctx)
1766 {
1767 	char name[SPECNAMELEN + 1], numbuf[8];
1768 	size_t seglen;
1769 	int error, segid;
1770 
1771 	printf("ID  Length      Name\n");
1772 
1773 	segid = 0;
1774 	while (1) {
1775 		error = vm_get_memseg(ctx, segid, &seglen, name, sizeof(name));
1776 		if (error)
1777 			return (errno == EINVAL ? 0 : error);
1778 
1779 		if (seglen) {
1780 			printf("%-4d", segid);
1781 			humanize_number(numbuf, sizeof(numbuf), seglen, "B",
1782 			    HN_AUTOSCALE, HN_NOSPACE);
1783 			printf("%-12s", numbuf);
1784 			printf("%s", name[0] ? name : "sysmem");
1785 			printf("\n");
1786 		}
1787 		segid++;
1788 	}
1789 }
1790 
1791 #ifndef __FreeBSD__
1792 static int
1793 show_fpu(struct vmctx *ctx, int vcpu)
1794 {
1795 	int res, fd;
1796 
1797 	struct vm_fpu_desc_entry entries[64];
1798 	struct vm_fpu_desc desc = {
1799 		.vfd_entry_data = entries,
1800 		.vfd_num_entries = 64,
1801 	};
1802 	fd = vm_get_device_fd(ctx);
1803 	res = ioctl(fd, VM_DESC_FPU_AREA, &desc);
1804 	if (res != 0) {
1805 		return (errno);
1806 	}
1807 	for (uint_t i = 0; i < desc.vfd_num_entries; i++) {
1808 		const struct vm_fpu_desc_entry *entry = &entries[i];
1809 
1810 		/* confirm that AVX fields are where we expect */
1811 		if (entry->vfde_feature == XFEATURE_AVX) {
1812 			if (entry->vfde_size != 0x100 ||
1813 			    entry->vfde_off != 0x240) {
1814 				(void) fprintf(stderr,
1815 				    "show_fpu: unexpected AVX size/placement "
1816 				    "- size:%x off:%x\n",
1817 				    entry->vfde_size, entry->vfde_off);
1818 				return (EINVAL);
1819 			}
1820 		}
1821 	}
1822 	void *buf = malloc(desc.vfd_req_size);
1823 	if (buf == NULL) {
1824 		return (ENOMEM);
1825 	}
1826 	struct vm_fpu_state req = {
1827 		.vcpuid = vcpu,
1828 		.buf = buf,
1829 		.len = desc.vfd_req_size,
1830 	};
1831 	res = ioctl(fd, VM_GET_FPU, &req);
1832 	if (res != 0) {
1833 		res = errno;
1834 		free(buf);
1835 		return (res);
1836 	}
1837 
1838 	const struct xsave_state *state = buf;
1839 	const struct fxsave_state *fx = &state->xs_fxsave;
1840 	(void) printf("fpu_fcw[%d]\t\t0x%04x\n", vcpu, fx->fx_fcw);
1841 	(void) printf("fpu_fsw[%d]\t\t0x%04x\n", vcpu, fx->fx_fsw);
1842 	(void) printf("fpu_ftw[%d]\t\t0x%04x\n", vcpu, fx->fx_fctw);
1843 	(void) printf("fpu_fop[%d]\t\t0x%04x\n", vcpu, fx->fx_fop);
1844 	(void) printf("fpu_rip[%d]\t\t0x%016lx\n", vcpu, fx->fx_rip);
1845 	(void) printf("fpu_rdp[%d]\t\t0x%016lx\n", vcpu, fx->fx_rdp);
1846 	(void) printf("fpu_mxcsr[%d]\t\t0x%08x\n", vcpu, fx->fx_mxcsr);
1847 	(void) printf("fpu_mxcsr_mask[%d]\t0x%08x\n", vcpu,
1848 	    fx->fx_mxcsr_mask);
1849 	/* ST/MMX regs */
1850 	for (uint_t i = 0; i < 8; i++) {
1851 		(void) printf("fpu_st%u[%d]\t\t0x%08x%08x%08x%08x\n", vcpu, i,
1852 		    fx->fx_st[i].__fpr_pad[0], fx->fx_st[i].__fpr_pad[1],
1853 		    fx->fx_st[i].__fpr_pad[2], fx->fx_st[i].__fpr_pad[3]);
1854 	}
1855 	/* SSE regs */
1856 	for (uint_t i = 0; i < 16; i++) {
1857 		(void) printf("fpu_xmm%u[%d]\t\t0x%08x%08x%08x%08x\n",
1858 		    i, vcpu,
1859 		    fx->fx_xmm[i]._l[0], fx->fx_xmm[i]._l[1],
1860 		    fx->fx_xmm[i]._l[2], fx->fx_xmm[i]._l[3]);
1861 	}
1862 
1863 	if (state->xs_header.xsh_xstate_bv & XFEATURE_AVX) {
1864 		/* AVX regs */
1865 		for (uint_t i = 0; i < 16; i++) {
1866 			(void) printf("fpu_ymm%u[%d]\t\t0x%08x%08x%08x%08x\n",
1867 			    i, vcpu,
1868 			    state->xs_ymm[i]._l[0], state->xs_ymm[i]._l[1],
1869 			    state->xs_ymm[i]._l[2], state->xs_ymm[i]._l[3]);
1870 		}
1871 	}
1872 
1873 	free(buf);
1874 	return (0);
1875 }
1876 #endif /*__FreeBSD__ */
1877 
1878 int
1879 main(int argc, char *argv[])
1880 {
1881 	char *vmname;
1882 	int error, ch, vcpu, ptenum;
1883 	vm_paddr_t gpa_pmap;
1884 	struct vm_exit vmexit;
1885 	uint64_t rax, cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7;
1886 	uint64_t rsp, rip, rflags, efer, pat;
1887 	uint64_t eptp, bm, addr, u64, pteval[4], *pte, info[2];
1888 	struct vmctx *ctx;
1889 	cpuset_t cpus;
1890 	bool cpu_intel;
1891 	uint64_t cs, ds, es, fs, gs, ss, tr, ldtr;
1892 	struct tm tm;
1893 	struct option *opts;
1894 
1895 	cpu_intel = cpu_vendor_intel();
1896 	opts = setup_options(cpu_intel);
1897 
1898 	vcpu = 0;
1899 	vmname = NULL;
1900 	assert_lapic_lvt = -1;
1901 	progname = basename(argv[0]);
1902 
1903 	while ((ch = getopt_long(argc, argv, "", opts, NULL)) != -1) {
1904 		switch (ch) {
1905 		case 0:
1906 			break;
1907 		case VMNAME:
1908 			vmname = optarg;
1909 			break;
1910 		case VCPU:
1911 			vcpu = atoi(optarg);
1912 			break;
1913 		case SET_MEM:
1914 			memsize = atoi(optarg) * MB;
1915 			memsize = roundup(memsize, 2 * MB);
1916 			break;
1917 		case SET_EFER:
1918 			efer = strtoul(optarg, NULL, 0);
1919 			set_efer = 1;
1920 			break;
1921 		case SET_CR0:
1922 			cr0 = strtoul(optarg, NULL, 0);
1923 			set_cr0 = 1;
1924 			break;
1925 		case SET_CR2:
1926 			cr2 = strtoul(optarg, NULL, 0);
1927 			set_cr2 = 1;
1928 			break;
1929 		case SET_CR3:
1930 			cr3 = strtoul(optarg, NULL, 0);
1931 			set_cr3 = 1;
1932 			break;
1933 		case SET_CR4:
1934 			cr4 = strtoul(optarg, NULL, 0);
1935 			set_cr4 = 1;
1936 			break;
1937 		case SET_DR0:
1938 			dr0 = strtoul(optarg, NULL, 0);
1939 			set_dr0 = 1;
1940 			break;
1941 		case SET_DR1:
1942 			dr1 = strtoul(optarg, NULL, 0);
1943 			set_dr1 = 1;
1944 			break;
1945 		case SET_DR2:
1946 			dr2 = strtoul(optarg, NULL, 0);
1947 			set_dr2 = 1;
1948 			break;
1949 		case SET_DR3:
1950 			dr3 = strtoul(optarg, NULL, 0);
1951 			set_dr3 = 1;
1952 			break;
1953 		case SET_DR6:
1954 			dr6 = strtoul(optarg, NULL, 0);
1955 			set_dr6 = 1;
1956 			break;
1957 		case SET_DR7:
1958 			dr7 = strtoul(optarg, NULL, 0);
1959 			set_dr7 = 1;
1960 			break;
1961 		case SET_RSP:
1962 			rsp = strtoul(optarg, NULL, 0);
1963 			set_rsp = 1;
1964 			break;
1965 		case SET_RIP:
1966 			rip = strtoul(optarg, NULL, 0);
1967 			set_rip = 1;
1968 			break;
1969 		case SET_RAX:
1970 			rax = strtoul(optarg, NULL, 0);
1971 			set_rax = 1;
1972 			break;
1973 		case SET_RFLAGS:
1974 			rflags = strtoul(optarg, NULL, 0);
1975 			set_rflags = 1;
1976 			break;
1977 		case DESC_BASE:
1978 			desc_base = strtoul(optarg, NULL, 0);
1979 			break;
1980 		case DESC_LIMIT:
1981 			desc_limit = strtoul(optarg, NULL, 0);
1982 			break;
1983 		case DESC_ACCESS:
1984 			desc_access = strtoul(optarg, NULL, 0);
1985 			break;
1986 		case SET_CS:
1987 			cs = strtoul(optarg, NULL, 0);
1988 			set_cs = 1;
1989 			break;
1990 		case SET_DS:
1991 			ds = strtoul(optarg, NULL, 0);
1992 			set_ds = 1;
1993 			break;
1994 		case SET_ES:
1995 			es = strtoul(optarg, NULL, 0);
1996 			set_es = 1;
1997 			break;
1998 		case SET_FS:
1999 			fs = strtoul(optarg, NULL, 0);
2000 			set_fs = 1;
2001 			break;
2002 		case SET_GS:
2003 			gs = strtoul(optarg, NULL, 0);
2004 			set_gs = 1;
2005 			break;
2006 		case SET_SS:
2007 			ss = strtoul(optarg, NULL, 0);
2008 			set_ss = 1;
2009 			break;
2010 		case SET_TR:
2011 			tr = strtoul(optarg, NULL, 0);
2012 			set_tr = 1;
2013 			break;
2014 		case SET_LDTR:
2015 			ldtr = strtoul(optarg, NULL, 0);
2016 			set_ldtr = 1;
2017 			break;
2018 		case SET_X2APIC_STATE:
2019 			x2apic_state = strtol(optarg, NULL, 0);
2020 			set_x2apic_state = 1;
2021 			break;
2022 		case SET_EXCEPTION_BITMAP:
2023 			exception_bitmap = strtoul(optarg, NULL, 0);
2024 			set_exception_bitmap = 1;
2025 			break;
2026 		case SET_VMCS_ENTRY_INTERRUPTION_INFO:
2027 			vmcs_entry_interruption_info = strtoul(optarg, NULL, 0);
2028 			set_vmcs_entry_interruption_info = 1;
2029 			break;
2030 		case SET_CAP:
2031 			capval = strtoul(optarg, NULL, 0);
2032 			setcap = 1;
2033 			break;
2034 		case SET_RTC_TIME:
2035 			rtc_secs = strtoul(optarg, NULL, 0);
2036 			set_rtc_time = 1;
2037 			break;
2038 		case SET_RTC_NVRAM:
2039 			rtc_nvram_value = (uint8_t)strtoul(optarg, NULL, 0);
2040 			set_rtc_nvram = 1;
2041 			break;
2042 		case RTC_NVRAM_OFFSET:
2043 			rtc_nvram_offset = strtoul(optarg, NULL, 0);
2044 			break;
2045 		case GET_GPA_PMAP:
2046 			gpa_pmap = strtoul(optarg, NULL, 0);
2047 			get_gpa_pmap = 1;
2048 			break;
2049 		case CAPNAME:
2050 			capname = optarg;
2051 			break;
2052 #ifdef __FreeBSD__
2053 		case UNASSIGN_PPTDEV:
2054 			unassign_pptdev = 1;
2055 			if (sscanf(optarg, "%d/%d/%d", &bus, &slot, &func) != 3)
2056 				usage(cpu_intel);
2057 			break;
2058 #endif
2059 		case ASSERT_LAPIC_LVT:
2060 			assert_lapic_lvt = atoi(optarg);
2061 			break;
2062 #ifndef __FreeBSD__
2063 		case PMTMR_PORT:
2064 			pmtmr_port = strtoul(optarg, NULL, 16);
2065 			break;
2066 #endif
2067 		default:
2068 			usage(cpu_intel);
2069 		}
2070 	}
2071 	argc -= optind;
2072 	argv += optind;
2073 
2074 	if (vmname == NULL)
2075 		usage(cpu_intel);
2076 
2077 	error = 0;
2078 
2079 #ifndef __FreeBSD__
2080 	if (!error && create)
2081 		error = vm_create(vmname, 0);
2082 # else
2083 	if (!error && create)
2084 		error = vm_create(vmname);
2085 #endif /* __FreeBSD__ */
2086 
2087 	if (!error) {
2088 		ctx = vm_open(vmname);
2089 		if (ctx == NULL) {
2090 			fprintf(stderr,
2091 			    "vm_open: %s could not be opened: %s\n",
2092 			    vmname, strerror(errno));
2093 			exit (1);
2094 		}
2095 	}
2096 
2097 #ifndef __FreeBSD__
2098 	if (!error && pmtmr_port) {
2099 		error = vm_pmtmr_set_location(ctx, pmtmr_port);
2100 		exit(error);
2101 	}
2102 	if (!error && wrlock_cycle) {
2103 		error = vm_wrlock_cycle(ctx);
2104 		exit(error);
2105 	}
2106 #endif /* __FreeBSD__ */
2107 
2108 	if (!error && memsize)
2109 		error = vm_setup_memory(ctx, memsize, VM_MMAP_ALL);
2110 
2111 	if (!error && set_efer)
2112 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_EFER, efer);
2113 
2114 	if (!error && set_cr0)
2115 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR0, cr0);
2116 
2117 	if (!error && set_cr2)
2118 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR2, cr2);
2119 
2120 	if (!error && set_cr3)
2121 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR3, cr3);
2122 
2123 	if (!error && set_cr4)
2124 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR4, cr4);
2125 
2126 	if (!error && set_dr0)
2127 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR0, dr0);
2128 
2129 	if (!error && set_dr1)
2130 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR1, dr1);
2131 
2132 	if (!error && set_dr2)
2133 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR2, dr2);
2134 
2135 	if (!error && set_dr3)
2136 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR3, dr3);
2137 
2138 	if (!error && set_dr6)
2139 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR6, dr6);
2140 
2141 	if (!error && set_dr7)
2142 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR7, dr7);
2143 
2144 	if (!error && set_rsp)
2145 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RSP, rsp);
2146 
2147 	if (!error && set_rip)
2148 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, rip);
2149 
2150 	if (!error && set_rax)
2151 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, rax);
2152 
2153 	if (!error && set_rflags) {
2154 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RFLAGS,
2155 					rflags);
2156 	}
2157 
2158 	if (!error && set_desc_ds) {
2159 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_DS,
2160 				    desc_base, desc_limit, desc_access);
2161 	}
2162 
2163 	if (!error && set_desc_es) {
2164 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_ES,
2165 				    desc_base, desc_limit, desc_access);
2166 	}
2167 
2168 	if (!error && set_desc_ss) {
2169 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_SS,
2170 				    desc_base, desc_limit, desc_access);
2171 	}
2172 
2173 	if (!error && set_desc_cs) {
2174 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_CS,
2175 				    desc_base, desc_limit, desc_access);
2176 	}
2177 
2178 	if (!error && set_desc_fs) {
2179 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_FS,
2180 				    desc_base, desc_limit, desc_access);
2181 	}
2182 
2183 	if (!error && set_desc_gs) {
2184 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GS,
2185 				    desc_base, desc_limit, desc_access);
2186 	}
2187 
2188 	if (!error && set_desc_tr) {
2189 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_TR,
2190 				    desc_base, desc_limit, desc_access);
2191 	}
2192 
2193 	if (!error && set_desc_ldtr) {
2194 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_LDTR,
2195 				    desc_base, desc_limit, desc_access);
2196 	}
2197 
2198 	if (!error && set_desc_gdtr) {
2199 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GDTR,
2200 				    desc_base, desc_limit, 0);
2201 	}
2202 
2203 	if (!error && set_desc_idtr) {
2204 		error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_IDTR,
2205 				    desc_base, desc_limit, 0);
2206 	}
2207 
2208 	if (!error && set_cs)
2209 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CS, cs);
2210 
2211 	if (!error && set_ds)
2212 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DS, ds);
2213 
2214 	if (!error && set_es)
2215 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_ES, es);
2216 
2217 	if (!error && set_fs)
2218 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_FS, fs);
2219 
2220 	if (!error && set_gs)
2221 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_GS, gs);
2222 
2223 	if (!error && set_ss)
2224 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_SS, ss);
2225 
2226 	if (!error && set_tr)
2227 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_TR, tr);
2228 
2229 	if (!error && set_ldtr)
2230 		error = vm_set_register(ctx, vcpu, VM_REG_GUEST_LDTR, ldtr);
2231 
2232 	if (!error && set_x2apic_state)
2233 		error = vm_set_x2apic_state(ctx, vcpu, x2apic_state);
2234 
2235 #ifdef __FreeBSD__
2236 	if (!error && unassign_pptdev)
2237 		error = vm_unassign_pptdev(ctx, bus, slot, func);
2238 #endif /* __FreeBSD__ */
2239 
2240 	if (!error && set_exception_bitmap) {
2241 		if (cpu_intel)
2242 			error = vm_set_vmcs_field(ctx, vcpu,
2243 						  VMCS_EXCEPTION_BITMAP,
2244 						  exception_bitmap);
2245 		else
2246 			error = vm_set_vmcb_field(ctx, vcpu,
2247 						  VMCB_OFF_EXC_INTERCEPT,
2248 						  4, exception_bitmap);
2249 	}
2250 
2251 	if (!error && cpu_intel && set_vmcs_entry_interruption_info) {
2252 		error = vm_set_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,
2253 					  vmcs_entry_interruption_info);
2254 	}
2255 
2256 	if (!error && inject_nmi) {
2257 		error = vm_inject_nmi(ctx, vcpu);
2258 	}
2259 
2260 	if (!error && assert_lapic_lvt != -1) {
2261 		error = vm_lapic_local_irq(ctx, vcpu, assert_lapic_lvt);
2262 	}
2263 
2264 	if (!error && (get_memseg || get_all))
2265 		error = show_memseg(ctx);
2266 
2267 	if (!error && (get_memmap || get_all))
2268 		error = show_memmap(ctx);
2269 
2270 	if (!error)
2271 		error = get_all_registers(ctx, vcpu);
2272 
2273 	if (!error)
2274 		error = get_all_segments(ctx, vcpu);
2275 
2276 #ifndef __FreeBSD__
2277 	if (!error && (get_fpu || get_all)) {
2278 		error = show_fpu(ctx, vcpu);
2279 	}
2280 #endif /* __FreeBSD__ */
2281 
2282 	if (!error) {
2283 		if (cpu_intel)
2284 			error = get_misc_vmcs(ctx, vcpu);
2285 		else
2286 			error = get_misc_vmcb(ctx, vcpu);
2287 	}
2288 
2289 	if (!error && (get_x2apic_state || get_all)) {
2290 		error = vm_get_x2apic_state(ctx, vcpu, &x2apic_state);
2291 		if (error == 0)
2292 			printf("x2apic_state[%d]\t%d\n", vcpu, x2apic_state);
2293 	}
2294 
2295 	if (!error && (get_eptp || get_all)) {
2296 		if (cpu_intel)
2297 			error = vm_get_vmcs_field(ctx, vcpu, VMCS_EPTP, &eptp);
2298 		else
2299 			error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_NPT_BASE,
2300 						   8, &eptp);
2301 		if (error == 0)
2302 			printf("%s[%d]\t\t0x%016lx\n",
2303 				cpu_intel ? "eptp" : "rvi/npt", vcpu, eptp);
2304 	}
2305 
2306 	if (!error && (get_exception_bitmap || get_all)) {
2307 		if(cpu_intel)
2308 			error = vm_get_vmcs_field(ctx, vcpu,
2309 						VMCS_EXCEPTION_BITMAP, &bm);
2310 		else
2311 			error = vm_get_vmcb_field(ctx, vcpu,
2312 						  VMCB_OFF_EXC_INTERCEPT,
2313 						  4, &bm);
2314 		if (error == 0)
2315 			printf("exception_bitmap[%d]\t%#lx\n", vcpu, bm);
2316 	}
2317 
2318 	if (!error && (get_io_bitmap || get_all)) {
2319 		if (cpu_intel) {
2320 			error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_A,
2321 						  &bm);
2322 			if (error == 0)
2323 				printf("io_bitmap_a[%d]\t%#lx\n", vcpu, bm);
2324 			error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_B,
2325 						  &bm);
2326 			if (error == 0)
2327 				printf("io_bitmap_b[%d]\t%#lx\n", vcpu, bm);
2328 		} else {
2329 			error = vm_get_vmcb_field(ctx, vcpu,
2330 						  VMCB_OFF_IO_PERM, 8, &bm);
2331 			if (error == 0)
2332 				printf("io_bitmap[%d]\t%#lx\n", vcpu, bm);
2333 		}
2334 	}
2335 
2336 	if (!error && (get_tsc_offset || get_all)) {
2337 		uint64_t tscoff;
2338 		if (cpu_intel)
2339 			error = vm_get_vmcs_field(ctx, vcpu, VMCS_TSC_OFFSET,
2340 						  &tscoff);
2341 		else
2342 			error = vm_get_vmcb_field(ctx, vcpu,
2343 						  VMCB_OFF_TSC_OFFSET,
2344 						  8, &tscoff);
2345 		if (error == 0)
2346 			printf("tsc_offset[%d]\t0x%016lx\n", vcpu, tscoff);
2347 	}
2348 
2349 	if (!error && (get_msr_bitmap_address || get_all)) {
2350 		if (cpu_intel)
2351 			error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP,
2352 						  &addr);
2353 		else
2354 			error = vm_get_vmcb_field(ctx, vcpu,
2355 						  VMCB_OFF_MSR_PERM, 8, &addr);
2356 		if (error == 0)
2357 			printf("msr_bitmap[%d]\t\t%#lx\n", vcpu, addr);
2358 	}
2359 
2360 	if (!error && (get_msr_bitmap || get_all)) {
2361 		if (cpu_intel) {
2362 			error = vm_get_vmcs_field(ctx, vcpu,
2363 						  VMCS_MSR_BITMAP, &addr);
2364 		} else {
2365 			error = vm_get_vmcb_field(ctx, vcpu,
2366 						  VMCB_OFF_MSR_PERM, 8,
2367 						  &addr);
2368 		}
2369 
2370 #ifdef __FreeBSD__
2371 		if (error == 0)
2372 			error = dump_msr_bitmap(vcpu, addr, cpu_intel);
2373 #else
2374 		/*
2375 		 * Skip dumping the MSR bitmap since raw access to the VMCS is
2376 		 * currently not possible.
2377 		 */
2378 #endif /* __FreeBSD__ */
2379 	}
2380 
2381 	if (!error && (get_vpid_asid || get_all)) {
2382 		uint64_t vpid;
2383 		if (cpu_intel)
2384 			error = vm_get_vmcs_field(ctx, vcpu, VMCS_VPID, &vpid);
2385 		else
2386 			error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_ASID,
2387 						  4, &vpid);
2388 		if (error == 0)
2389 			printf("%s[%d]\t\t0x%04lx\n",
2390 				cpu_intel ? "vpid" : "asid", vcpu, vpid);
2391 	}
2392 
2393 	if (!error && (get_guest_pat || get_all)) {
2394 		if (cpu_intel)
2395 			error = vm_get_vmcs_field(ctx, vcpu,
2396 						  VMCS_GUEST_IA32_PAT, &pat);
2397 		else
2398 			error = vm_get_vmcb_field(ctx, vcpu,
2399 						  VMCB_OFF_GUEST_PAT, 8, &pat);
2400 		if (error == 0)
2401 			printf("guest_pat[%d]\t\t0x%016lx\n", vcpu, pat);
2402 	}
2403 
2404 	if (!error && (get_guest_sysenter || get_all)) {
2405 		if (cpu_intel)
2406 			error = vm_get_vmcs_field(ctx, vcpu,
2407 						  VMCS_GUEST_IA32_SYSENTER_CS,
2408 						  &cs);
2409 		else
2410 			error = vm_get_vmcb_field(ctx, vcpu,
2411 						  VMCB_OFF_SYSENTER_CS, 8,
2412 						  &cs);
2413 
2414 		if (error == 0)
2415 			printf("guest_sysenter_cs[%d]\t%#lx\n", vcpu, cs);
2416 		if (cpu_intel)
2417 			error = vm_get_vmcs_field(ctx, vcpu,
2418 						  VMCS_GUEST_IA32_SYSENTER_ESP,
2419 						  &rsp);
2420 		else
2421 			error = vm_get_vmcb_field(ctx, vcpu,
2422 						  VMCB_OFF_SYSENTER_ESP, 8,
2423 						  &rsp);
2424 
2425 		if (error == 0)
2426 			printf("guest_sysenter_sp[%d]\t%#lx\n", vcpu, rsp);
2427 		if (cpu_intel)
2428 			error = vm_get_vmcs_field(ctx, vcpu,
2429 						  VMCS_GUEST_IA32_SYSENTER_EIP,
2430 						  &rip);
2431 		else
2432 			error = vm_get_vmcb_field(ctx, vcpu,
2433 						  VMCB_OFF_SYSENTER_EIP, 8,
2434 						  &rip);
2435 		if (error == 0)
2436 			printf("guest_sysenter_ip[%d]\t%#lx\n", vcpu, rip);
2437 	}
2438 
2439 	if (!error && (get_exit_reason || get_all)) {
2440 		if (cpu_intel)
2441 			error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_REASON,
2442 						  &u64);
2443 		else
2444 			error = vm_get_vmcb_field(ctx, vcpu,
2445 						  VMCB_OFF_EXIT_REASON, 8,
2446 						  &u64);
2447 		if (error == 0)
2448 			printf("exit_reason[%d]\t%#lx\n", vcpu, u64);
2449 	}
2450 
2451 	if (!error && setcap) {
2452 		int captype;
2453 		captype = vm_capability_name2type(capname);
2454 		error = vm_set_capability(ctx, vcpu, captype, capval);
2455 		if (error != 0 && errno == ENOENT)
2456 			printf("Capability \"%s\" is not available\n", capname);
2457 	}
2458 
2459 	if (!error && get_gpa_pmap) {
2460 		error = vm_get_gpa_pmap(ctx, gpa_pmap, pteval, &ptenum);
2461 		if (error == 0) {
2462 			printf("gpa %#lx:", gpa_pmap);
2463 			pte = &pteval[0];
2464 			while (ptenum-- > 0)
2465 				printf(" %#lx", *pte++);
2466 			printf("\n");
2467 		}
2468 	}
2469 
2470 	if (!error && set_rtc_nvram)
2471 		error = vm_rtc_write(ctx, rtc_nvram_offset, rtc_nvram_value);
2472 
2473 	if (!error && (get_rtc_nvram || get_all)) {
2474 		error = vm_rtc_read(ctx, rtc_nvram_offset, &rtc_nvram_value);
2475 		if (error == 0) {
2476 			printf("rtc nvram[%03d]: 0x%02x\n", rtc_nvram_offset,
2477 			    rtc_nvram_value);
2478 		}
2479 	}
2480 
2481 	if (!error && set_rtc_time)
2482 		error = vm_rtc_settime(ctx, rtc_secs);
2483 
2484 	if (!error && (get_rtc_time || get_all)) {
2485 		error = vm_rtc_gettime(ctx, &rtc_secs);
2486 		if (error == 0) {
2487 			gmtime_r(&rtc_secs, &tm);
2488 			printf("rtc time %#lx: %s %s %02d %02d:%02d:%02d %d\n",
2489 			    rtc_secs, wday_str(tm.tm_wday), mon_str(tm.tm_mon),
2490 			    tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
2491 			    1900 + tm.tm_year);
2492 		}
2493 	}
2494 
2495 	if (!error && (getcap || get_all)) {
2496 		int captype, val, getcaptype;
2497 
2498 		if (getcap && capname)
2499 			getcaptype = vm_capability_name2type(capname);
2500 		else
2501 			getcaptype = -1;
2502 
2503 		for (captype = 0; captype < VM_CAP_MAX; captype++) {
2504 			if (getcaptype >= 0 && captype != getcaptype)
2505 				continue;
2506 			error = vm_get_capability(ctx, vcpu, captype, &val);
2507 			if (error == 0) {
2508 				printf("Capability \"%s\" is %s on vcpu %d\n",
2509 					vm_capability_type2name(captype),
2510 					val ? "set" : "not set", vcpu);
2511 			} else if (errno == ENOENT) {
2512 				error = 0;
2513 				printf("Capability \"%s\" is not available\n",
2514 					vm_capability_type2name(captype));
2515 			} else {
2516 				break;
2517 			}
2518 		}
2519 	}
2520 
2521 	if (!error && (get_active_cpus || get_all)) {
2522 		error = vm_active_cpus(ctx, &cpus);
2523 		if (!error)
2524 			print_cpus("active cpus", &cpus);
2525 	}
2526 
2527 	if (!error && (get_suspended_cpus || get_all)) {
2528 		error = vm_suspended_cpus(ctx, &cpus);
2529 		if (!error)
2530 			print_cpus("suspended cpus", &cpus);
2531 	}
2532 
2533 	if (!error && (get_intinfo || get_all)) {
2534 		error = vm_get_intinfo(ctx, vcpu, &info[0], &info[1]);
2535 		if (!error) {
2536 			print_intinfo("pending", info[0]);
2537 			print_intinfo("current", info[1]);
2538 		}
2539 	}
2540 
2541 	if (!error && (get_stats || get_all)) {
2542 		int i, num_stats;
2543 		uint64_t *stats;
2544 		struct timeval tv;
2545 		const char *desc;
2546 
2547 		stats = vm_get_stats(ctx, vcpu, &tv, &num_stats);
2548 		if (stats != NULL) {
2549 			printf("vcpu%d stats:\n", vcpu);
2550 			for (i = 0; i < num_stats; i++) {
2551 				desc = vm_get_stat_desc(ctx, i);
2552 				printf("%-40s\t%ld\n", desc, stats[i]);
2553 			}
2554 		}
2555 	}
2556 
2557 	if (!error && (get_cpu_topology || get_all)) {
2558 		uint16_t sockets, cores, threads, maxcpus;
2559 
2560 		vm_get_topology(ctx, &sockets, &cores, &threads, &maxcpus);
2561 		printf("cpu_topology:\tsockets=%hu, cores=%hu, threads=%hu, "
2562 		    "maxcpus=%hu\n", sockets, cores, threads, maxcpus);
2563 	}
2564 
2565 	if (!error && run) {
2566 		struct vm_entry entry;
2567 
2568 		bzero(&entry, sizeof (entry));
2569 
2570 		error = vm_run(ctx, vcpu, &entry, &vmexit);
2571 		if (error == 0)
2572 			dump_vm_run_exitcode(&vmexit, vcpu);
2573 		else
2574 			printf("vm_run error %d\n", error);
2575 	}
2576 
2577 	if (!error && force_reset)
2578 		error = vm_suspend(ctx, VM_SUSPEND_RESET);
2579 
2580 	if (!error && force_poweroff)
2581 		error = vm_suspend(ctx, VM_SUSPEND_POWEROFF);
2582 
2583 	if (error)
2584 		printf("errno = %d\n", errno);
2585 
2586 	if (!error && destroy)
2587 		vm_destroy(ctx);
2588 
2589 	free (opts);
2590 	exit(error);
2591 }
2592