Path: blob/main/usr.sbin/bhyvectl/amd64/bhyvectl_machdep.c
108736 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2011 NetApp, Inc.4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728#include <sys/types.h>29#include <sys/mman.h>3031#include <machine/cpufunc.h>32#include <machine/specialreg.h>3334#include <err.h>35#include <fcntl.h>36#include <getopt.h>37#include <stdbool.h>38#include <stdio.h>39#include <stdlib.h>40#include <string.h>41#include <time.h>42#include <unistd.h>4344#include <vmmapi.h>45#include "amd/vmcb.h"46#include "intel/vmcs.h"4748#include "bhyvectl.h"4950enum {51SET_EFER = OPT_START_MD,52SET_CR0,53SET_CR2,54SET_CR3,55SET_CR4,56SET_DR0,57SET_DR1,58SET_DR2,59SET_DR3,60SET_DR6,61SET_DR7,62SET_RSP,63SET_RIP,64SET_RAX,65SET_RFLAGS,66DESC_BASE,67DESC_LIMIT,68DESC_ACCESS,69SET_CS,70SET_DS,71SET_ES,72SET_FS,73SET_GS,74SET_SS,75SET_TR,76SET_LDTR,77SET_X2APIC_STATE,78UNASSIGN_PPTDEV,79GET_GPA_PMAP,80ASSERT_LAPIC_LVT,81SET_RTC_TIME,82SET_RTC_NVRAM,83RTC_NVRAM_OFFSET,84};8586static int get_rtc_time, set_rtc_time;87static int get_rtc_nvram, set_rtc_nvram;88static int rtc_nvram_offset;89static uint8_t rtc_nvram_value;90static time_t rtc_secs;91static int get_gpa_pmap;92static vm_paddr_t gpa_pmap;93static int inject_nmi, assert_lapic_lvt = -1;94static int get_intinfo;95static int set_cr0, get_cr0, set_cr2, get_cr2, set_cr3, get_cr3;96static int set_cr4, get_cr4;97static uint64_t set_cr0_val, set_cr2_val, set_cr3_val, set_cr4_val;98static int set_efer, get_efer;99static uint64_t set_efer_val;100static int set_dr0, get_dr0;101static int set_dr1, get_dr1;102static int set_dr2, get_dr2;103static int set_dr3, get_dr3;104static int set_dr6, get_dr6;105static int set_dr7, get_dr7;106static uint64_t set_dr0_val, set_dr1_val, set_dr2_val, set_dr3_val, set_dr6_val;107static uint64_t set_dr7_val;108static int set_rsp, get_rsp, set_rip, get_rip, set_rflags, get_rflags;109static int set_rax, get_rax;110static uint64_t set_rsp_val, set_rip_val, set_rflags_val, set_rax_val;111static int get_rbx, get_rcx, get_rdx, get_rsi, get_rdi, get_rbp;112static int get_r8, get_r9, get_r10, get_r11, get_r12, get_r13, get_r14, get_r15;113static int set_desc_ds, get_desc_ds;114static int set_desc_es, get_desc_es;115static int set_desc_fs, get_desc_fs;116static int set_desc_gs, get_desc_gs;117static int set_desc_cs, get_desc_cs;118static int set_desc_ss, get_desc_ss;119static int set_desc_gdtr, get_desc_gdtr;120static int set_desc_idtr, get_desc_idtr;121static int set_desc_tr, get_desc_tr;122static int set_desc_ldtr, get_desc_ldtr;123static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr;124static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr;125static uint64_t set_cs_val, set_ds_val, set_es_val, set_fs_val, set_gs_val;126static uint64_t set_ss_val, set_tr_val, set_ldtr_val;127static int set_x2apic_state, get_x2apic_state;128static enum x2apic_state x2apic_state;129static int unassign_pptdev, bus, slot, func;130131static uint64_t desc_base;132static uint32_t desc_limit, desc_access;133134/*135* VMCB specific.136*/137static int get_vmcb_intercept, get_vmcb_exit_details, get_vmcb_tlb_ctrl;138static int get_vmcb_virq, get_avic_table;139140/*141* VMCS-specific fields142*/143static int get_pinbased_ctls, get_procbased_ctls, get_procbased_ctls2;144static int get_eptp, get_io_bitmap, get_tsc_offset;145static int get_vmcs_entry_interruption_info;146static int get_vmcs_interruptibility;147static int get_vmcs_gpa, get_vmcs_gla;148static int get_exception_bitmap;149static int get_cr0_mask, get_cr0_shadow;150static int get_cr4_mask, get_cr4_shadow;151static int get_cr3_targets;152static int get_apic_access_addr, get_virtual_apic_addr, get_tpr_threshold;153static int get_msr_bitmap, get_msr_bitmap_address;154static int get_vpid_asid;155static int get_inst_err, get_exit_ctls, get_entry_ctls;156static int get_host_cr0, get_host_cr3, get_host_cr4;157static int get_host_rip, get_host_rsp;158static int get_guest_pat, get_host_pat;159static int get_guest_sysenter, get_vmcs_link;160static int get_exit_reason, get_vmcs_exit_qualification;161static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error;162static int get_vmcs_exit_inst_length;163164static bool165cpu_vendor_intel(void)166{167u_int regs[4], v[3];168169do_cpuid(0, regs);170v[0] = regs[1];171v[1] = regs[3];172v[2] = regs[2];173174if (memcmp(v, "GenuineIntel", sizeof(v)) == 0)175return (true);176if (memcmp(v, "AuthenticAMD", sizeof(v)) == 0 ||177memcmp(v, "HygonGenuine", sizeof(v)) == 0)178return (false);179fprintf(stderr, "Unknown cpu vendor \"%s\"\n", (const char *)v);180exit(1);181}182183void184bhyvectl_dump_vm_run_exitcode(struct vm_exit *vmexit, int vcpu)185{186printf("vm exit[%d]\n", vcpu);187printf("\trip\t\t0x%016lx\n", vmexit->rip);188printf("\tinst_length\t%d\n", vmexit->inst_length);189switch (vmexit->exitcode) {190case VM_EXITCODE_INOUT:191printf("\treason\t\tINOUT\n");192printf("\tdirection\t%s\n", vmexit->u.inout.in ? "IN" : "OUT");193printf("\tbytes\t\t%d\n", vmexit->u.inout.bytes);194printf("\tflags\t\t%s%s\n",195vmexit->u.inout.string ? "STRING " : "",196vmexit->u.inout.rep ? "REP " : "");197printf("\tport\t\t0x%04x\n", vmexit->u.inout.port);198printf("\teax\t\t0x%08x\n", vmexit->u.inout.eax);199break;200case VM_EXITCODE_VMX:201printf("\treason\t\tVMX\n");202printf("\tstatus\t\t%d\n", vmexit->u.vmx.status);203printf("\texit_reason\t0x%08x (%u)\n",204vmexit->u.vmx.exit_reason, vmexit->u.vmx.exit_reason);205printf("\tqualification\t0x%016lx\n",206vmexit->u.vmx.exit_qualification);207printf("\tinst_type\t\t%d\n", vmexit->u.vmx.inst_type);208printf("\tinst_error\t\t%d\n", vmexit->u.vmx.inst_error);209break;210case VM_EXITCODE_SVM:211printf("\treason\t\tSVM\n");212printf("\texit_reason\t\t%#lx\n", vmexit->u.svm.exitcode);213printf("\texitinfo1\t\t%#lx\n", vmexit->u.svm.exitinfo1);214printf("\texitinfo2\t\t%#lx\n", vmexit->u.svm.exitinfo2);215break;216default:217printf("*** unknown vm run exitcode %d\n", vmexit->exitcode);218break;219}220}221222static const char *223wday_str(int idx)224{225static const char *weekdays[] = {226"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"227};228229if (idx >= 0 && idx < 7)230return (weekdays[idx]);231else232return ("UNK");233}234235static const char *236mon_str(int idx)237{238static const char *months[] = {239"Jan", "Feb", "Mar", "Apr", "May", "Jun",240"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"241};242243if (idx >= 0 && idx < 12)244return (months[idx]);245else246return ("UNK");247}248249static void250print_intinfo(const char *banner, uint64_t info)251{252int type;253254printf("%s:\t", banner);255if (info & VM_INTINFO_VALID) {256type = info & VM_INTINFO_TYPE;257switch (type) {258case VM_INTINFO_HWINTR:259printf("extint");260break;261case VM_INTINFO_NMI:262printf("nmi");263break;264case VM_INTINFO_SWINTR:265printf("swint");266break;267default:268printf("exception");269break;270}271printf(" vector %d", (int)VM_INTINFO_VECTOR(info));272if (info & VM_INTINFO_DEL_ERRCODE)273printf(" errcode %#x", (u_int)(info >> 32));274} else {275printf("n/a");276}277printf("\n");278}279280/* AMD 6th generation and Intel compatible MSRs */281#define MSR_AMD6TH_START 0xC0000000282#define MSR_AMD6TH_END 0xC0001FFF283/* AMD 7th and 8th generation compatible MSRs */284#define MSR_AMD7TH_START 0xC0010000285#define MSR_AMD7TH_END 0xC0011FFF286287static const char *288msr_name(uint32_t msr)289{290static char buf[32];291292switch (msr) {293case MSR_TSC:294return ("MSR_TSC");295case MSR_EFER:296return ("MSR_EFER");297case MSR_STAR:298return ("MSR_STAR");299case MSR_LSTAR:300return ("MSR_LSTAR");301case MSR_CSTAR:302return ("MSR_CSTAR");303case MSR_SF_MASK:304return ("MSR_SF_MASK");305case MSR_FSBASE:306return ("MSR_FSBASE");307case MSR_GSBASE:308return ("MSR_GSBASE");309case MSR_KGSBASE:310return ("MSR_KGSBASE");311case MSR_SYSENTER_CS_MSR:312return ("MSR_SYSENTER_CS_MSR");313case MSR_SYSENTER_ESP_MSR:314return ("MSR_SYSENTER_ESP_MSR");315case MSR_SYSENTER_EIP_MSR:316return ("MSR_SYSENTER_EIP_MSR");317case MSR_PAT:318return ("MSR_PAT");319}320snprintf(buf, sizeof(buf), "MSR %#08x", msr);321322return (buf);323}324325static inline void326print_msr_pm(uint64_t msr, int vcpu, int readable, int writeable)327{328329if (readable || writeable) {330printf("%-20s[%d]\t\t%c%c\n", msr_name(msr), vcpu,331readable ? 'R' : '-', writeable ? 'W' : '-');332}333}334335/*336* Reference APM vol2, section 15.11 MSR Intercepts.337*/338static void339dump_amd_msr_pm(const char *bitmap, int vcpu)340{341int byte, bit, readable, writeable;342uint32_t msr;343344for (msr = 0; msr < 0x2000; msr++) {345byte = msr / 4;346bit = (msr % 4) * 2;347348/* Look at MSRs in the range 0x00000000 to 0x00001FFF */349readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;350writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1;351print_msr_pm(msr, vcpu, readable, writeable);352353/* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */354byte += 2048;355readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;356writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1;357print_msr_pm(msr + MSR_AMD6TH_START, vcpu, readable,358writeable);359360/* MSR 0xC0010000 to 0xC0011FF is only for AMD */361byte += 4096;362readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;363writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1;364print_msr_pm(msr + MSR_AMD7TH_START, vcpu, readable,365writeable);366}367}368369/*370* Reference Intel SDM Vol3 Section 24.6.9 MSR-Bitmap Address371*/372static void373dump_intel_msr_pm(const char *bitmap, int vcpu)374{375int byte, bit, readable, writeable;376uint32_t msr;377378for (msr = 0; msr < 0x2000; msr++) {379byte = msr / 8;380bit = msr & 0x7;381382/* Look at MSRs in the range 0x00000000 to 0x00001FFF */383readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;384writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1;385print_msr_pm(msr, vcpu, readable, writeable);386387/* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */388byte += 1024;389readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;390writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1;391print_msr_pm(msr + MSR_AMD6TH_START, vcpu, readable,392writeable);393}394}395396static int397dump_msr_bitmap(int vcpu, uint64_t addr, bool cpu_intel)398{399char *bitmap;400int error, fd, map_size;401402error = -1;403bitmap = MAP_FAILED;404405fd = open("/dev/mem", O_RDONLY, 0);406if (fd < 0) {407perror("Couldn't open /dev/mem");408goto done;409}410411if (cpu_intel)412map_size = PAGE_SIZE;413else414map_size = 2 * PAGE_SIZE;415416bitmap = mmap(NULL, map_size, PROT_READ, MAP_SHARED, fd, addr);417if (bitmap == MAP_FAILED) {418perror("mmap failed");419goto done;420}421422if (cpu_intel)423dump_intel_msr_pm(bitmap, vcpu);424else425dump_amd_msr_pm(bitmap, vcpu);426427error = 0;428done:429if (bitmap != MAP_FAILED)430munmap((void *)bitmap, map_size);431if (fd >= 0)432close(fd);433434return (error);435}436437static int438vm_get_vmcs_field(struct vcpu *vcpu, int field, uint64_t *ret_val)439{440441return (vm_get_register(vcpu, VMCS_IDENT(field), ret_val));442}443444static int445vm_get_vmcb_field(struct vcpu *vcpu, int off, int bytes,446uint64_t *ret_val)447{448449return (vm_get_register(vcpu, VMCB_ACCESS(off, bytes), ret_val));450}451452static int453get_all_registers(struct vcpu *vcpu, int vcpuid, bool get_all)454{455uint64_t cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7;456uint64_t rsp, rip, rflags, efer;457uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp;458uint64_t r8, r9, r10, r11, r12, r13, r14, r15;459int error = 0;460461if (!error && (get_efer || get_all)) {462error = vm_get_register(vcpu, VM_REG_GUEST_EFER, &efer);463if (error == 0)464printf("efer[%d]\t\t0x%016lx\n", vcpuid, efer);465}466467if (!error && (get_cr0 || get_all)) {468error = vm_get_register(vcpu, VM_REG_GUEST_CR0, &cr0);469if (error == 0)470printf("cr0[%d]\t\t0x%016lx\n", vcpuid, cr0);471}472473if (!error && (get_cr2 || get_all)) {474error = vm_get_register(vcpu, VM_REG_GUEST_CR2, &cr2);475if (error == 0)476printf("cr2[%d]\t\t0x%016lx\n", vcpuid, cr2);477}478479if (!error && (get_cr3 || get_all)) {480error = vm_get_register(vcpu, VM_REG_GUEST_CR3, &cr3);481if (error == 0)482printf("cr3[%d]\t\t0x%016lx\n", vcpuid, cr3);483}484485if (!error && (get_cr4 || get_all)) {486error = vm_get_register(vcpu, VM_REG_GUEST_CR4, &cr4);487if (error == 0)488printf("cr4[%d]\t\t0x%016lx\n", vcpuid, cr4);489}490491if (!error && (get_dr0 || get_all)) {492error = vm_get_register(vcpu, VM_REG_GUEST_DR0, &dr0);493if (error == 0)494printf("dr0[%d]\t\t0x%016lx\n", vcpuid, dr0);495}496497if (!error && (get_dr1 || get_all)) {498error = vm_get_register(vcpu, VM_REG_GUEST_DR1, &dr1);499if (error == 0)500printf("dr1[%d]\t\t0x%016lx\n", vcpuid, dr1);501}502503if (!error && (get_dr2 || get_all)) {504error = vm_get_register(vcpu, VM_REG_GUEST_DR2, &dr2);505if (error == 0)506printf("dr2[%d]\t\t0x%016lx\n", vcpuid, dr2);507}508509if (!error && (get_dr3 || get_all)) {510error = vm_get_register(vcpu, VM_REG_GUEST_DR3, &dr3);511if (error == 0)512printf("dr3[%d]\t\t0x%016lx\n", vcpuid, dr3);513}514515if (!error && (get_dr6 || get_all)) {516error = vm_get_register(vcpu, VM_REG_GUEST_DR6, &dr6);517if (error == 0)518printf("dr6[%d]\t\t0x%016lx\n", vcpuid, dr6);519}520521if (!error && (get_dr7 || get_all)) {522error = vm_get_register(vcpu, VM_REG_GUEST_DR7, &dr7);523if (error == 0)524printf("dr7[%d]\t\t0x%016lx\n", vcpuid, dr7);525}526527if (!error && (get_rsp || get_all)) {528error = vm_get_register(vcpu, VM_REG_GUEST_RSP, &rsp);529if (error == 0)530printf("rsp[%d]\t\t0x%016lx\n", vcpuid, rsp);531}532533if (!error && (get_rip || get_all)) {534error = vm_get_register(vcpu, VM_REG_GUEST_RIP, &rip);535if (error == 0)536printf("rip[%d]\t\t0x%016lx\n", vcpuid, rip);537}538539if (!error && (get_rax || get_all)) {540error = vm_get_register(vcpu, VM_REG_GUEST_RAX, &rax);541if (error == 0)542printf("rax[%d]\t\t0x%016lx\n", vcpuid, rax);543}544545if (!error && (get_rbx || get_all)) {546error = vm_get_register(vcpu, VM_REG_GUEST_RBX, &rbx);547if (error == 0)548printf("rbx[%d]\t\t0x%016lx\n", vcpuid, rbx);549}550551if (!error && (get_rcx || get_all)) {552error = vm_get_register(vcpu, VM_REG_GUEST_RCX, &rcx);553if (error == 0)554printf("rcx[%d]\t\t0x%016lx\n", vcpuid, rcx);555}556557if (!error && (get_rdx || get_all)) {558error = vm_get_register(vcpu, VM_REG_GUEST_RDX, &rdx);559if (error == 0)560printf("rdx[%d]\t\t0x%016lx\n", vcpuid, rdx);561}562563if (!error && (get_rsi || get_all)) {564error = vm_get_register(vcpu, VM_REG_GUEST_RSI, &rsi);565if (error == 0)566printf("rsi[%d]\t\t0x%016lx\n", vcpuid, rsi);567}568569if (!error && (get_rdi || get_all)) {570error = vm_get_register(vcpu, VM_REG_GUEST_RDI, &rdi);571if (error == 0)572printf("rdi[%d]\t\t0x%016lx\n", vcpuid, rdi);573}574575if (!error && (get_rbp || get_all)) {576error = vm_get_register(vcpu, VM_REG_GUEST_RBP, &rbp);577if (error == 0)578printf("rbp[%d]\t\t0x%016lx\n", vcpuid, rbp);579}580581if (!error && (get_r8 || get_all)) {582error = vm_get_register(vcpu, VM_REG_GUEST_R8, &r8);583if (error == 0)584printf("r8[%d]\t\t0x%016lx\n", vcpuid, r8);585}586587if (!error && (get_r9 || get_all)) {588error = vm_get_register(vcpu, VM_REG_GUEST_R9, &r9);589if (error == 0)590printf("r9[%d]\t\t0x%016lx\n", vcpuid, r9);591}592593if (!error && (get_r10 || get_all)) {594error = vm_get_register(vcpu, VM_REG_GUEST_R10, &r10);595if (error == 0)596printf("r10[%d]\t\t0x%016lx\n", vcpuid, r10);597}598599if (!error && (get_r11 || get_all)) {600error = vm_get_register(vcpu, VM_REG_GUEST_R11, &r11);601if (error == 0)602printf("r11[%d]\t\t0x%016lx\n", vcpuid, r11);603}604605if (!error && (get_r12 || get_all)) {606error = vm_get_register(vcpu, VM_REG_GUEST_R12, &r12);607if (error == 0)608printf("r12[%d]\t\t0x%016lx\n", vcpuid, r12);609}610611if (!error && (get_r13 || get_all)) {612error = vm_get_register(vcpu, VM_REG_GUEST_R13, &r13);613if (error == 0)614printf("r13[%d]\t\t0x%016lx\n", vcpuid, r13);615}616617if (!error && (get_r14 || get_all)) {618error = vm_get_register(vcpu, VM_REG_GUEST_R14, &r14);619if (error == 0)620printf("r14[%d]\t\t0x%016lx\n", vcpuid, r14);621}622623if (!error && (get_r15 || get_all)) {624error = vm_get_register(vcpu, VM_REG_GUEST_R15, &r15);625if (error == 0)626printf("r15[%d]\t\t0x%016lx\n", vcpuid, r15);627}628629if (!error && (get_rflags || get_all)) {630error = vm_get_register(vcpu, VM_REG_GUEST_RFLAGS,631&rflags);632if (error == 0)633printf("rflags[%d]\t0x%016lx\n", vcpuid, rflags);634}635636return (error);637}638639static int640get_all_segments(struct vcpu *vcpu, int vcpuid, bool get_all)641{642uint64_t cs, ds, es, fs, gs, ss, tr, ldtr;643int error = 0;644645if (!error && (get_desc_ds || get_all)) {646error = vm_get_desc(vcpu, VM_REG_GUEST_DS,647&desc_base, &desc_limit, &desc_access);648if (error == 0) {649printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n",650vcpuid, desc_base, desc_limit, desc_access);651}652}653654if (!error && (get_desc_es || get_all)) {655error = vm_get_desc(vcpu, VM_REG_GUEST_ES,656&desc_base, &desc_limit, &desc_access);657if (error == 0) {658printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n",659vcpuid, desc_base, desc_limit, desc_access);660}661}662663if (!error && (get_desc_fs || get_all)) {664error = vm_get_desc(vcpu, VM_REG_GUEST_FS,665&desc_base, &desc_limit, &desc_access);666if (error == 0) {667printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",668vcpuid, desc_base, desc_limit, desc_access);669}670}671672if (!error && (get_desc_gs || get_all)) {673error = vm_get_desc(vcpu, VM_REG_GUEST_GS,674&desc_base, &desc_limit, &desc_access);675if (error == 0) {676printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",677vcpuid, desc_base, desc_limit, desc_access);678}679}680681if (!error && (get_desc_ss || get_all)) {682error = vm_get_desc(vcpu, VM_REG_GUEST_SS,683&desc_base, &desc_limit, &desc_access);684if (error == 0) {685printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n",686vcpuid, desc_base, desc_limit, desc_access);687}688}689690if (!error && (get_desc_cs || get_all)) {691error = vm_get_desc(vcpu, VM_REG_GUEST_CS,692&desc_base, &desc_limit, &desc_access);693if (error == 0) {694printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",695vcpuid, desc_base, desc_limit, desc_access);696}697}698699if (!error && (get_desc_tr || get_all)) {700error = vm_get_desc(vcpu, VM_REG_GUEST_TR,701&desc_base, &desc_limit, &desc_access);702if (error == 0) {703printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",704vcpuid, desc_base, desc_limit, desc_access);705}706}707708if (!error && (get_desc_ldtr || get_all)) {709error = vm_get_desc(vcpu, VM_REG_GUEST_LDTR,710&desc_base, &desc_limit, &desc_access);711if (error == 0) {712printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",713vcpuid, desc_base, desc_limit, desc_access);714}715}716717if (!error && (get_desc_gdtr || get_all)) {718error = vm_get_desc(vcpu, VM_REG_GUEST_GDTR,719&desc_base, &desc_limit, &desc_access);720if (error == 0) {721printf("gdtr[%d]\t\t0x%016lx/0x%08x\n",722vcpuid, desc_base, desc_limit);723}724}725726if (!error && (get_desc_idtr || get_all)) {727error = vm_get_desc(vcpu, VM_REG_GUEST_IDTR,728&desc_base, &desc_limit, &desc_access);729if (error == 0) {730printf("idtr[%d]\t\t0x%016lx/0x%08x\n",731vcpuid, desc_base, desc_limit);732}733}734735if (!error && (get_cs || get_all)) {736error = vm_get_register(vcpu, VM_REG_GUEST_CS, &cs);737if (error == 0)738printf("cs[%d]\t\t0x%04lx\n", vcpuid, cs);739}740741if (!error && (get_ds || get_all)) {742error = vm_get_register(vcpu, VM_REG_GUEST_DS, &ds);743if (error == 0)744printf("ds[%d]\t\t0x%04lx\n", vcpuid, ds);745}746747if (!error && (get_es || get_all)) {748error = vm_get_register(vcpu, VM_REG_GUEST_ES, &es);749if (error == 0)750printf("es[%d]\t\t0x%04lx\n", vcpuid, es);751}752753if (!error && (get_fs || get_all)) {754error = vm_get_register(vcpu, VM_REG_GUEST_FS, &fs);755if (error == 0)756printf("fs[%d]\t\t0x%04lx\n", vcpuid, fs);757}758759if (!error && (get_gs || get_all)) {760error = vm_get_register(vcpu, VM_REG_GUEST_GS, &gs);761if (error == 0)762printf("gs[%d]\t\t0x%04lx\n", vcpuid, gs);763}764765if (!error && (get_ss || get_all)) {766error = vm_get_register(vcpu, VM_REG_GUEST_SS, &ss);767if (error == 0)768printf("ss[%d]\t\t0x%04lx\n", vcpuid, ss);769}770771if (!error && (get_tr || get_all)) {772error = vm_get_register(vcpu, VM_REG_GUEST_TR, &tr);773if (error == 0)774printf("tr[%d]\t\t0x%04lx\n", vcpuid, tr);775}776777if (!error && (get_ldtr || get_all)) {778error = vm_get_register(vcpu, VM_REG_GUEST_LDTR, &ldtr);779if (error == 0)780printf("ldtr[%d]\t\t0x%04lx\n", vcpuid, ldtr);781}782783return (error);784}785786static int787get_misc_vmcs(struct vcpu *vcpu, int vcpuid, bool get_all)788{789uint64_t ctl, cr0, cr3, cr4, rsp, rip, pat, addr, u64;790int error = 0;791792if (!error && (get_cr0_mask || get_all)) {793uint64_t cr0mask;794error = vm_get_vmcs_field(vcpu, VMCS_CR0_MASK, &cr0mask);795if (error == 0)796printf("cr0_mask[%d]\t\t0x%016lx\n", vcpuid, cr0mask);797}798799if (!error && (get_cr0_shadow || get_all)) {800uint64_t cr0shadow;801error = vm_get_vmcs_field(vcpu, VMCS_CR0_SHADOW,802&cr0shadow);803if (error == 0)804printf("cr0_shadow[%d]\t\t0x%016lx\n", vcpuid, cr0shadow);805}806807if (!error && (get_cr4_mask || get_all)) {808uint64_t cr4mask;809error = vm_get_vmcs_field(vcpu, VMCS_CR4_MASK, &cr4mask);810if (error == 0)811printf("cr4_mask[%d]\t\t0x%016lx\n", vcpuid, cr4mask);812}813814if (!error && (get_cr4_shadow || get_all)) {815uint64_t cr4shadow;816error = vm_get_vmcs_field(vcpu, VMCS_CR4_SHADOW,817&cr4shadow);818if (error == 0)819printf("cr4_shadow[%d]\t\t0x%016lx\n", vcpuid, cr4shadow);820}821822if (!error && (get_cr3_targets || get_all)) {823uint64_t target_count, target_addr;824error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET_COUNT,825&target_count);826if (error == 0) {827printf("cr3_target_count[%d]\t0x%016lx\n",828vcpuid, target_count);829}830831error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET0,832&target_addr);833if (error == 0) {834printf("cr3_target0[%d]\t\t0x%016lx\n",835vcpuid, target_addr);836}837838error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET1,839&target_addr);840if (error == 0) {841printf("cr3_target1[%d]\t\t0x%016lx\n",842vcpuid, target_addr);843}844845error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET2,846&target_addr);847if (error == 0) {848printf("cr3_target2[%d]\t\t0x%016lx\n",849vcpuid, target_addr);850}851852error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET3,853&target_addr);854if (error == 0) {855printf("cr3_target3[%d]\t\t0x%016lx\n",856vcpuid, target_addr);857}858}859860if (!error && (get_pinbased_ctls || get_all)) {861error = vm_get_vmcs_field(vcpu, VMCS_PIN_BASED_CTLS, &ctl);862if (error == 0)863printf("pinbased_ctls[%d]\t0x%016lx\n", vcpuid, ctl);864}865866if (!error && (get_procbased_ctls || get_all)) {867error = vm_get_vmcs_field(vcpu,868VMCS_PRI_PROC_BASED_CTLS, &ctl);869if (error == 0)870printf("procbased_ctls[%d]\t0x%016lx\n", vcpuid, ctl);871}872873if (!error && (get_procbased_ctls2 || get_all)) {874error = vm_get_vmcs_field(vcpu,875VMCS_SEC_PROC_BASED_CTLS, &ctl);876if (error == 0)877printf("procbased_ctls2[%d]\t0x%016lx\n", vcpuid, ctl);878}879880if (!error && (get_vmcs_gla || get_all)) {881error = vm_get_vmcs_field(vcpu,882VMCS_GUEST_LINEAR_ADDRESS, &u64);883if (error == 0)884printf("gla[%d]\t\t0x%016lx\n", vcpuid, u64);885}886887if (!error && (get_vmcs_gpa || get_all)) {888error = vm_get_vmcs_field(vcpu,889VMCS_GUEST_PHYSICAL_ADDRESS, &u64);890if (error == 0)891printf("gpa[%d]\t\t0x%016lx\n", vcpuid, u64);892}893894if (!error && (get_vmcs_entry_interruption_info ||895get_all)) {896error = vm_get_vmcs_field(vcpu, VMCS_ENTRY_INTR_INFO,&u64);897if (error == 0) {898printf("entry_interruption_info[%d]\t0x%016lx\n",899vcpuid, u64);900}901}902903if (!error && (get_tpr_threshold || get_all)) {904uint64_t threshold;905error = vm_get_vmcs_field(vcpu, VMCS_TPR_THRESHOLD,906&threshold);907if (error == 0)908printf("tpr_threshold[%d]\t0x%016lx\n", vcpuid, threshold);909}910911if (!error && (get_inst_err || get_all)) {912uint64_t insterr;913error = vm_get_vmcs_field(vcpu, VMCS_INSTRUCTION_ERROR,914&insterr);915if (error == 0) {916printf("instruction_error[%d]\t0x%016lx\n",917vcpuid, insterr);918}919}920921if (!error && (get_exit_ctls || get_all)) {922error = vm_get_vmcs_field(vcpu, VMCS_EXIT_CTLS, &ctl);923if (error == 0)924printf("exit_ctls[%d]\t\t0x%016lx\n", vcpuid, ctl);925}926927if (!error && (get_entry_ctls || get_all)) {928error = vm_get_vmcs_field(vcpu, VMCS_ENTRY_CTLS, &ctl);929if (error == 0)930printf("entry_ctls[%d]\t\t0x%016lx\n", vcpuid, ctl);931}932933if (!error && (get_host_pat || get_all)) {934error = vm_get_vmcs_field(vcpu, VMCS_HOST_IA32_PAT, &pat);935if (error == 0)936printf("host_pat[%d]\t\t0x%016lx\n", vcpuid, pat);937}938939if (!error && (get_host_cr0 || get_all)) {940error = vm_get_vmcs_field(vcpu, VMCS_HOST_CR0, &cr0);941if (error == 0)942printf("host_cr0[%d]\t\t0x%016lx\n", vcpuid, cr0);943}944945if (!error && (get_host_cr3 || get_all)) {946error = vm_get_vmcs_field(vcpu, VMCS_HOST_CR3, &cr3);947if (error == 0)948printf("host_cr3[%d]\t\t0x%016lx\n", vcpuid, cr3);949}950951if (!error && (get_host_cr4 || get_all)) {952error = vm_get_vmcs_field(vcpu, VMCS_HOST_CR4, &cr4);953if (error == 0)954printf("host_cr4[%d]\t\t0x%016lx\n", vcpuid, cr4);955}956957if (!error && (get_host_rip || get_all)) {958error = vm_get_vmcs_field(vcpu, VMCS_HOST_RIP, &rip);959if (error == 0)960printf("host_rip[%d]\t\t0x%016lx\n", vcpuid, rip);961}962963if (!error && (get_host_rsp || get_all)) {964error = vm_get_vmcs_field(vcpu, VMCS_HOST_RSP, &rsp);965if (error == 0)966printf("host_rsp[%d]\t\t0x%016lx\n", vcpuid, rsp);967}968969if (!error && (get_vmcs_link || get_all)) {970error = vm_get_vmcs_field(vcpu, VMCS_LINK_POINTER, &addr);971if (error == 0)972printf("vmcs_pointer[%d]\t0x%016lx\n", vcpuid, addr);973}974975if (!error && (get_vmcs_exit_interruption_info || get_all)) {976error = vm_get_vmcs_field(vcpu, VMCS_EXIT_INTR_INFO, &u64);977if (error == 0) {978printf("vmcs_exit_interruption_info[%d]\t0x%016lx\n",979vcpuid, u64);980}981}982983if (!error && (get_vmcs_exit_interruption_error || get_all)) {984error = vm_get_vmcs_field(vcpu, VMCS_EXIT_INTR_ERRCODE, &u64);985if (error == 0) {986printf("vmcs_exit_interruption_error[%d]\t0x%016lx\n",987vcpuid, u64);988}989}990991if (!error && (get_vmcs_interruptibility || get_all)) {992error = vm_get_vmcs_field(vcpu,993VMCS_GUEST_INTERRUPTIBILITY, &u64);994if (error == 0) {995printf("vmcs_guest_interruptibility[%d]\t0x%016lx\n",996vcpuid, u64);997}998}9991000if (!error && (get_vmcs_exit_inst_length || get_all)) {1001error = vm_get_vmcs_field(vcpu,1002VMCS_EXIT_INSTRUCTION_LENGTH, &u64);1003if (error == 0)1004printf("vmcs_exit_inst_length[%d]\t0x%08x\n", vcpuid,1005(uint32_t)u64);1006}10071008if (!error && (get_vmcs_exit_qualification || get_all)) {1009error = vm_get_vmcs_field(vcpu, VMCS_EXIT_QUALIFICATION,1010&u64);1011if (error == 0)1012printf("vmcs_exit_qualification[%d]\t0x%016lx\n",1013vcpuid, u64);1014}10151016return (error);1017}10181019static int1020get_misc_vmcb(struct vcpu *vcpu, int vcpuid, bool get_all)1021{1022uint64_t ctl, addr;1023int error = 0;10241025if (!error && (get_vmcb_intercept || get_all)) {1026error = vm_get_vmcb_field(vcpu, VMCB_OFF_CR_INTERCEPT, 4,1027&ctl);1028if (error == 0)1029printf("cr_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);10301031error = vm_get_vmcb_field(vcpu, VMCB_OFF_DR_INTERCEPT, 4,1032&ctl);1033if (error == 0)1034printf("dr_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);10351036error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXC_INTERCEPT, 4,1037&ctl);1038if (error == 0)1039printf("exc_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);10401041error = vm_get_vmcb_field(vcpu, VMCB_OFF_INST1_INTERCEPT,10424, &ctl);1043if (error == 0)1044printf("inst1_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);10451046error = vm_get_vmcb_field(vcpu, VMCB_OFF_INST2_INTERCEPT,10474, &ctl);1048if (error == 0)1049printf("inst2_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);1050}10511052if (!error && (get_vmcb_tlb_ctrl || get_all)) {1053error = vm_get_vmcb_field(vcpu, VMCB_OFF_TLB_CTRL,10544, &ctl);1055if (error == 0)1056printf("TLB ctrl[%d]\t0x%016lx\n", vcpuid, ctl);1057}10581059if (!error && (get_vmcb_exit_details || get_all)) {1060error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXITINFO1,10618, &ctl);1062if (error == 0)1063printf("exitinfo1[%d]\t0x%016lx\n", vcpuid, ctl);1064error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXITINFO2,10658, &ctl);1066if (error == 0)1067printf("exitinfo2[%d]\t0x%016lx\n", vcpuid, ctl);1068error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXITINTINFO,10698, &ctl);1070if (error == 0)1071printf("exitintinfo[%d]\t0x%016lx\n", vcpuid, ctl);1072}10731074if (!error && (get_vmcb_virq || get_all)) {1075error = vm_get_vmcb_field(vcpu, VMCB_OFF_VIRQ,10768, &ctl);1077if (error == 0)1078printf("v_irq/tpr[%d]\t0x%016lx\n", vcpuid, ctl);1079}10801081if (!error && (get_apic_access_addr || get_all)) {1082error = vm_get_vmcb_field(vcpu, VMCB_OFF_AVIC_BAR, 8,1083&addr);1084if (error == 0)1085printf("AVIC apic_bar[%d]\t0x%016lx\n", vcpuid, addr);1086}10871088if (!error && (get_virtual_apic_addr || get_all)) {1089error = vm_get_vmcb_field(vcpu, VMCB_OFF_AVIC_PAGE, 8,1090&addr);1091if (error == 0)1092printf("AVIC backing page[%d]\t0x%016lx\n", vcpuid, addr);1093}10941095if (!error && (get_avic_table || get_all)) {1096error = vm_get_vmcb_field(vcpu, VMCB_OFF_AVIC_LT, 8,1097&addr);1098if (error == 0)1099printf("AVIC logical table[%d]\t0x%016lx\n",1100vcpuid, addr);1101error = vm_get_vmcb_field(vcpu, VMCB_OFF_AVIC_PT, 8,1102&addr);1103if (error == 0)1104printf("AVIC physical table[%d]\t0x%016lx\n",1105vcpuid, addr);1106}11071108return (error);1109}11101111struct option *1112bhyvectl_opts(const struct option *options, size_t count)1113{1114const struct option common_opts[] = {1115{ "set-efer", REQ_ARG, 0, SET_EFER },1116{ "set-cr0", REQ_ARG, 0, SET_CR0 },1117{ "set-cr2", REQ_ARG, 0, SET_CR2 },1118{ "set-cr3", REQ_ARG, 0, SET_CR3 },1119{ "set-cr4", REQ_ARG, 0, SET_CR4 },1120{ "set-dr0", REQ_ARG, 0, SET_DR0 },1121{ "set-dr1", REQ_ARG, 0, SET_DR1 },1122{ "set-dr2", REQ_ARG, 0, SET_DR2 },1123{ "set-dr3", REQ_ARG, 0, SET_DR3 },1124{ "set-dr6", REQ_ARG, 0, SET_DR6 },1125{ "set-dr7", REQ_ARG, 0, SET_DR7 },1126{ "set-rsp", REQ_ARG, 0, SET_RSP },1127{ "set-rip", REQ_ARG, 0, SET_RIP },1128{ "set-rax", REQ_ARG, 0, SET_RAX },1129{ "set-rflags", REQ_ARG, 0, SET_RFLAGS },1130{ "desc-base", REQ_ARG, 0, DESC_BASE },1131{ "desc-limit", REQ_ARG, 0, DESC_LIMIT },1132{ "desc-access",REQ_ARG, 0, DESC_ACCESS },1133{ "set-cs", REQ_ARG, 0, SET_CS },1134{ "set-ds", REQ_ARG, 0, SET_DS },1135{ "set-es", REQ_ARG, 0, SET_ES },1136{ "set-fs", REQ_ARG, 0, SET_FS },1137{ "set-gs", REQ_ARG, 0, SET_GS },1138{ "set-ss", REQ_ARG, 0, SET_SS },1139{ "set-tr", REQ_ARG, 0, SET_TR },1140{ "set-ldtr", REQ_ARG, 0, SET_LDTR },1141{ "set-x2apic-state",REQ_ARG, 0, SET_X2APIC_STATE },1142{ "unassign-pptdev", REQ_ARG, 0, UNASSIGN_PPTDEV },1143{ "get-gpa-pmap", REQ_ARG, 0, GET_GPA_PMAP },1144{ "assert-lapic-lvt", REQ_ARG, 0, ASSERT_LAPIC_LVT },1145{ "get-rtc-time", NO_ARG, &get_rtc_time, 1 },1146{ "set-rtc-time", REQ_ARG, 0, SET_RTC_TIME },1147{ "rtc-nvram-offset", REQ_ARG, 0, RTC_NVRAM_OFFSET },1148{ "get-rtc-nvram", NO_ARG, &get_rtc_nvram, 1 },1149{ "set-rtc-nvram", REQ_ARG, 0, SET_RTC_NVRAM },1150{ "get-desc-ds",NO_ARG, &get_desc_ds, 1 },1151{ "set-desc-ds",NO_ARG, &set_desc_ds, 1 },1152{ "get-desc-es",NO_ARG, &get_desc_es, 1 },1153{ "set-desc-es",NO_ARG, &set_desc_es, 1 },1154{ "get-desc-ss",NO_ARG, &get_desc_ss, 1 },1155{ "set-desc-ss",NO_ARG, &set_desc_ss, 1 },1156{ "get-desc-cs",NO_ARG, &get_desc_cs, 1 },1157{ "set-desc-cs",NO_ARG, &set_desc_cs, 1 },1158{ "get-desc-fs",NO_ARG, &get_desc_fs, 1 },1159{ "set-desc-fs",NO_ARG, &set_desc_fs, 1 },1160{ "get-desc-gs",NO_ARG, &get_desc_gs, 1 },1161{ "set-desc-gs",NO_ARG, &set_desc_gs, 1 },1162{ "get-desc-tr",NO_ARG, &get_desc_tr, 1 },1163{ "set-desc-tr",NO_ARG, &set_desc_tr, 1 },1164{ "set-desc-ldtr", NO_ARG, &set_desc_ldtr, 1 },1165{ "get-desc-ldtr", NO_ARG, &get_desc_ldtr, 1 },1166{ "set-desc-gdtr", NO_ARG, &set_desc_gdtr, 1 },1167{ "get-desc-gdtr", NO_ARG, &get_desc_gdtr, 1 },1168{ "set-desc-idtr", NO_ARG, &set_desc_idtr, 1 },1169{ "get-desc-idtr", NO_ARG, &get_desc_idtr, 1 },1170{ "get-efer", NO_ARG, &get_efer, 1 },1171{ "get-cr0", NO_ARG, &get_cr0, 1 },1172{ "get-cr2", NO_ARG, &get_cr2, 1 },1173{ "get-cr3", NO_ARG, &get_cr3, 1 },1174{ "get-cr4", NO_ARG, &get_cr4, 1 },1175{ "get-dr0", NO_ARG, &get_dr0, 1 },1176{ "get-dr1", NO_ARG, &get_dr1, 1 },1177{ "get-dr2", NO_ARG, &get_dr2, 1 },1178{ "get-dr3", NO_ARG, &get_dr3, 1 },1179{ "get-dr6", NO_ARG, &get_dr6, 1 },1180{ "get-dr7", NO_ARG, &get_dr7, 1 },1181{ "get-rsp", NO_ARG, &get_rsp, 1 },1182{ "get-rip", NO_ARG, &get_rip, 1 },1183{ "get-rax", NO_ARG, &get_rax, 1 },1184{ "get-rbx", NO_ARG, &get_rbx, 1 },1185{ "get-rcx", NO_ARG, &get_rcx, 1 },1186{ "get-rdx", NO_ARG, &get_rdx, 1 },1187{ "get-rsi", NO_ARG, &get_rsi, 1 },1188{ "get-rdi", NO_ARG, &get_rdi, 1 },1189{ "get-rbp", NO_ARG, &get_rbp, 1 },1190{ "get-r8", NO_ARG, &get_r8, 1 },1191{ "get-r9", NO_ARG, &get_r9, 1 },1192{ "get-r10", NO_ARG, &get_r10, 1 },1193{ "get-r11", NO_ARG, &get_r11, 1 },1194{ "get-r12", NO_ARG, &get_r12, 1 },1195{ "get-r13", NO_ARG, &get_r13, 1 },1196{ "get-r14", NO_ARG, &get_r14, 1 },1197{ "get-r15", NO_ARG, &get_r15, 1 },1198{ "get-rflags", NO_ARG, &get_rflags, 1 },1199{ "get-cs", NO_ARG, &get_cs, 1 },1200{ "get-ds", NO_ARG, &get_ds, 1 },1201{ "get-es", NO_ARG, &get_es, 1 },1202{ "get-fs", NO_ARG, &get_fs, 1 },1203{ "get-gs", NO_ARG, &get_gs, 1 },1204{ "get-ss", NO_ARG, &get_ss, 1 },1205{ "get-tr", NO_ARG, &get_tr, 1 },1206{ "get-ldtr", NO_ARG, &get_ldtr, 1 },1207{ "get-eptp", NO_ARG, &get_eptp, 1 },1208{ "get-exception-bitmap", NO_ARG, &get_exception_bitmap, 1 },1209{ "get-io-bitmap-address", NO_ARG, &get_io_bitmap, 1 },1210{ "get-tsc-offset", NO_ARG, &get_tsc_offset, 1 },1211{ "get-msr-bitmap", NO_ARG, &get_msr_bitmap, 1 },1212{ "get-msr-bitmap-address", NO_ARG, &get_msr_bitmap_address, 1},1213{ "get-guest-pat", NO_ARG, &get_guest_pat, 1 },1214{ "get-guest-sysenter", NO_ARG, &get_guest_sysenter, 1 },1215{ "get-exit-reason", NO_ARG, &get_exit_reason, 1 },1216{ "get-x2apic-state", NO_ARG, &get_x2apic_state, 1 },1217{ "inject-nmi", NO_ARG, &inject_nmi, 1 },1218{ "get-intinfo", NO_ARG, &get_intinfo, 1 },1219};1220const struct option intel_opts[] = {1221{ "get-vmcs-pinbased-ctls",1222NO_ARG, &get_pinbased_ctls, 1 },1223{ "get-vmcs-procbased-ctls",1224NO_ARG, &get_procbased_ctls, 1 },1225{ "get-vmcs-procbased-ctls2",1226NO_ARG, &get_procbased_ctls2, 1 },1227{ "get-vmcs-guest-linear-address",1228NO_ARG, &get_vmcs_gla, 1 },1229{ "get-vmcs-guest-physical-address",1230NO_ARG, &get_vmcs_gpa, 1 },1231{ "get-vmcs-entry-interruption-info",1232NO_ARG, &get_vmcs_entry_interruption_info, 1},1233{ "get-vmcs-cr0-mask", NO_ARG, &get_cr0_mask, 1 },1234{ "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 },1235{ "get-vmcs-cr4-mask", NO_ARG, &get_cr4_mask, 1 },1236{ "get-vmcs-cr4-shadow", NO_ARG, &get_cr4_shadow, 1 },1237{ "get-vmcs-cr3-targets", NO_ARG, &get_cr3_targets, 1 },1238{ "get-vmcs-tpr-threshold",1239NO_ARG, &get_tpr_threshold, 1 },1240{ "get-vmcs-vpid", NO_ARG, &get_vpid_asid, 1 },1241{ "get-vmcs-exit-ctls", NO_ARG, &get_exit_ctls, 1 },1242{ "get-vmcs-entry-ctls",1243NO_ARG, &get_entry_ctls, 1 },1244{ "get-vmcs-instruction-error",1245NO_ARG, &get_inst_err, 1 },1246{ "get-vmcs-host-pat", NO_ARG, &get_host_pat, 1 },1247{ "get-vmcs-host-cr0",1248NO_ARG, &get_host_cr0, 1 },1249{ "get-vmcs-exit-qualification",1250NO_ARG, &get_vmcs_exit_qualification, 1 },1251{ "get-vmcs-exit-inst-length",1252NO_ARG, &get_vmcs_exit_inst_length, 1 },1253{ "get-vmcs-interruptibility",1254NO_ARG, &get_vmcs_interruptibility, 1 },1255{ "get-vmcs-exit-interruption-error",1256NO_ARG, &get_vmcs_exit_interruption_error, 1 },1257{ "get-vmcs-exit-interruption-info",1258NO_ARG, &get_vmcs_exit_interruption_info, 1 },1259{ "get-vmcs-link", NO_ARG, &get_vmcs_link, 1 },1260{ "get-vmcs-host-cr3",1261NO_ARG, &get_host_cr3, 1 },1262{ "get-vmcs-host-cr4",1263NO_ARG, &get_host_cr4, 1 },1264{ "get-vmcs-host-rip",1265NO_ARG, &get_host_rip, 1 },1266{ "get-vmcs-host-rsp",1267NO_ARG, &get_host_rsp, 1 },1268{ "get-apic-access-address",1269NO_ARG, &get_apic_access_addr, 1},1270{ "get-virtual-apic-address",1271NO_ARG, &get_virtual_apic_addr, 1}1272};1273const struct option amd_opts[] = {1274{ "get-vmcb-intercepts",1275NO_ARG, &get_vmcb_intercept, 1 },1276{ "get-vmcb-asid",1277NO_ARG, &get_vpid_asid, 1 },1278{ "get-vmcb-exit-details",1279NO_ARG, &get_vmcb_exit_details, 1 },1280{ "get-vmcb-tlb-ctrl",1281NO_ARG, &get_vmcb_tlb_ctrl, 1 },1282{ "get-vmcb-virq",1283NO_ARG, &get_vmcb_virq, 1 },1284{ "get-avic-apic-bar",1285NO_ARG, &get_apic_access_addr, 1 },1286{ "get-avic-backing-page",1287NO_ARG, &get_virtual_apic_addr, 1 },1288{ "get-avic-table",1289NO_ARG, &get_avic_table, 1 }1290};1291const struct option null_opt = {1292NULL, 0, NULL, 01293};12941295struct option *all_opts;1296char *cp;1297int optlen;1298bool cpu_intel;12991300cpu_intel = cpu_vendor_intel();1301optlen = count * sizeof(struct option) + sizeof(common_opts);13021303if (cpu_intel)1304optlen += sizeof(intel_opts);1305else1306optlen += sizeof(amd_opts);13071308optlen += sizeof(null_opt);13091310all_opts = malloc(optlen);1311if (all_opts == NULL)1312err(1, "malloc");13131314cp = (char *)all_opts;1315memcpy(cp, options, count * sizeof(struct option));1316cp += count * sizeof(struct option);1317memcpy(cp, common_opts, sizeof(common_opts));1318cp += sizeof(common_opts);13191320if (cpu_intel) {1321memcpy(cp, intel_opts, sizeof(intel_opts));1322cp += sizeof(intel_opts);1323} else {1324memcpy(cp, amd_opts, sizeof(amd_opts));1325cp += sizeof(amd_opts);1326}13271328memcpy(cp, &null_opt, sizeof(null_opt));1329cp += sizeof(null_opt);13301331return (all_opts);1332}13331334void1335bhyvectl_handle_opt(const struct option *opts, int opt)1336{1337switch (opt) {1338case SET_EFER:1339set_efer_val = strtoul(optarg, NULL, 0);1340set_efer = 1;1341break;1342case SET_CR0:1343set_cr0_val = strtoul(optarg, NULL, 0);1344set_cr0 = 1;1345break;1346case SET_CR2:1347set_cr2_val = strtoul(optarg, NULL, 0);1348set_cr2 = 1;1349break;1350case SET_CR3:1351set_cr3_val = strtoul(optarg, NULL, 0);1352set_cr3 = 1;1353break;1354case SET_CR4:1355set_cr4_val = strtoul(optarg, NULL, 0);1356set_cr4 = 1;1357break;1358case SET_DR0:1359set_dr0_val = strtoul(optarg, NULL, 0);1360set_dr0 = 1;1361break;1362case SET_DR1:1363set_dr1_val = strtoul(optarg, NULL, 0);1364set_dr1 = 1;1365break;1366case SET_DR2:1367set_dr2_val = strtoul(optarg, NULL, 0);1368set_dr2 = 1;1369break;1370case SET_DR3:1371set_dr3_val = strtoul(optarg, NULL, 0);1372set_dr3 = 1;1373break;1374case SET_DR6:1375set_dr6_val = strtoul(optarg, NULL, 0);1376set_dr6 = 1;1377break;1378case SET_DR7:1379set_dr7_val = strtoul(optarg, NULL, 0);1380set_dr7 = 1;1381break;1382case SET_RSP:1383set_rsp_val = strtoul(optarg, NULL, 0);1384set_rsp = 1;1385break;1386case SET_RIP:1387set_rip_val = strtoul(optarg, NULL, 0);1388set_rip = 1;1389break;1390case SET_RAX:1391set_rax_val = strtoul(optarg, NULL, 0);1392set_rax = 1;1393break;1394case SET_RFLAGS:1395set_rflags_val = strtoul(optarg, NULL, 0);1396set_rflags = 1;1397break;1398case DESC_BASE:1399desc_base = strtoul(optarg, NULL, 0);1400break;1401case DESC_LIMIT:1402desc_limit = strtoul(optarg, NULL, 0);1403break;1404case DESC_ACCESS:1405desc_access = strtoul(optarg, NULL, 0);1406break;1407case SET_CS:1408set_cs_val = strtoul(optarg, NULL, 0);1409set_cs = 1;1410break;1411case SET_DS:1412set_ds_val = strtoul(optarg, NULL, 0);1413set_ds = 1;1414break;1415case SET_ES:1416set_es_val = strtoul(optarg, NULL, 0);1417set_es = 1;1418break;1419case SET_FS:1420set_fs_val = strtoul(optarg, NULL, 0);1421set_fs = 1;1422break;1423case SET_GS:1424set_gs_val = strtoul(optarg, NULL, 0);1425set_gs = 1;1426break;1427case SET_SS:1428set_ss_val = strtoul(optarg, NULL, 0);1429set_ss = 1;1430break;1431case SET_TR:1432set_tr_val = strtoul(optarg, NULL, 0);1433set_tr = 1;1434break;1435case SET_LDTR:1436set_ldtr_val = strtoul(optarg, NULL, 0);1437set_ldtr = 1;1438break;1439case SET_X2APIC_STATE:1440x2apic_state = strtol(optarg, NULL, 0);1441set_x2apic_state = 1;1442break;1443case SET_RTC_TIME:1444rtc_secs = strtoul(optarg, NULL, 0);1445set_rtc_time = 1;1446break;1447case SET_RTC_NVRAM:1448rtc_nvram_value = (uint8_t)strtoul(optarg, NULL, 0);1449set_rtc_nvram = 1;1450break;1451case RTC_NVRAM_OFFSET:1452rtc_nvram_offset = strtoul(optarg, NULL, 0);1453break;1454case GET_GPA_PMAP:1455gpa_pmap = strtoul(optarg, NULL, 0);1456get_gpa_pmap = 1;1457break;1458case UNASSIGN_PPTDEV:1459unassign_pptdev = 1;1460if (sscanf(optarg, "%d/%d/%d", &bus, &slot, &func) != 3)1461usage(opts);1462break;1463case ASSERT_LAPIC_LVT:1464assert_lapic_lvt = atoi(optarg);1465break;1466}1467}14681469const char *1470bhyvectl_opt_desc(int opt)1471{1472switch (opt) {1473case SET_EFER:1474return ("EFER");1475case SET_CR0:1476return ("CR0");1477case SET_CR2:1478return ("CR2");1479case SET_CR3:1480return ("CR3");1481case SET_CR4:1482return ("CR4");1483case SET_DR0:1484return ("DR0");1485case SET_DR1:1486return ("DR1");1487case SET_DR2:1488return ("DR2");1489case SET_DR3:1490return ("DR3");1491case SET_DR6:1492return ("DR6");1493case SET_DR7:1494return ("DR7");1495case SET_RSP:1496return ("RSP");1497case SET_RIP:1498return ("RIP");1499case SET_RAX:1500return ("RAX");1501case SET_RFLAGS:1502return ("RFLAGS");1503case DESC_BASE:1504return ("BASE");1505case DESC_LIMIT:1506return ("LIMIT");1507case DESC_ACCESS:1508return ("ACCESS");1509case SET_CS:1510return ("CS");1511case SET_DS:1512return ("DS");1513case SET_ES:1514return ("ES");1515case SET_FS:1516return ("FS");1517case SET_GS:1518return ("GS");1519case SET_SS:1520return ("SS");1521case SET_TR:1522return ("TR");1523case SET_LDTR:1524return ("LDTR");1525case SET_X2APIC_STATE:1526return ("state");1527case UNASSIGN_PPTDEV:1528return ("bus/slot.func");1529case GET_GPA_PMAP:1530return ("gpa");1531case ASSERT_LAPIC_LVT:1532return ("pin");1533case SET_RTC_TIME:1534return ("secs");1535case SET_RTC_NVRAM:1536return ("val");1537case RTC_NVRAM_OFFSET:1538return ("offset");1539default:1540return ("???");1541}1542}15431544void1545bhyvectl_md_main(struct vmctx *ctx, struct vcpu *vcpu, int vcpuid, bool get_all)1546{1547struct tm tm;1548uint64_t info[2], pteval[4], *pte;1549uint64_t addr, bm, eptp, u64;1550uint64_t cs, rsp, rip, pat;1551int error, ptenum;1552bool cpu_intel;15531554cpu_intel = cpu_vendor_intel();1555error = 0;15561557if (!error && set_efer)1558error = vm_set_register(vcpu, VM_REG_GUEST_EFER, set_efer_val);15591560if (!error && set_cr0)1561error = vm_set_register(vcpu, VM_REG_GUEST_CR0, set_cr0_val);15621563if (!error && set_cr2)1564error = vm_set_register(vcpu, VM_REG_GUEST_CR2, set_cr2_val);15651566if (!error && set_cr3)1567error = vm_set_register(vcpu, VM_REG_GUEST_CR3, set_cr3_val);15681569if (!error && set_cr4)1570error = vm_set_register(vcpu, VM_REG_GUEST_CR4, set_cr4_val);15711572if (!error && set_dr0)1573error = vm_set_register(vcpu, VM_REG_GUEST_DR0, set_dr0_val);15741575if (!error && set_dr1)1576error = vm_set_register(vcpu, VM_REG_GUEST_DR1, set_dr1_val);15771578if (!error && set_dr2)1579error = vm_set_register(vcpu, VM_REG_GUEST_DR2, set_dr2_val);15801581if (!error && set_dr3)1582error = vm_set_register(vcpu, VM_REG_GUEST_DR3, set_dr3_val);15831584if (!error && set_dr6)1585error = vm_set_register(vcpu, VM_REG_GUEST_DR6, set_dr6_val);15861587if (!error && set_dr7)1588error = vm_set_register(vcpu, VM_REG_GUEST_DR7, set_dr7_val);15891590if (!error && set_rsp)1591error = vm_set_register(vcpu, VM_REG_GUEST_RSP, set_rsp_val);15921593if (!error && set_rip)1594error = vm_set_register(vcpu, VM_REG_GUEST_RIP, set_rip_val);15951596if (!error && set_rax)1597error = vm_set_register(vcpu, VM_REG_GUEST_RAX, set_rax_val);15981599if (!error && set_rflags)1600error = vm_set_register(vcpu, VM_REG_GUEST_RFLAGS,1601set_rflags_val);16021603if (!error && set_desc_ds) {1604error = vm_set_desc(vcpu, VM_REG_GUEST_DS,1605desc_base, desc_limit, desc_access);1606}16071608if (!error && set_desc_es) {1609error = vm_set_desc(vcpu, VM_REG_GUEST_ES,1610desc_base, desc_limit, desc_access);1611}16121613if (!error && set_desc_ss) {1614error = vm_set_desc(vcpu, VM_REG_GUEST_SS,1615desc_base, desc_limit, desc_access);1616}16171618if (!error && set_desc_cs) {1619error = vm_set_desc(vcpu, VM_REG_GUEST_CS,1620desc_base, desc_limit, desc_access);1621}16221623if (!error && set_desc_fs) {1624error = vm_set_desc(vcpu, VM_REG_GUEST_FS,1625desc_base, desc_limit, desc_access);1626}16271628if (!error && set_desc_gs) {1629error = vm_set_desc(vcpu, VM_REG_GUEST_GS,1630desc_base, desc_limit, desc_access);1631}16321633if (!error && set_desc_tr) {1634error = vm_set_desc(vcpu, VM_REG_GUEST_TR,1635desc_base, desc_limit, desc_access);1636}16371638if (!error && set_desc_ldtr) {1639error = vm_set_desc(vcpu, VM_REG_GUEST_LDTR,1640desc_base, desc_limit, desc_access);1641}16421643if (!error && set_desc_gdtr) {1644error = vm_set_desc(vcpu, VM_REG_GUEST_GDTR,1645desc_base, desc_limit, 0);1646}16471648if (!error && set_desc_idtr) {1649error = vm_set_desc(vcpu, VM_REG_GUEST_IDTR,1650desc_base, desc_limit, 0);1651}16521653if (!error && set_cs)1654error = vm_set_register(vcpu, VM_REG_GUEST_CS, set_cs_val);16551656if (!error && set_ds)1657error = vm_set_register(vcpu, VM_REG_GUEST_DS, set_ds_val);16581659if (!error && set_es)1660error = vm_set_register(vcpu, VM_REG_GUEST_ES, set_es_val);16611662if (!error && set_fs)1663error = vm_set_register(vcpu, VM_REG_GUEST_FS, set_fs_val);16641665if (!error && set_gs)1666error = vm_set_register(vcpu, VM_REG_GUEST_GS, set_gs_val);16671668if (!error && set_ss)1669error = vm_set_register(vcpu, VM_REG_GUEST_SS, set_ss_val);16701671if (!error && set_tr)1672error = vm_set_register(vcpu, VM_REG_GUEST_TR, set_tr_val);16731674if (!error && set_ldtr)1675error = vm_set_register(vcpu, VM_REG_GUEST_LDTR, set_ldtr_val);16761677if (!error && set_x2apic_state)1678error = vm_set_x2apic_state(vcpu, x2apic_state);16791680if (!error && unassign_pptdev)1681error = vm_unassign_pptdev(ctx, bus, slot, func);16821683if (!error && inject_nmi)1684error = vm_inject_nmi(vcpu);16851686if (!error && assert_lapic_lvt != -1)1687error = vm_lapic_local_irq(vcpu, assert_lapic_lvt);16881689if (!error)1690error = get_all_registers(vcpu, vcpuid, get_all);16911692if (!error)1693error = get_all_segments(vcpu, vcpuid, get_all);16941695if (!error) {1696if (cpu_intel)1697error = get_misc_vmcs(vcpu, vcpuid, get_all);1698else1699error = get_misc_vmcb(vcpu, vcpuid, get_all);1700}17011702if (!error && (get_x2apic_state || get_all)) {1703error = vm_get_x2apic_state(vcpu, &x2apic_state);1704if (error == 0)1705printf("x2apic_state[%d]\t%d\n", vcpuid, x2apic_state);1706}17071708if (!error && (get_eptp || get_all)) {1709if (cpu_intel)1710error = vm_get_vmcs_field(vcpu, VMCS_EPTP, &eptp);1711else1712error = vm_get_vmcb_field(vcpu, VMCB_OFF_NPT_BASE, 8,1713&eptp);1714if (error == 0)1715printf("%s[%d]\t\t0x%016lx\n",1716cpu_intel ? "eptp" : "rvi/npt", vcpuid, eptp);1717}17181719if (!error && (get_exception_bitmap || get_all)) {1720if (cpu_intel)1721error = vm_get_vmcs_field(vcpu, VMCS_EXCEPTION_BITMAP,1722&bm);1723else1724error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXC_INTERCEPT,17254, &bm);1726if (error == 0)1727printf("exception_bitmap[%d]\t%#lx\n", vcpuid, bm);1728}17291730if (!error && (get_io_bitmap || get_all)) {1731if (cpu_intel) {1732error = vm_get_vmcs_field(vcpu, VMCS_IO_BITMAP_A, &bm);1733if (error == 0)1734printf("io_bitmap_a[%d]\t%#lx\n", vcpuid, bm);1735error = vm_get_vmcs_field(vcpu, VMCS_IO_BITMAP_B, &bm);1736if (error == 0)1737printf("io_bitmap_b[%d]\t%#lx\n", vcpuid, bm);1738} else {1739error = vm_get_vmcb_field(vcpu, VMCB_OFF_IO_PERM, 8,1740&bm);1741if (error == 0)1742printf("io_bitmap[%d]\t%#lx\n", vcpuid, bm);1743}1744}17451746if (!error && (get_tsc_offset || get_all)) {1747uint64_t tscoff;17481749if (cpu_intel)1750error = vm_get_vmcs_field(vcpu, VMCS_TSC_OFFSET,1751&tscoff);1752else1753error = vm_get_vmcb_field(vcpu, VMCB_OFF_TSC_OFFSET, 8,1754&tscoff);1755if (error == 0)1756printf("tsc_offset[%d]\t0x%016lx\n", vcpuid, tscoff);1757}17581759if (!error && (get_msr_bitmap_address || get_all)) {1760if (cpu_intel)1761error = vm_get_vmcs_field(vcpu, VMCS_MSR_BITMAP, &addr);1762else1763error = vm_get_vmcb_field(vcpu, VMCB_OFF_MSR_PERM, 8,1764&addr);1765if (error == 0)1766printf("msr_bitmap[%d]\t\t%#lx\n", vcpuid, addr);1767}17681769if (!error && (get_msr_bitmap || get_all)) {1770if (cpu_intel) {1771error = vm_get_vmcs_field(vcpu, VMCS_MSR_BITMAP, &addr);1772} else {1773error = vm_get_vmcb_field(vcpu, VMCB_OFF_MSR_PERM, 8,1774&addr);1775}17761777if (error == 0)1778error = dump_msr_bitmap(vcpuid, addr, cpu_intel);1779}17801781if (!error && (get_vpid_asid || get_all)) {1782uint64_t vpid;17831784if (cpu_intel)1785error = vm_get_vmcs_field(vcpu, VMCS_VPID, &vpid);1786else1787error = vm_get_vmcb_field(vcpu, VMCB_OFF_ASID, 4,1788&vpid);1789if (error == 0)1790printf("%s[%d]\t\t0x%04lx\n",1791cpu_intel ? "vpid" : "asid", vcpuid, vpid);1792}17931794if (!error && (get_guest_pat || get_all)) {1795if (cpu_intel)1796error = vm_get_vmcs_field(vcpu, VMCS_GUEST_IA32_PAT,1797&pat);1798else1799error = vm_get_vmcb_field(vcpu, VMCB_OFF_GUEST_PAT, 8,1800&pat);1801if (error == 0)1802printf("guest_pat[%d]\t\t0x%016lx\n", vcpuid, pat);1803}18041805if (!error && (get_guest_sysenter || get_all)) {1806if (cpu_intel)1807error = vm_get_vmcs_field(vcpu,1808VMCS_GUEST_IA32_SYSENTER_CS, &cs);1809else1810error = vm_get_vmcb_field(vcpu,1811VMCB_OFF_SYSENTER_CS, 8, &cs);18121813if (error == 0)1814printf("guest_sysenter_cs[%d]\t%#lx\n", vcpuid, cs);1815if (cpu_intel)1816error = vm_get_vmcs_field(vcpu,1817VMCS_GUEST_IA32_SYSENTER_ESP, &rsp);1818else1819error = vm_get_vmcb_field(vcpu, VMCB_OFF_SYSENTER_ESP,18208, &rsp);18211822if (error == 0)1823printf("guest_sysenter_sp[%d]\t%#lx\n", vcpuid, rsp);1824if (cpu_intel)1825error = vm_get_vmcs_field(vcpu,1826VMCS_GUEST_IA32_SYSENTER_EIP, &rip);1827else1828error = vm_get_vmcb_field(vcpu, VMCB_OFF_SYSENTER_EIP,18298, &rip);1830if (error == 0)1831printf("guest_sysenter_ip[%d]\t%#lx\n", vcpuid, rip);1832}18331834if (!error && (get_exit_reason || get_all)) {1835if (cpu_intel)1836error = vm_get_vmcs_field(vcpu, VMCS_EXIT_REASON, &u64);1837else1838error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXIT_REASON, 8,1839&u64);1840if (error == 0)1841printf("exit_reason[%d]\t%#lx\n", vcpuid, u64);1842}18431844if (!error && get_gpa_pmap) {1845error = vm_get_gpa_pmap(ctx, gpa_pmap, pteval, &ptenum);1846if (error == 0) {1847printf("gpa %#lx:", gpa_pmap);1848pte = &pteval[0];1849while (ptenum-- > 0)1850printf(" %#lx", *pte++);1851printf("\n");1852}1853}18541855if (!error && set_rtc_nvram)1856error = vm_rtc_write(ctx, rtc_nvram_offset, rtc_nvram_value);18571858if (!error && (get_rtc_nvram || get_all)) {1859error = vm_rtc_read(ctx, rtc_nvram_offset, &rtc_nvram_value);1860if (error == 0) {1861printf("rtc nvram[%03d]: 0x%02x\n", rtc_nvram_offset,1862rtc_nvram_value);1863}1864}18651866if (!error && set_rtc_time)1867error = vm_rtc_settime(ctx, rtc_secs);18681869if (!error && (get_rtc_time || get_all)) {1870error = vm_rtc_gettime(ctx, &rtc_secs);1871if (error == 0) {1872gmtime_r(&rtc_secs, &tm);1873printf("rtc time %#lx: %s %s %02d %02d:%02d:%02d %d\n",1874rtc_secs, wday_str(tm.tm_wday), mon_str(tm.tm_mon),1875tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,18761900 + tm.tm_year);1877}1878}18791880if (!error && (get_intinfo || get_all)) {1881error = vm_get_intinfo(vcpu, &info[0], &info[1]);1882if (!error) {1883print_intinfo("pending", info[0]);1884print_intinfo("current", info[1]);1885}1886}1887}188818891890