xref: /illumos-gate/usr/src/cmd/bhyvectl/bhyvectl.c (revision 54cf5b63)
1bf21cd93STycho Nightingale /*-
24c87aefeSPatrick Mooney  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
34c87aefeSPatrick Mooney  *
4bf21cd93STycho Nightingale  * Copyright (c) 2011 NetApp, Inc.
5bf21cd93STycho Nightingale  * All rights reserved.
6bf21cd93STycho Nightingale  *
7bf21cd93STycho Nightingale  * Redistribution and use in source and binary forms, with or without
8bf21cd93STycho Nightingale  * modification, are permitted provided that the following conditions
9bf21cd93STycho Nightingale  * are met:
10bf21cd93STycho Nightingale  * 1. Redistributions of source code must retain the above copyright
11bf21cd93STycho Nightingale  *    notice, this list of conditions and the following disclaimer.
12bf21cd93STycho Nightingale  * 2. Redistributions in binary form must reproduce the above copyright
13bf21cd93STycho Nightingale  *    notice, this list of conditions and the following disclaimer in the
14bf21cd93STycho Nightingale  *    documentation and/or other materials provided with the distribution.
15bf21cd93STycho Nightingale  *
16bf21cd93STycho Nightingale  * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17bf21cd93STycho Nightingale  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18bf21cd93STycho Nightingale  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19bf21cd93STycho Nightingale  * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20bf21cd93STycho Nightingale  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21bf21cd93STycho Nightingale  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22bf21cd93STycho Nightingale  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23bf21cd93STycho Nightingale  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24bf21cd93STycho Nightingale  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25bf21cd93STycho Nightingale  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26bf21cd93STycho Nightingale  * SUCH DAMAGE.
27bf21cd93STycho Nightingale  *
284c87aefeSPatrick Mooney  * $FreeBSD$
29bf21cd93STycho Nightingale  */
30bf21cd93STycho Nightingale /*
31bf21cd93STycho Nightingale  * This file and its contents are supplied under the terms of the
32bf21cd93STycho Nightingale  * Common Development and Distribution License ("CDDL"), version 1.0.
33bf21cd93STycho Nightingale  * You may only use this file in accordance with the terms of version
34bf21cd93STycho Nightingale  * 1.0 of the CDDL.
35bf21cd93STycho Nightingale  *
36bf21cd93STycho Nightingale  * A full copy of the text of the CDDL should have accompanied this
37bf21cd93STycho Nightingale  * source.  A copy of the CDDL is also available via the Internet at
38bf21cd93STycho Nightingale  * http://www.illumos.org/license/CDDL.
39e0c0d44eSPatrick Mooney  *
40bf21cd93STycho Nightingale  * Copyright 2015 Pluribus Networks Inc.
414c87aefeSPatrick Mooney  * Copyright 2019 Joyent, Inc.
42957246c9SPatrick Mooney  * Copyright 2022 Oxide Computer Company
43bf21cd93STycho Nightingale  */
44bf21cd93STycho Nightingale 
45bf21cd93STycho Nightingale #include <sys/cdefs.h>
464c87aefeSPatrick Mooney __FBSDID("$FreeBSD$");
47bf21cd93STycho Nightingale 
48bf21cd93STycho Nightingale #include <sys/param.h>
49bf21cd93STycho Nightingale #include <sys/types.h>
50bf21cd93STycho Nightingale #include <sys/sysctl.h>
51bf21cd93STycho Nightingale #include <sys/errno.h>
52bf21cd93STycho Nightingale #include <sys/mman.h>
534c87aefeSPatrick Mooney #include <sys/cpuset.h>
54957246c9SPatrick Mooney #include <sys/fp.h>
55bf21cd93STycho Nightingale 
56bf21cd93STycho Nightingale #include <stdio.h>
57bf21cd93STycho Nightingale #include <stdlib.h>
584c87aefeSPatrick Mooney #include <stdbool.h>
594c87aefeSPatrick Mooney #include <string.h>
60bf21cd93STycho Nightingale #include <unistd.h>
61bf21cd93STycho Nightingale #include <libgen.h>
62bf21cd93STycho Nightingale #include <libutil.h>
63bf21cd93STycho Nightingale #include <fcntl.h>
64bf21cd93STycho Nightingale #include <getopt.h>
654c87aefeSPatrick Mooney #include <time.h>
66bf21cd93STycho Nightingale #include <assert.h>
674c87aefeSPatrick Mooney #include <libutil.h>
68bf21cd93STycho Nightingale 
694c87aefeSPatrick Mooney #include <machine/cpufunc.h>
704c87aefeSPatrick Mooney #include <machine/specialreg.h>
71bf21cd93STycho Nightingale #include <machine/vmm.h>
724c87aefeSPatrick Mooney #include <machine/vmm_dev.h>
73*54cf5b63SPatrick Mooney #include <sys/vmm_data.h>
74bf21cd93STycho Nightingale #include <vmmapi.h>
75bf21cd93STycho Nightingale 
764c87aefeSPatrick Mooney #include "amd/vmcb.h"
77bf21cd93STycho Nightingale #include "intel/vmcs.h"
78bf21cd93STycho Nightingale 
79bf21cd93STycho Nightingale #define	MB	(1UL << 20)
80bf21cd93STycho Nightingale #define	GB	(1UL << 30)
81bf21cd93STycho Nightingale 
82bf21cd93STycho Nightingale #define	REQ_ARG		required_argument
83bf21cd93STycho Nightingale #define	NO_ARG		no_argument
84bf21cd93STycho Nightingale #define	OPT_ARG		optional_argument
85bf21cd93STycho Nightingale 
86bf21cd93STycho Nightingale static const char *progname;
87bf21cd93STycho Nightingale 
88bf21cd93STycho Nightingale static void
usage(bool cpu_intel)894c87aefeSPatrick Mooney usage(bool cpu_intel)
90bf21cd93STycho Nightingale {
91bf21cd93STycho Nightingale 
92bf21cd93STycho Nightingale 	(void)fprintf(stderr,
93bf21cd93STycho Nightingale 	"Usage: %s --vm=<vmname>\n"
94bf21cd93STycho Nightingale 	"       [--cpu=<vcpu_number>]\n"
95bf21cd93STycho Nightingale 	"       [--create]\n"
96bf21cd93STycho Nightingale 	"       [--destroy]\n"
970e1453c3SPatrick Mooney 	"       [--pmtmr-port=ioport]\n"
984c87aefeSPatrick Mooney 	"       [--wrlock-cycle]\n"
99bf21cd93STycho Nightingale 	"       [--get-all]\n"
100bf21cd93STycho Nightingale 	"       [--get-stats]\n"
101bf21cd93STycho Nightingale 	"       [--set-desc-ds]\n"
102bf21cd93STycho Nightingale 	"       [--get-desc-ds]\n"
103bf21cd93STycho Nightingale 	"       [--set-desc-es]\n"
104bf21cd93STycho Nightingale 	"       [--get-desc-es]\n"
105bf21cd93STycho Nightingale 	"       [--set-desc-gs]\n"
106bf21cd93STycho Nightingale 	"       [--get-desc-gs]\n"
107bf21cd93STycho Nightingale 	"       [--set-desc-fs]\n"
108bf21cd93STycho Nightingale 	"       [--get-desc-fs]\n"
109bf21cd93STycho Nightingale 	"       [--set-desc-cs]\n"
110bf21cd93STycho Nightingale 	"       [--get-desc-cs]\n"
111bf21cd93STycho Nightingale 	"       [--set-desc-ss]\n"
112bf21cd93STycho Nightingale 	"       [--get-desc-ss]\n"
113bf21cd93STycho Nightingale 	"       [--set-desc-tr]\n"
114bf21cd93STycho Nightingale 	"       [--get-desc-tr]\n"
115bf21cd93STycho Nightingale 	"       [--set-desc-ldtr]\n"
116bf21cd93STycho Nightingale 	"       [--get-desc-ldtr]\n"
117bf21cd93STycho Nightingale 	"       [--set-desc-gdtr]\n"
118bf21cd93STycho Nightingale 	"       [--get-desc-gdtr]\n"
119bf21cd93STycho Nightingale 	"       [--set-desc-idtr]\n"
120bf21cd93STycho Nightingale 	"       [--get-desc-idtr]\n"
121bf21cd93STycho Nightingale 	"       [--run]\n"
122bf21cd93STycho Nightingale 	"       [--capname=<capname>]\n"
123bf21cd93STycho Nightingale 	"       [--getcap]\n"
124bf21cd93STycho Nightingale 	"       [--setcap=<0|1>]\n"
125bf21cd93STycho Nightingale 	"       [--desc-base=<BASE>]\n"
126bf21cd93STycho Nightingale 	"       [--desc-limit=<LIMIT>]\n"
127bf21cd93STycho Nightingale 	"       [--desc-access=<ACCESS>]\n"
128bf21cd93STycho Nightingale 	"       [--set-cr0=<CR0>]\n"
129bf21cd93STycho Nightingale 	"       [--get-cr0]\n"
1304c87aefeSPatrick Mooney 	"       [--set-cr2=<CR2>]\n"
1314c87aefeSPatrick Mooney 	"       [--get-cr2]\n"
132bf21cd93STycho Nightingale 	"       [--set-cr3=<CR3>]\n"
133bf21cd93STycho Nightingale 	"       [--get-cr3]\n"
134bf21cd93STycho Nightingale 	"       [--set-cr4=<CR4>]\n"
135bf21cd93STycho Nightingale 	"       [--get-cr4]\n"
1364c87aefeSPatrick Mooney 	"       [--set-dr0=<DR0>]\n"
1374c87aefeSPatrick Mooney 	"       [--get-dr0]\n"
1384c87aefeSPatrick Mooney 	"       [--set-dr1=<DR1>]\n"
1394c87aefeSPatrick Mooney 	"       [--get-dr1]\n"
1404c87aefeSPatrick Mooney 	"       [--set-dr2=<DR2>]\n"
1414c87aefeSPatrick Mooney 	"       [--get-dr2]\n"
1424c87aefeSPatrick Mooney 	"       [--set-dr3=<DR3>]\n"
1434c87aefeSPatrick Mooney 	"       [--get-dr3]\n"
1444c87aefeSPatrick Mooney 	"       [--set-dr6=<DR6>]\n"
1454c87aefeSPatrick Mooney 	"       [--get-dr6]\n"
146bf21cd93STycho Nightingale 	"       [--set-dr7=<DR7>]\n"
147bf21cd93STycho Nightingale 	"       [--get-dr7]\n"
148bf21cd93STycho Nightingale 	"       [--set-rsp=<RSP>]\n"
149bf21cd93STycho Nightingale 	"       [--get-rsp]\n"
150bf21cd93STycho Nightingale 	"       [--set-rip=<RIP>]\n"
151bf21cd93STycho Nightingale 	"       [--get-rip]\n"
152bf21cd93STycho Nightingale 	"       [--get-rax]\n"
153bf21cd93STycho Nightingale 	"       [--set-rax=<RAX>]\n"
154bf21cd93STycho Nightingale 	"       [--get-rbx]\n"
155bf21cd93STycho Nightingale 	"       [--get-rcx]\n"
156bf21cd93STycho Nightingale 	"       [--get-rdx]\n"
157bf21cd93STycho Nightingale 	"       [--get-rsi]\n"
158bf21cd93STycho Nightingale 	"       [--get-rdi]\n"
159bf21cd93STycho Nightingale 	"       [--get-rbp]\n"
160bf21cd93STycho Nightingale 	"       [--get-r8]\n"
161bf21cd93STycho Nightingale 	"       [--get-r9]\n"
162bf21cd93STycho Nightingale 	"       [--get-r10]\n"
163bf21cd93STycho Nightingale 	"       [--get-r11]\n"
164bf21cd93STycho Nightingale 	"       [--get-r12]\n"
165bf21cd93STycho Nightingale 	"       [--get-r13]\n"
166bf21cd93STycho Nightingale 	"       [--get-r14]\n"
167bf21cd93STycho Nightingale 	"       [--get-r15]\n"
168bf21cd93STycho Nightingale 	"       [--set-rflags=<RFLAGS>]\n"
169bf21cd93STycho Nightingale 	"       [--get-rflags]\n"
170bf21cd93STycho Nightingale 	"       [--set-cs]\n"
171bf21cd93STycho Nightingale 	"       [--get-cs]\n"
172bf21cd93STycho Nightingale 	"       [--set-ds]\n"
173bf21cd93STycho Nightingale 	"       [--get-ds]\n"
174bf21cd93STycho Nightingale 	"       [--set-es]\n"
175bf21cd93STycho Nightingale 	"       [--get-es]\n"
176bf21cd93STycho Nightingale 	"       [--set-fs]\n"
177bf21cd93STycho Nightingale 	"       [--get-fs]\n"
178bf21cd93STycho Nightingale 	"       [--set-gs]\n"
179bf21cd93STycho Nightingale 	"       [--get-gs]\n"
180bf21cd93STycho Nightingale 	"       [--set-ss]\n"
181bf21cd93STycho Nightingale 	"       [--get-ss]\n"
182bf21cd93STycho Nightingale 	"       [--get-tr]\n"
183bf21cd93STycho Nightingale 	"       [--get-ldtr]\n"
184bf21cd93STycho Nightingale 	"       [--set-x2apic-state=<state>]\n"
185bf21cd93STycho Nightingale 	"       [--get-x2apic-state]\n"
186bf21cd93STycho Nightingale 	"       [--set-mem=<memory in units of MB>]\n"
187bf21cd93STycho Nightingale 	"       [--get-lowmem]\n"
1884c87aefeSPatrick Mooney 	"       [--get-highmem]\n"
1894c87aefeSPatrick Mooney 	"       [--get-gpa-pmap]\n"
1904c87aefeSPatrick Mooney 	"       [--assert-lapic-lvt=<pin>]\n"
1914c87aefeSPatrick Mooney 	"       [--inject-nmi]\n"
1924c87aefeSPatrick Mooney 	"       [--force-reset]\n"
1934c87aefeSPatrick Mooney 	"       [--force-poweroff]\n"
1944c87aefeSPatrick Mooney 	"       [--get-rtc-time]\n"
1954c87aefeSPatrick Mooney 	"       [--set-rtc-time=<secs>]\n"
1964c87aefeSPatrick Mooney 	"       [--get-rtc-nvram]\n"
1974c87aefeSPatrick Mooney 	"       [--set-rtc-nvram=<val>]\n"
1984c87aefeSPatrick Mooney 	"       [--rtc-nvram-offset=<offset>]\n"
1994c87aefeSPatrick Mooney 	"       [--get-active-cpus]\n"
2004c87aefeSPatrick Mooney 	"       [--get-suspended-cpus]\n"
2014c87aefeSPatrick Mooney 	"       [--get-intinfo]\n"
2024c87aefeSPatrick Mooney 	"       [--get-eptp]\n"
2034c87aefeSPatrick Mooney 	"       [--set-exception-bitmap]\n"
2044c87aefeSPatrick Mooney 	"       [--get-exception-bitmap]\n"
2054c87aefeSPatrick Mooney 	"       [--get-tsc-offset]\n"
2064c87aefeSPatrick Mooney 	"       [--get-guest-pat]\n"
2074c87aefeSPatrick Mooney 	"       [--get-io-bitmap-address]\n"
2084c87aefeSPatrick Mooney 	"       [--get-msr-bitmap]\n"
2094c87aefeSPatrick Mooney 	"       [--get-msr-bitmap-address]\n"
2104c87aefeSPatrick Mooney 	"       [--get-guest-sysenter]\n"
2114c87aefeSPatrick Mooney 	"       [--get-exit-reason]\n"
2124c87aefeSPatrick Mooney 	"       [--get-cpu-topology]\n",
213bf21cd93STycho Nightingale 	progname);
2144c87aefeSPatrick Mooney 
2154c87aefeSPatrick Mooney 	if (cpu_intel) {
2164c87aefeSPatrick Mooney 		(void)fprintf(stderr,
2174c87aefeSPatrick Mooney 		"       [--get-vmcs-pinbased-ctls]\n"
2184c87aefeSPatrick Mooney 		"       [--get-vmcs-procbased-ctls]\n"
2194c87aefeSPatrick Mooney 		"       [--get-vmcs-procbased-ctls2]\n"
2204c87aefeSPatrick Mooney 		"       [--get-vmcs-entry-interruption-info]\n"
2214c87aefeSPatrick Mooney 		"       [--set-vmcs-entry-interruption-info=<info>]\n"
2224c87aefeSPatrick Mooney 		"       [--get-vmcs-guest-physical-address\n"
2234c87aefeSPatrick Mooney 		"       [--get-vmcs-guest-linear-address\n"
2244c87aefeSPatrick Mooney 		"       [--get-vmcs-host-pat]\n"
2254c87aefeSPatrick Mooney 		"       [--get-vmcs-host-cr0]\n"
2264c87aefeSPatrick Mooney 		"       [--get-vmcs-host-cr3]\n"
2274c87aefeSPatrick Mooney 		"       [--get-vmcs-host-cr4]\n"
2284c87aefeSPatrick Mooney 		"       [--get-vmcs-host-rip]\n"
2294c87aefeSPatrick Mooney 		"       [--get-vmcs-host-rsp]\n"
2304c87aefeSPatrick Mooney 		"       [--get-vmcs-cr0-mask]\n"
2314c87aefeSPatrick Mooney 		"       [--get-vmcs-cr0-shadow]\n"
2324c87aefeSPatrick Mooney 		"       [--get-vmcs-cr4-mask]\n"
2334c87aefeSPatrick Mooney 		"       [--get-vmcs-cr4-shadow]\n"
2344c87aefeSPatrick Mooney 		"       [--get-vmcs-cr3-targets]\n"
2354c87aefeSPatrick Mooney 		"       [--get-vmcs-apic-access-address]\n"
2364c87aefeSPatrick Mooney 		"       [--get-vmcs-virtual-apic-address]\n"
2374c87aefeSPatrick Mooney 		"       [--get-vmcs-tpr-threshold]\n"
2384c87aefeSPatrick Mooney 		"       [--get-vmcs-vpid]\n"
2394c87aefeSPatrick Mooney 		"       [--get-vmcs-instruction-error]\n"
2404c87aefeSPatrick Mooney 		"       [--get-vmcs-exit-ctls]\n"
2414c87aefeSPatrick Mooney 		"       [--get-vmcs-entry-ctls]\n"
2424c87aefeSPatrick Mooney 		"       [--get-vmcs-link]\n"
2434c87aefeSPatrick Mooney 		"       [--get-vmcs-exit-qualification]\n"
2444c87aefeSPatrick Mooney 		"       [--get-vmcs-exit-interruption-info]\n"
2454c87aefeSPatrick Mooney 		"       [--get-vmcs-exit-interruption-error]\n"
2464c87aefeSPatrick Mooney 		"       [--get-vmcs-interruptibility]\n"
2474c87aefeSPatrick Mooney 		);
2484c87aefeSPatrick Mooney 	} else {
2494c87aefeSPatrick Mooney 		(void)fprintf(stderr,
2504c87aefeSPatrick Mooney 		"       [--get-vmcb-intercepts]\n"
2514c87aefeSPatrick Mooney 		"       [--get-vmcb-asid]\n"
2524c87aefeSPatrick Mooney 		"       [--get-vmcb-exit-details]\n"
2534c87aefeSPatrick Mooney 		"       [--get-vmcb-tlb-ctrl]\n"
2544c87aefeSPatrick Mooney 		"       [--get-vmcb-virq]\n"
2554c87aefeSPatrick Mooney 		"       [--get-avic-apic-bar]\n"
2564c87aefeSPatrick Mooney 		"       [--get-avic-backing-page]\n"
2574c87aefeSPatrick Mooney 		"       [--get-avic-table]\n"
2584c87aefeSPatrick Mooney 		);
2594c87aefeSPatrick Mooney 	}
260bf21cd93STycho Nightingale 	exit(1);
261bf21cd93STycho Nightingale }
262bf21cd93STycho Nightingale 
2634c87aefeSPatrick Mooney static int get_rtc_time, set_rtc_time;
2644c87aefeSPatrick Mooney static int get_rtc_nvram, set_rtc_nvram;
2654c87aefeSPatrick Mooney static int rtc_nvram_offset;
2664c87aefeSPatrick Mooney static uint8_t rtc_nvram_value;
2674c87aefeSPatrick Mooney static time_t rtc_secs;
2684c87aefeSPatrick Mooney 
2694c87aefeSPatrick Mooney static int get_stats, getcap, setcap, capval, get_gpa_pmap;
2704c87aefeSPatrick Mooney static int inject_nmi, assert_lapic_lvt;
2714c87aefeSPatrick Mooney static int force_reset, force_poweroff;
272bf21cd93STycho Nightingale static const char *capname;
2734c87aefeSPatrick Mooney static int create, destroy, get_memmap, get_memseg;
2744c87aefeSPatrick Mooney static int get_intinfo;
2754c87aefeSPatrick Mooney static int get_active_cpus, get_suspended_cpus;
276bf21cd93STycho Nightingale static uint64_t memsize;
2774c87aefeSPatrick Mooney static int set_cr0, get_cr0, set_cr2, get_cr2, set_cr3, get_cr3;
2784c87aefeSPatrick Mooney static int set_cr4, get_cr4;
279bf21cd93STycho Nightingale static int set_efer, get_efer;
2804c87aefeSPatrick Mooney static int set_dr0, get_dr0;
2814c87aefeSPatrick Mooney static int set_dr1, get_dr1;
2824c87aefeSPatrick Mooney static int set_dr2, get_dr2;
2834c87aefeSPatrick Mooney static int set_dr3, get_dr3;
2844c87aefeSPatrick Mooney static int set_dr6, get_dr6;
285bf21cd93STycho Nightingale static int set_dr7, get_dr7;
286bf21cd93STycho Nightingale static int set_rsp, get_rsp, set_rip, get_rip, set_rflags, get_rflags;
287bf21cd93STycho Nightingale static int set_rax, get_rax;
288bf21cd93STycho Nightingale static int get_rbx, get_rcx, get_rdx, get_rsi, get_rdi, get_rbp;
289bf21cd93STycho Nightingale static int get_r8, get_r9, get_r10, get_r11, get_r12, get_r13, get_r14, get_r15;
290bf21cd93STycho Nightingale static int set_desc_ds, get_desc_ds;
291bf21cd93STycho Nightingale static int set_desc_es, get_desc_es;
292bf21cd93STycho Nightingale static int set_desc_fs, get_desc_fs;
293bf21cd93STycho Nightingale static int set_desc_gs, get_desc_gs;
294bf21cd93STycho Nightingale static int set_desc_cs, get_desc_cs;
295bf21cd93STycho Nightingale static int set_desc_ss, get_desc_ss;
296bf21cd93STycho Nightingale static int set_desc_gdtr, get_desc_gdtr;
297bf21cd93STycho Nightingale static int set_desc_idtr, get_desc_idtr;
298bf21cd93STycho Nightingale static int set_desc_tr, get_desc_tr;
299bf21cd93STycho Nightingale static int set_desc_ldtr, get_desc_ldtr;
300bf21cd93STycho Nightingale static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr;
301bf21cd93STycho Nightingale static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr;
302bf21cd93STycho Nightingale static int set_x2apic_state, get_x2apic_state;
303bf21cd93STycho Nightingale enum x2apic_state x2apic_state;
304bf21cd93STycho Nightingale static int run;
3054c87aefeSPatrick Mooney static int get_cpu_topology;
3060e1453c3SPatrick Mooney static int pmtmr_port;
3074c87aefeSPatrick Mooney static int wrlock_cycle;
308957246c9SPatrick Mooney static int get_fpu;
3094c87aefeSPatrick Mooney 
3104c87aefeSPatrick Mooney /*
3114c87aefeSPatrick Mooney  * VMCB specific.
3124c87aefeSPatrick Mooney  */
3134c87aefeSPatrick Mooney static int get_vmcb_intercept, get_vmcb_exit_details, get_vmcb_tlb_ctrl;
3144c87aefeSPatrick Mooney static int get_vmcb_virq, get_avic_table;
315bf21cd93STycho Nightingale 
316bf21cd93STycho Nightingale /*
317bf21cd93STycho Nightingale  * VMCS-specific fields
318bf21cd93STycho Nightingale  */
319bf21cd93STycho Nightingale static int get_pinbased_ctls, get_procbased_ctls, get_procbased_ctls2;
320bf21cd93STycho Nightingale static int get_eptp, get_io_bitmap, get_tsc_offset;
321bf21cd93STycho Nightingale static int get_vmcs_entry_interruption_info, set_vmcs_entry_interruption_info;
322bf21cd93STycho Nightingale static int get_vmcs_interruptibility;
323bf21cd93STycho Nightingale uint32_t vmcs_entry_interruption_info;
324bf21cd93STycho Nightingale static int get_vmcs_gpa, get_vmcs_gla;
325bf21cd93STycho Nightingale static int get_exception_bitmap, set_exception_bitmap, exception_bitmap;
326bf21cd93STycho Nightingale static int get_cr0_mask, get_cr0_shadow;
327bf21cd93STycho Nightingale static int get_cr4_mask, get_cr4_shadow;
328bf21cd93STycho Nightingale static int get_cr3_targets;
329bf21cd93STycho Nightingale static int get_apic_access_addr, get_virtual_apic_addr, get_tpr_threshold;
330bf21cd93STycho Nightingale static int get_msr_bitmap, get_msr_bitmap_address;
331*54cf5b63SPatrick Mooney static int get_guest_msrs;
3324c87aefeSPatrick Mooney static int get_vpid_asid;
333bf21cd93STycho Nightingale static int get_inst_err, get_exit_ctls, get_entry_ctls;
334bf21cd93STycho Nightingale static int get_host_cr0, get_host_cr3, get_host_cr4;
335bf21cd93STycho Nightingale static int get_host_rip, get_host_rsp;
336*54cf5b63SPatrick Mooney static int get_host_pat;
337*54cf5b63SPatrick Mooney static int get_vmcs_link;
3384c87aefeSPatrick Mooney static int get_exit_reason, get_vmcs_exit_qualification;
339bf21cd93STycho Nightingale static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error;
3404c87aefeSPatrick Mooney static int get_vmcs_exit_inst_length;
341bf21cd93STycho Nightingale 
342bf21cd93STycho Nightingale static uint64_t desc_base;
343bf21cd93STycho Nightingale static uint32_t desc_limit, desc_access;
344bf21cd93STycho Nightingale 
345bf21cd93STycho Nightingale static int get_all;
346bf21cd93STycho Nightingale 
347bf21cd93STycho Nightingale static void
dump_vm_run_exitcode(struct vm_exit * vmexit,int vcpu)348bf21cd93STycho Nightingale dump_vm_run_exitcode(struct vm_exit *vmexit, int vcpu)
349bf21cd93STycho Nightingale {
350bf21cd93STycho Nightingale 	printf("vm exit[%d]\n", vcpu);
351bf21cd93STycho Nightingale 	printf("\trip\t\t0x%016lx\n", vmexit->rip);
352bf21cd93STycho Nightingale 	printf("\tinst_length\t%d\n", vmexit->inst_length);
353bf21cd93STycho Nightingale 	switch (vmexit->exitcode) {
354bf21cd93STycho Nightingale 	case VM_EXITCODE_INOUT:
355bf21cd93STycho Nightingale 		printf("\treason\t\tINOUT\n");
356e0c0d44eSPatrick Mooney 		printf("\tdirection\t%s\n",
357e0c0d44eSPatrick Mooney 		    (vmexit->u.inout.flags & INOUT_IN) ? "IN" : "OUT");
358bf21cd93STycho Nightingale 		printf("\tbytes\t\t%d\n", vmexit->u.inout.bytes);
359bf21cd93STycho Nightingale 		printf("\tport\t\t0x%04x\n", vmexit->u.inout.port);
360bf21cd93STycho Nightingale 		printf("\teax\t\t0x%08x\n", vmexit->u.inout.eax);
361bf21cd93STycho Nightingale 		break;
362e0c0d44eSPatrick Mooney 	case VM_EXITCODE_MMIO:
363e0c0d44eSPatrick Mooney 		printf("\treason\t\tMMIO\n");
364e0c0d44eSPatrick Mooney 		printf("\toperation\t%s\n",
365e0c0d44eSPatrick Mooney 		    vmexit->u.mmio.read ? "READ" : "WRITE");
366e0c0d44eSPatrick Mooney 		printf("\tbytes\t\t%d\n", vmexit->u.mmio.bytes);
367e0c0d44eSPatrick Mooney 		printf("\tgpa\t\t0x%08x\n", vmexit->u.mmio.gpa);
368e0c0d44eSPatrick Mooney 		printf("\tdata\t\t0x%08x\n", vmexit->u.mmio.data);
369e0c0d44eSPatrick Mooney 		break;
370bf21cd93STycho Nightingale 	case VM_EXITCODE_VMX:
371bf21cd93STycho Nightingale 		printf("\treason\t\tVMX\n");
372bf21cd93STycho Nightingale 		printf("\tstatus\t\t%d\n", vmexit->u.vmx.status);
373bf21cd93STycho Nightingale 		printf("\texit_reason\t0x%08x (%u)\n",
374bf21cd93STycho Nightingale 		    vmexit->u.vmx.exit_reason, vmexit->u.vmx.exit_reason);
375bf21cd93STycho Nightingale 		printf("\tqualification\t0x%016lx\n",
376bf21cd93STycho Nightingale 			vmexit->u.vmx.exit_qualification);
377bf21cd93STycho Nightingale 		printf("\tinst_type\t\t%d\n", vmexit->u.vmx.inst_type);
378bf21cd93STycho Nightingale 		printf("\tinst_error\t\t%d\n", vmexit->u.vmx.inst_error);
379bf21cd93STycho Nightingale 		break;
3804c87aefeSPatrick Mooney 	case VM_EXITCODE_SVM:
3814c87aefeSPatrick Mooney 		printf("\treason\t\tSVM\n");
3824c87aefeSPatrick Mooney 		printf("\texit_reason\t\t%#lx\n", vmexit->u.svm.exitcode);
3834c87aefeSPatrick Mooney 		printf("\texitinfo1\t\t%#lx\n", vmexit->u.svm.exitinfo1);
3844c87aefeSPatrick Mooney 		printf("\texitinfo2\t\t%#lx\n", vmexit->u.svm.exitinfo2);
3854c87aefeSPatrick Mooney 		break;
386bf21cd93STycho Nightingale 	default:
387bf21cd93STycho Nightingale 		printf("*** unknown vm run exitcode %d\n", vmexit->exitcode);
388bf21cd93STycho Nightingale 		break;
389bf21cd93STycho Nightingale 	}
390bf21cd93STycho Nightingale }
391bf21cd93STycho Nightingale 
3924c87aefeSPatrick Mooney /* AMD 6th generation and Intel compatible MSRs */
3934c87aefeSPatrick Mooney #define MSR_AMD6TH_START	0xC0000000
3944c87aefeSPatrick Mooney #define MSR_AMD6TH_END		0xC0001FFF
3954c87aefeSPatrick Mooney /* AMD 7th and 8th generation compatible MSRs */
3964c87aefeSPatrick Mooney #define MSR_AMD7TH_START	0xC0010000
3974c87aefeSPatrick Mooney #define MSR_AMD7TH_END		0xC0011FFF
3984c87aefeSPatrick Mooney 
399*54cf5b63SPatrick Mooney /* Until a safe method is created, arbitrary VMCS reads/writes are forbidden */
400007ca332SPatrick Mooney static int
vm_get_vmcs_field(struct vmctx * ctx,int vcpu,int field,uint64_t * ret_val)401007ca332SPatrick Mooney vm_get_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t *ret_val)
402007ca332SPatrick Mooney {
403007ca332SPatrick Mooney 	*ret_val = 0;
404007ca332SPatrick Mooney 	return (0);
405007ca332SPatrick Mooney }
406007ca332SPatrick Mooney 
407007ca332SPatrick Mooney static int
vm_set_vmcs_field(struct vmctx * ctx,int vcpu,int field,uint64_t val)408007ca332SPatrick Mooney vm_set_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t val)
409007ca332SPatrick Mooney {
410007ca332SPatrick Mooney 	return (EINVAL);
411007ca332SPatrick Mooney }
4124c87aefeSPatrick Mooney 
413*54cf5b63SPatrick Mooney /* Until a safe method is created, arbitrary VMCB reads/writes are forbidden */
414096bb5cbSPatrick Mooney static int
vm_get_vmcb_field(struct vmctx * ctx,int vcpu,int off,int bytes,uint64_t * ret_val)415096bb5cbSPatrick Mooney vm_get_vmcb_field(struct vmctx *ctx, int vcpu, int off, int bytes,
416*54cf5b63SPatrick Mooney     uint64_t *ret_val)
417096bb5cbSPatrick Mooney {
418096bb5cbSPatrick Mooney 	*ret_val = 0;
419096bb5cbSPatrick Mooney 	return (0);
420096bb5cbSPatrick Mooney }
421096bb5cbSPatrick Mooney 
422096bb5cbSPatrick Mooney static int
vm_set_vmcb_field(struct vmctx * ctx,int vcpu,int off,int bytes,uint64_t val)423096bb5cbSPatrick Mooney vm_set_vmcb_field(struct vmctx *ctx, int vcpu, int off, int bytes,
424*54cf5b63SPatrick Mooney     uint64_t val)
425096bb5cbSPatrick Mooney {
426096bb5cbSPatrick Mooney 	return (EINVAL);
427096bb5cbSPatrick Mooney }
4284c87aefeSPatrick Mooney 
429bf21cd93STycho Nightingale enum {
430bf21cd93STycho Nightingale 	VMNAME = 1000,	/* avoid collision with return values from getopt */
431bf21cd93STycho Nightingale 	VCPU,
432bf21cd93STycho Nightingale 	SET_MEM,
433bf21cd93STycho Nightingale 	SET_EFER,
434bf21cd93STycho Nightingale 	SET_CR0,
4354c87aefeSPatrick Mooney 	SET_CR2,
436bf21cd93STycho Nightingale 	SET_CR3,
437bf21cd93STycho Nightingale 	SET_CR4,
4384c87aefeSPatrick Mooney 	SET_DR0,
4394c87aefeSPatrick Mooney 	SET_DR1,
4404c87aefeSPatrick Mooney 	SET_DR2,
4414c87aefeSPatrick Mooney 	SET_DR3,
4424c87aefeSPatrick Mooney 	SET_DR6,
443bf21cd93STycho Nightingale 	SET_DR7,
444bf21cd93STycho Nightingale 	SET_RSP,
445bf21cd93STycho Nightingale 	SET_RIP,
446bf21cd93STycho Nightingale 	SET_RAX,
447bf21cd93STycho Nightingale 	SET_RFLAGS,
448bf21cd93STycho Nightingale 	DESC_BASE,
449bf21cd93STycho Nightingale 	DESC_LIMIT,
450bf21cd93STycho Nightingale 	DESC_ACCESS,
451bf21cd93STycho Nightingale 	SET_CS,
452bf21cd93STycho Nightingale 	SET_DS,
453bf21cd93STycho Nightingale 	SET_ES,
454bf21cd93STycho Nightingale 	SET_FS,
455bf21cd93STycho Nightingale 	SET_GS,
456bf21cd93STycho Nightingale 	SET_SS,
457bf21cd93STycho Nightingale 	SET_TR,
458bf21cd93STycho Nightingale 	SET_LDTR,
459bf21cd93STycho Nightingale 	SET_X2APIC_STATE,
4604c87aefeSPatrick Mooney 	SET_EXCEPTION_BITMAP,
461bf21cd93STycho Nightingale 	SET_VMCS_ENTRY_INTERRUPTION_INFO,
462bf21cd93STycho Nightingale 	SET_CAP,
463bf21cd93STycho Nightingale 	CAPNAME,
464bf21cd93STycho Nightingale 	UNASSIGN_PPTDEV,
4654c87aefeSPatrick Mooney 	GET_GPA_PMAP,
4664c87aefeSPatrick Mooney 	ASSERT_LAPIC_LVT,
4674c87aefeSPatrick Mooney 	SET_RTC_TIME,
4684c87aefeSPatrick Mooney 	SET_RTC_NVRAM,
4694c87aefeSPatrick Mooney 	RTC_NVRAM_OFFSET,
4700e1453c3SPatrick Mooney 	PMTMR_PORT,
471bf21cd93STycho Nightingale };
472bf21cd93STycho Nightingale 
4734c87aefeSPatrick Mooney static void
print_cpus(const char * banner,const cpuset_t * cpus)4744c87aefeSPatrick Mooney print_cpus(const char *banner, const cpuset_t *cpus)
475bf21cd93STycho Nightingale {
4764c87aefeSPatrick Mooney 	int i;
4774c87aefeSPatrick Mooney 	int first;
4784c87aefeSPatrick Mooney 
4794c87aefeSPatrick Mooney 	first = 1;
4804c87aefeSPatrick Mooney 	printf("%s:\t", banner);
4814c87aefeSPatrick Mooney 	if (!CPU_EMPTY(cpus)) {
4824c87aefeSPatrick Mooney 		for (i = 0; i < CPU_SETSIZE; i++) {
4834c87aefeSPatrick Mooney 			if (CPU_ISSET(i, cpus)) {
4844c87aefeSPatrick Mooney 				printf("%s%d", first ? " " : ", ", i);
4854c87aefeSPatrick Mooney 				first = 0;
4864c87aefeSPatrick Mooney 			}
4874c87aefeSPatrick Mooney 		}
4884c87aefeSPatrick Mooney 	} else
4894c87aefeSPatrick Mooney 		printf(" (none)");
4904c87aefeSPatrick Mooney 	printf("\n");
4914c87aefeSPatrick Mooney }
4924c87aefeSPatrick Mooney 
4933d097f7dSPatrick Mooney static void
print_intinfo(const char * banner,uint64_t info)4943d097f7dSPatrick Mooney print_intinfo(const char *banner, uint64_t info)
4953d097f7dSPatrick Mooney {
4963d097f7dSPatrick Mooney 	printf("%s:\t", banner);
4973d097f7dSPatrick Mooney 	if (VM_INTINFO_PENDING(info)) {
4983d097f7dSPatrick Mooney 		switch (VM_INTINFO_TYPE(info)) {
4993d097f7dSPatrick Mooney 		case VM_INTINFO_HWINTR:
5003d097f7dSPatrick Mooney 			printf("extint");
5013d097f7dSPatrick Mooney 			break;
5023d097f7dSPatrick Mooney 		case VM_INTINFO_NMI:
5033d097f7dSPatrick Mooney 			printf("nmi");
5043d097f7dSPatrick Mooney 			break;
5053d097f7dSPatrick Mooney 		case VM_INTINFO_SWINTR:
5063d097f7dSPatrick Mooney 			printf("swint");
5073d097f7dSPatrick Mooney 			break;
5083d097f7dSPatrick Mooney 		default:
5093d097f7dSPatrick Mooney 			printf("exception");
5103d097f7dSPatrick Mooney 			break;
5113d097f7dSPatrick Mooney 		}
5123d097f7dSPatrick Mooney 		printf(" vector %hhd", VM_INTINFO_VECTOR(info));
5133d097f7dSPatrick Mooney 		if (VM_INTINFO_HAS_ERRCODE(info)) {
5143d097f7dSPatrick Mooney 			printf(" errcode %#x", VM_INTINFO_ERRCODE(info));
5153d097f7dSPatrick Mooney 		}
5163d097f7dSPatrick Mooney 	} else {
5173d097f7dSPatrick Mooney 		printf("n/a");
5183d097f7dSPatrick Mooney 	}
5193d097f7dSPatrick Mooney 	printf("\n");
5203d097f7dSPatrick Mooney }
521bf21cd93STycho Nightingale 
5224c87aefeSPatrick Mooney static bool
cpu_vendor_intel(void)5234c87aefeSPatrick Mooney cpu_vendor_intel(void)
5244c87aefeSPatrick Mooney {
5254c87aefeSPatrick Mooney 	u_int regs[4];
5264c87aefeSPatrick Mooney 	char cpu_vendor[13];
5274c87aefeSPatrick Mooney 
5284c87aefeSPatrick Mooney 	do_cpuid(0, regs);
5294c87aefeSPatrick Mooney 	((u_int *)&cpu_vendor)[0] = regs[1];
5304c87aefeSPatrick Mooney 	((u_int *)&cpu_vendor)[1] = regs[3];
5314c87aefeSPatrick Mooney 	((u_int *)&cpu_vendor)[2] = regs[2];
5324c87aefeSPatrick Mooney 	cpu_vendor[12] = '\0';
5334c87aefeSPatrick Mooney 
5344c87aefeSPatrick Mooney 	if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
5354c87aefeSPatrick Mooney 		return (false);
536154972afSPatrick Mooney 	} else if (strcmp(cpu_vendor, "HygonGenuine") == 0) {
537154972afSPatrick Mooney 		return (false);
5384c87aefeSPatrick Mooney 	} else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
5394c87aefeSPatrick Mooney 		return (true);
5404c87aefeSPatrick Mooney 	} else {
5414c87aefeSPatrick Mooney 		fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor);
5424c87aefeSPatrick Mooney 		exit(1);
5434c87aefeSPatrick Mooney 	}
5444c87aefeSPatrick Mooney }
5454c87aefeSPatrick Mooney 
5464c87aefeSPatrick Mooney static int
get_all_registers(struct vmctx * ctx,int vcpu)5474c87aefeSPatrick Mooney get_all_registers(struct vmctx *ctx, int vcpu)
5484c87aefeSPatrick Mooney {
5494c87aefeSPatrick Mooney 	uint64_t cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7;
5504c87aefeSPatrick Mooney 	uint64_t rsp, rip, rflags, efer;
551bf21cd93STycho Nightingale 	uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp;
552bf21cd93STycho Nightingale 	uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
5534c87aefeSPatrick Mooney 	int error = 0;
554bf21cd93STycho Nightingale 
5554c87aefeSPatrick Mooney 	if (!error && (get_efer || get_all)) {
5564c87aefeSPatrick Mooney 		error = vm_get_register(ctx, vcpu,