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