1 /*- 2 * Copyright (c) 2011 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/cdefs.h> 30 __FBSDID("$FreeBSD$"); 31 32 #include <sys/param.h> 33 #include <sys/types.h> 34 #include <sys/sysctl.h> 35 #include <sys/errno.h> 36 #include <sys/mman.h> 37 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <unistd.h> 41 #include <libgen.h> 42 #include <libutil.h> 43 #include <fcntl.h> 44 #include <string.h> 45 #include <getopt.h> 46 #include <assert.h> 47 48 #include <machine/vmm.h> 49 #include <vmmapi.h> 50 51 #include "intel/vmcs.h" 52 53 #define MB (1UL << 20) 54 #define GB (1UL << 30) 55 56 #define REQ_ARG required_argument 57 #define NO_ARG no_argument 58 #define OPT_ARG optional_argument 59 60 static const char *progname; 61 62 static void 63 usage(void) 64 { 65 66 (void)fprintf(stderr, 67 "Usage: %s --vm=<vmname>\n" 68 " [--cpu=<vcpu_number>]\n" 69 " [--create]\n" 70 " [--destroy]\n" 71 " [--get-all]\n" 72 " [--get-stats]\n" 73 " [--set-desc-ds]\n" 74 " [--get-desc-ds]\n" 75 " [--set-desc-es]\n" 76 " [--get-desc-es]\n" 77 " [--set-desc-gs]\n" 78 " [--get-desc-gs]\n" 79 " [--set-desc-fs]\n" 80 " [--get-desc-fs]\n" 81 " [--set-desc-cs]\n" 82 " [--get-desc-cs]\n" 83 " [--set-desc-ss]\n" 84 " [--get-desc-ss]\n" 85 " [--set-desc-tr]\n" 86 " [--get-desc-tr]\n" 87 " [--set-desc-ldtr]\n" 88 " [--get-desc-ldtr]\n" 89 " [--set-desc-gdtr]\n" 90 " [--get-desc-gdtr]\n" 91 " [--set-desc-idtr]\n" 92 " [--get-desc-idtr]\n" 93 " [--run]\n" 94 " [--capname=<capname>]\n" 95 " [--getcap]\n" 96 " [--setcap=<0|1>]\n" 97 " [--desc-base=<BASE>]\n" 98 " [--desc-limit=<LIMIT>]\n" 99 " [--desc-access=<ACCESS>]\n" 100 " [--set-cr0=<CR0>]\n" 101 " [--get-cr0]\n" 102 " [--set-cr3=<CR3>]\n" 103 " [--get-cr3]\n" 104 " [--set-cr4=<CR4>]\n" 105 " [--get-cr4]\n" 106 " [--set-dr7=<DR7>]\n" 107 " [--get-dr7]\n" 108 " [--set-rsp=<RSP>]\n" 109 " [--get-rsp]\n" 110 " [--set-rip=<RIP>]\n" 111 " [--get-rip]\n" 112 " [--get-rax]\n" 113 " [--set-rax=<RAX>]\n" 114 " [--get-rbx]\n" 115 " [--get-rcx]\n" 116 " [--get-rdx]\n" 117 " [--get-rsi]\n" 118 " [--get-rdi]\n" 119 " [--get-rbp]\n" 120 " [--get-r8]\n" 121 " [--get-r9]\n" 122 " [--get-r10]\n" 123 " [--get-r11]\n" 124 " [--get-r12]\n" 125 " [--get-r13]\n" 126 " [--get-r14]\n" 127 " [--get-r15]\n" 128 " [--set-rflags=<RFLAGS>]\n" 129 " [--get-rflags]\n" 130 " [--set-cs]\n" 131 " [--get-cs]\n" 132 " [--set-ds]\n" 133 " [--get-ds]\n" 134 " [--set-es]\n" 135 " [--get-es]\n" 136 " [--set-fs]\n" 137 " [--get-fs]\n" 138 " [--set-gs]\n" 139 " [--get-gs]\n" 140 " [--set-ss]\n" 141 " [--get-ss]\n" 142 " [--get-tr]\n" 143 " [--get-ldtr]\n" 144 " [--get-vmcs-pinbased-ctls]\n" 145 " [--get-vmcs-procbased-ctls]\n" 146 " [--get-vmcs-procbased-ctls2]\n" 147 " [--get-vmcs-entry-interruption-info]\n" 148 " [--set-vmcs-entry-interruption-info=<info>]\n" 149 " [--get-vmcs-eptp]\n" 150 " [--get-vmcs-guest-physical-address\n" 151 " [--get-vmcs-guest-linear-address\n" 152 " [--set-vmcs-exception-bitmap]\n" 153 " [--get-vmcs-exception-bitmap]\n" 154 " [--get-vmcs-io-bitmap-address]\n" 155 " [--get-vmcs-tsc-offset]\n" 156 " [--get-vmcs-guest-pat]\n" 157 " [--get-vmcs-host-pat]\n" 158 " [--get-vmcs-host-cr0]\n" 159 " [--get-vmcs-host-cr3]\n" 160 " [--get-vmcs-host-cr4]\n" 161 " [--get-vmcs-host-rip]\n" 162 " [--get-vmcs-host-rsp]\n" 163 " [--get-vmcs-cr0-mask]\n" 164 " [--get-vmcs-cr0-shadow]\n" 165 " [--get-vmcs-cr4-mask]\n" 166 " [--get-vmcs-cr4-shadow]\n" 167 " [--get-vmcs-cr3-targets]\n" 168 " [--get-vmcs-apic-access-address]\n" 169 " [--get-vmcs-virtual-apic-address]\n" 170 " [--get-vmcs-tpr-threshold]\n" 171 " [--get-vmcs-msr-bitmap]\n" 172 " [--get-vmcs-msr-bitmap-address]\n" 173 " [--get-vmcs-vpid]\n" 174 " [--get-vmcs-ple-gap]\n" 175 " [--get-vmcs-ple-window]\n" 176 " [--get-vmcs-instruction-error]\n" 177 " [--get-vmcs-exit-ctls]\n" 178 " [--get-vmcs-entry-ctls]\n" 179 " [--get-vmcs-guest-sysenter]\n" 180 " [--get-vmcs-link]\n" 181 " [--get-vmcs-exit-reason]\n" 182 " [--get-vmcs-exit-qualification]\n" 183 " [--get-vmcs-exit-interruption-info]\n" 184 " [--get-vmcs-exit-interruption-error]\n" 185 " [--get-vmcs-interruptibility]\n" 186 " [--set-x2apic-state=<state>]\n" 187 " [--get-x2apic-state]\n" 188 " [--unassign-pptdev=<bus/slot/func>]\n" 189 " [--set-mem=<memory in units of MB>]\n" 190 " [--get-lowmem]\n" 191 " [--get-highmem]\n", 192 progname); 193 exit(1); 194 } 195 196 static int get_stats, getcap, setcap, capval; 197 static const char *capname; 198 static int create, destroy, get_lowmem, get_highmem; 199 static uint64_t memsize; 200 static int set_cr0, get_cr0, set_cr3, get_cr3, set_cr4, get_cr4; 201 static int set_efer, get_efer; 202 static int set_dr7, get_dr7; 203 static int set_rsp, get_rsp, set_rip, get_rip, set_rflags, get_rflags; 204 static int set_rax, get_rax; 205 static int get_rbx, get_rcx, get_rdx, get_rsi, get_rdi, get_rbp; 206 static int get_r8, get_r9, get_r10, get_r11, get_r12, get_r13, get_r14, get_r15; 207 static int set_desc_ds, get_desc_ds; 208 static int set_desc_es, get_desc_es; 209 static int set_desc_fs, get_desc_fs; 210 static int set_desc_gs, get_desc_gs; 211 static int set_desc_cs, get_desc_cs; 212 static int set_desc_ss, get_desc_ss; 213 static int set_desc_gdtr, get_desc_gdtr; 214 static int set_desc_idtr, get_desc_idtr; 215 static int set_desc_tr, get_desc_tr; 216 static int set_desc_ldtr, get_desc_ldtr; 217 static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr; 218 static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr; 219 static int set_x2apic_state, get_x2apic_state; 220 enum x2apic_state x2apic_state; 221 static int unassign_pptdev, bus, slot, func; 222 static int run; 223 224 /* 225 * VMCS-specific fields 226 */ 227 static int get_pinbased_ctls, get_procbased_ctls, get_procbased_ctls2; 228 static int get_eptp, get_io_bitmap, get_tsc_offset; 229 static int get_vmcs_entry_interruption_info, set_vmcs_entry_interruption_info; 230 static int get_vmcs_interruptibility; 231 uint32_t vmcs_entry_interruption_info; 232 static int get_vmcs_gpa, get_vmcs_gla; 233 static int get_exception_bitmap, set_exception_bitmap, exception_bitmap; 234 static int get_cr0_mask, get_cr0_shadow; 235 static int get_cr4_mask, get_cr4_shadow; 236 static int get_cr3_targets; 237 static int get_apic_access_addr, get_virtual_apic_addr, get_tpr_threshold; 238 static int get_msr_bitmap, get_msr_bitmap_address; 239 static int get_vpid, get_ple_gap, get_ple_window; 240 static int get_inst_err, get_exit_ctls, get_entry_ctls; 241 static int get_host_cr0, get_host_cr3, get_host_cr4; 242 static int get_host_rip, get_host_rsp; 243 static int get_guest_pat, get_host_pat; 244 static int get_guest_sysenter, get_vmcs_link; 245 static int get_vmcs_exit_reason, get_vmcs_exit_qualification; 246 static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error; 247 248 static uint64_t desc_base; 249 static uint32_t desc_limit, desc_access; 250 251 static int get_all; 252 253 static void 254 dump_vm_run_exitcode(struct vm_exit *vmexit, int vcpu) 255 { 256 printf("vm exit[%d]\n", vcpu); 257 printf("\trip\t\t0x%016lx\n", vmexit->rip); 258 printf("\tinst_length\t%d\n", vmexit->inst_length); 259 switch (vmexit->exitcode) { 260 case VM_EXITCODE_INOUT: 261 printf("\treason\t\tINOUT\n"); 262 printf("\tdirection\t%s\n", vmexit->u.inout.in ? "IN" : "OUT"); 263 printf("\tbytes\t\t%d\n", vmexit->u.inout.bytes); 264 printf("\tflags\t\t%s%s\n", 265 vmexit->u.inout.string ? "STRING " : "", 266 vmexit->u.inout.rep ? "REP " : ""); 267 printf("\tport\t\t0x%04x\n", vmexit->u.inout.port); 268 printf("\teax\t\t0x%08x\n", vmexit->u.inout.eax); 269 break; 270 case VM_EXITCODE_VMX: 271 printf("\treason\t\tVMX\n"); 272 printf("\terror\t\t%d\n", vmexit->u.vmx.error); 273 printf("\texit_reason\t0x%08x (%u)\n", 274 vmexit->u.vmx.exit_reason, vmexit->u.vmx.exit_reason); 275 printf("\tqualification\t0x%016lx\n", 276 vmexit->u.vmx.exit_qualification); 277 break; 278 default: 279 printf("*** unknown vm run exitcode %d\n", vmexit->exitcode); 280 break; 281 } 282 } 283 284 static int 285 dump_vmcs_msr_bitmap(int vcpu, u_long addr) 286 { 287 int error, fd, byte, bit, readable, writeable; 288 u_int msr; 289 const char *bitmap; 290 291 error = -1; 292 bitmap = MAP_FAILED; 293 294 fd = open("/dev/mem", O_RDONLY, 0); 295 if (fd < 0) 296 goto done; 297 298 bitmap = mmap(NULL, PAGE_SIZE, PROT_READ, 0, fd, addr); 299 if (bitmap == MAP_FAILED) 300 goto done; 301 302 for (msr = 0; msr < 0x2000; msr++) { 303 byte = msr / 8; 304 bit = msr & 0x7; 305 306 /* Look at MSRs in the range 0x00000000 to 0x00001FFF */ 307 readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; 308 writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1; 309 if (readable || writeable) { 310 printf("msr 0x%08x[%d]\t\t%c%c\n", msr, vcpu, 311 readable ? 'R' : '-', 312 writeable ? 'W' : '-'); 313 } 314 315 /* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */ 316 byte += 1024; 317 readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; 318 writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1; 319 if (readable || writeable) { 320 printf("msr 0x%08x[%d]\t\t%c%c\n", 321 0xc0000000 + msr, vcpu, 322 readable ? 'R' : '-', 323 writeable ? 'W' : '-'); 324 } 325 } 326 327 error = 0; 328 done: 329 if (bitmap != MAP_FAILED) 330 munmap((void *)bitmap, PAGE_SIZE); 331 if (fd >= 0) 332 close(fd); 333 return (error); 334 } 335 336 static int 337 vm_get_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t *ret_val) 338 { 339 340 return (vm_get_register(ctx, vcpu, VMCS_IDENT(field), ret_val)); 341 } 342 343 static int 344 vm_set_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t val) 345 { 346 347 return (vm_set_register(ctx, vcpu, VMCS_IDENT(field), val)); 348 } 349 350 enum { 351 VMNAME = 1000, /* avoid collision with return values from getopt */ 352 VCPU, 353 SET_MEM, 354 SET_EFER, 355 SET_CR0, 356 SET_CR3, 357 SET_CR4, 358 SET_DR7, 359 SET_RSP, 360 SET_RIP, 361 SET_RAX, 362 SET_RFLAGS, 363 DESC_BASE, 364 DESC_LIMIT, 365 DESC_ACCESS, 366 SET_CS, 367 SET_DS, 368 SET_ES, 369 SET_FS, 370 SET_GS, 371 SET_SS, 372 SET_TR, 373 SET_LDTR, 374 SET_X2APIC_STATE, 375 SET_VMCS_EXCEPTION_BITMAP, 376 SET_VMCS_ENTRY_INTERRUPTION_INFO, 377 SET_CAP, 378 CAPNAME, 379 UNASSIGN_PPTDEV, 380 }; 381 382 int 383 main(int argc, char *argv[]) 384 { 385 char *vmname; 386 int error, ch, vcpu; 387 vm_paddr_t gpa; 388 size_t len; 389 struct vm_exit vmexit; 390 uint64_t ctl, eptp, bm, addr, u64; 391 struct vmctx *ctx; 392 393 uint64_t cr0, cr3, cr4, dr7, rsp, rip, rflags, efer, pat; 394 uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp; 395 uint64_t r8, r9, r10, r11, r12, r13, r14, r15; 396 uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; 397 398 struct option opts[] = { 399 { "vm", REQ_ARG, 0, VMNAME }, 400 { "cpu", REQ_ARG, 0, VCPU }, 401 { "set-mem", REQ_ARG, 0, SET_MEM }, 402 { "set-efer", REQ_ARG, 0, SET_EFER }, 403 { "set-cr0", REQ_ARG, 0, SET_CR0 }, 404 { "set-cr3", REQ_ARG, 0, SET_CR3 }, 405 { "set-cr4", REQ_ARG, 0, SET_CR4 }, 406 { "set-dr7", REQ_ARG, 0, SET_DR7 }, 407 { "set-rsp", REQ_ARG, 0, SET_RSP }, 408 { "set-rip", REQ_ARG, 0, SET_RIP }, 409 { "set-rax", REQ_ARG, 0, SET_RAX }, 410 { "set-rflags", REQ_ARG, 0, SET_RFLAGS }, 411 { "desc-base", REQ_ARG, 0, DESC_BASE }, 412 { "desc-limit", REQ_ARG, 0, DESC_LIMIT }, 413 { "desc-access",REQ_ARG, 0, DESC_ACCESS }, 414 { "set-cs", REQ_ARG, 0, SET_CS }, 415 { "set-ds", REQ_ARG, 0, SET_DS }, 416 { "set-es", REQ_ARG, 0, SET_ES }, 417 { "set-fs", REQ_ARG, 0, SET_FS }, 418 { "set-gs", REQ_ARG, 0, SET_GS }, 419 { "set-ss", REQ_ARG, 0, SET_SS }, 420 { "set-tr", REQ_ARG, 0, SET_TR }, 421 { "set-ldtr", REQ_ARG, 0, SET_LDTR }, 422 { "set-x2apic-state",REQ_ARG, 0, SET_X2APIC_STATE }, 423 { "set-vmcs-exception-bitmap", 424 REQ_ARG, 0, SET_VMCS_EXCEPTION_BITMAP }, 425 { "set-vmcs-entry-interruption-info", 426 REQ_ARG, 0, SET_VMCS_ENTRY_INTERRUPTION_INFO }, 427 { "capname", REQ_ARG, 0, CAPNAME }, 428 { "unassign-pptdev", REQ_ARG, 0, UNASSIGN_PPTDEV }, 429 { "setcap", REQ_ARG, 0, SET_CAP }, 430 { "getcap", NO_ARG, &getcap, 1 }, 431 { "get-stats", NO_ARG, &get_stats, 1 }, 432 { "get-desc-ds",NO_ARG, &get_desc_ds, 1 }, 433 { "set-desc-ds",NO_ARG, &set_desc_ds, 1 }, 434 { "get-desc-es",NO_ARG, &get_desc_es, 1 }, 435 { "set-desc-es",NO_ARG, &set_desc_es, 1 }, 436 { "get-desc-ss",NO_ARG, &get_desc_ss, 1 }, 437 { "set-desc-ss",NO_ARG, &set_desc_ss, 1 }, 438 { "get-desc-cs",NO_ARG, &get_desc_cs, 1 }, 439 { "set-desc-cs",NO_ARG, &set_desc_cs, 1 }, 440 { "get-desc-fs",NO_ARG, &get_desc_fs, 1 }, 441 { "set-desc-fs",NO_ARG, &set_desc_fs, 1 }, 442 { "get-desc-gs",NO_ARG, &get_desc_gs, 1 }, 443 { "set-desc-gs",NO_ARG, &set_desc_gs, 1 }, 444 { "get-desc-tr",NO_ARG, &get_desc_tr, 1 }, 445 { "set-desc-tr",NO_ARG, &set_desc_tr, 1 }, 446 { "set-desc-ldtr", NO_ARG, &set_desc_ldtr, 1 }, 447 { "get-desc-ldtr", NO_ARG, &get_desc_ldtr, 1 }, 448 { "set-desc-gdtr", NO_ARG, &set_desc_gdtr, 1 }, 449 { "get-desc-gdtr", NO_ARG, &get_desc_gdtr, 1 }, 450 { "set-desc-idtr", NO_ARG, &set_desc_idtr, 1 }, 451 { "get-desc-idtr", NO_ARG, &get_desc_idtr, 1 }, 452 { "get-lowmem", NO_ARG, &get_lowmem, 1 }, 453 { "get-highmem",NO_ARG, &get_highmem, 1 }, 454 { "get-efer", NO_ARG, &get_efer, 1 }, 455 { "get-cr0", NO_ARG, &get_cr0, 1 }, 456 { "get-cr3", NO_ARG, &get_cr3, 1 }, 457 { "get-cr4", NO_ARG, &get_cr4, 1 }, 458 { "get-dr7", NO_ARG, &get_dr7, 1 }, 459 { "get-rsp", NO_ARG, &get_rsp, 1 }, 460 { "get-rip", NO_ARG, &get_rip, 1 }, 461 { "get-rax", NO_ARG, &get_rax, 1 }, 462 { "get-rbx", NO_ARG, &get_rbx, 1 }, 463 { "get-rcx", NO_ARG, &get_rcx, 1 }, 464 { "get-rdx", NO_ARG, &get_rdx, 1 }, 465 { "get-rsi", NO_ARG, &get_rsi, 1 }, 466 { "get-rdi", NO_ARG, &get_rdi, 1 }, 467 { "get-rbp", NO_ARG, &get_rbp, 1 }, 468 { "get-r8", NO_ARG, &get_r8, 1 }, 469 { "get-r9", NO_ARG, &get_r9, 1 }, 470 { "get-r10", NO_ARG, &get_r10, 1 }, 471 { "get-r11", NO_ARG, &get_r11, 1 }, 472 { "get-r12", NO_ARG, &get_r12, 1 }, 473 { "get-r13", NO_ARG, &get_r13, 1 }, 474 { "get-r14", NO_ARG, &get_r14, 1 }, 475 { "get-r15", NO_ARG, &get_r15, 1 }, 476 { "get-rflags", NO_ARG, &get_rflags, 1 }, 477 { "get-cs", NO_ARG, &get_cs, 1 }, 478 { "get-ds", NO_ARG, &get_ds, 1 }, 479 { "get-es", NO_ARG, &get_es, 1 }, 480 { "get-fs", NO_ARG, &get_fs, 1 }, 481 { "get-gs", NO_ARG, &get_gs, 1 }, 482 { "get-ss", NO_ARG, &get_ss, 1 }, 483 { "get-tr", NO_ARG, &get_tr, 1 }, 484 { "get-ldtr", NO_ARG, &get_ldtr, 1 }, 485 { "get-vmcs-pinbased-ctls", 486 NO_ARG, &get_pinbased_ctls, 1 }, 487 { "get-vmcs-procbased-ctls", 488 NO_ARG, &get_procbased_ctls, 1 }, 489 { "get-vmcs-procbased-ctls2", 490 NO_ARG, &get_procbased_ctls2, 1 }, 491 { "get-vmcs-guest-linear-address", 492 NO_ARG, &get_vmcs_gla, 1 }, 493 { "get-vmcs-guest-physical-address", 494 NO_ARG, &get_vmcs_gpa, 1 }, 495 { "get-vmcs-entry-interruption-info", 496 NO_ARG, &get_vmcs_entry_interruption_info, 1}, 497 { "get-vmcs-eptp", NO_ARG, &get_eptp, 1 }, 498 { "get-vmcs-exception-bitmap", 499 NO_ARG, &get_exception_bitmap, 1 }, 500 { "get-vmcs-io-bitmap-address", 501 NO_ARG, &get_io_bitmap, 1 }, 502 { "get-vmcs-tsc-offset", NO_ARG,&get_tsc_offset, 1 }, 503 { "get-vmcs-cr0-mask", NO_ARG, &get_cr0_mask, 1 }, 504 { "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 }, 505 { "get-vmcs-cr4-mask", NO_ARG, &get_cr4_mask, 1 }, 506 { "get-vmcs-cr4-shadow", NO_ARG,&get_cr4_shadow, 1 }, 507 { "get-vmcs-cr3-targets", NO_ARG, &get_cr3_targets, 1}, 508 { "get-vmcs-apic-access-address", 509 NO_ARG, &get_apic_access_addr, 1}, 510 { "get-vmcs-virtual-apic-address", 511 NO_ARG, &get_virtual_apic_addr, 1}, 512 { "get-vmcs-tpr-threshold", 513 NO_ARG, &get_tpr_threshold, 1 }, 514 { "get-vmcs-msr-bitmap", 515 NO_ARG, &get_msr_bitmap, 1 }, 516 { "get-vmcs-msr-bitmap-address", 517 NO_ARG, &get_msr_bitmap_address, 1 }, 518 { "get-vmcs-vpid", NO_ARG, &get_vpid, 1 }, 519 { "get-vmcs-ple-gap", NO_ARG, &get_ple_gap, 1 }, 520 { "get-vmcs-ple-window", NO_ARG,&get_ple_window,1 }, 521 { "get-vmcs-instruction-error", 522 NO_ARG, &get_inst_err, 1 }, 523 { "get-vmcs-exit-ctls", NO_ARG, &get_exit_ctls, 1 }, 524 { "get-vmcs-entry-ctls", 525 NO_ARG, &get_entry_ctls, 1 }, 526 { "get-vmcs-guest-pat", NO_ARG, &get_guest_pat, 1 }, 527 { "get-vmcs-host-pat", NO_ARG, &get_host_pat, 1 }, 528 { "get-vmcs-host-cr0", 529 NO_ARG, &get_host_cr0, 1 }, 530 { "get-vmcs-host-cr3", 531 NO_ARG, &get_host_cr3, 1 }, 532 { "get-vmcs-host-cr4", 533 NO_ARG, &get_host_cr4, 1 }, 534 { "get-vmcs-host-rip", 535 NO_ARG, &get_host_rip, 1 }, 536 { "get-vmcs-host-rsp", 537 NO_ARG, &get_host_rsp, 1 }, 538 { "get-vmcs-guest-sysenter", 539 NO_ARG, &get_guest_sysenter, 1 }, 540 { "get-vmcs-link", NO_ARG, &get_vmcs_link, 1 }, 541 { "get-vmcs-exit-reason", 542 NO_ARG, &get_vmcs_exit_reason, 1 }, 543 { "get-vmcs-exit-qualification", 544 NO_ARG, &get_vmcs_exit_qualification, 1 }, 545 { "get-vmcs-exit-interruption-info", 546 NO_ARG, &get_vmcs_exit_interruption_info, 1}, 547 { "get-vmcs-exit-interruption-error", 548 NO_ARG, &get_vmcs_exit_interruption_error, 1}, 549 { "get-vmcs-interruptibility", 550 NO_ARG, &get_vmcs_interruptibility, 1 }, 551 { "get-x2apic-state",NO_ARG, &get_x2apic_state, 1 }, 552 { "get-all", NO_ARG, &get_all, 1 }, 553 { "run", NO_ARG, &run, 1 }, 554 { "create", NO_ARG, &create, 1 }, 555 { "destroy", NO_ARG, &destroy, 1 }, 556 { NULL, 0, NULL, 0 } 557 }; 558 559 vcpu = 0; 560 progname = basename(argv[0]); 561 562 while ((ch = getopt_long(argc, argv, "", opts, NULL)) != -1) { 563 switch (ch) { 564 case 0: 565 break; 566 case VMNAME: 567 vmname = optarg; 568 break; 569 case VCPU: 570 vcpu = atoi(optarg); 571 break; 572 case SET_MEM: 573 memsize = atoi(optarg) * MB; 574 memsize = roundup(memsize, 2 * MB); 575 break; 576 case SET_EFER: 577 efer = strtoul(optarg, NULL, 0); 578 set_efer = 1; 579 break; 580 case SET_CR0: 581 cr0 = strtoul(optarg, NULL, 0); 582 set_cr0 = 1; 583 break; 584 case SET_CR3: 585 cr3 = strtoul(optarg, NULL, 0); 586 set_cr3 = 1; 587 break; 588 case SET_CR4: 589 cr4 = strtoul(optarg, NULL, 0); 590 set_cr4 = 1; 591 break; 592 case SET_DR7: 593 dr7 = strtoul(optarg, NULL, 0); 594 set_dr7 = 1; 595 break; 596 case SET_RSP: 597 rsp = strtoul(optarg, NULL, 0); 598 set_rsp = 1; 599 break; 600 case SET_RIP: 601 rip = strtoul(optarg, NULL, 0); 602 set_rip = 1; 603 break; 604 case SET_RAX: 605 rax = strtoul(optarg, NULL, 0); 606 set_rax = 1; 607 break; 608 case SET_RFLAGS: 609 rflags = strtoul(optarg, NULL, 0); 610 set_rflags = 1; 611 break; 612 case DESC_BASE: 613 desc_base = strtoul(optarg, NULL, 0); 614 break; 615 case DESC_LIMIT: 616 desc_limit = strtoul(optarg, NULL, 0); 617 break; 618 case DESC_ACCESS: 619 desc_access = strtoul(optarg, NULL, 0); 620 break; 621 case SET_CS: 622 cs = strtoul(optarg, NULL, 0); 623 set_cs = 1; 624 break; 625 case SET_DS: 626 ds = strtoul(optarg, NULL, 0); 627 set_ds = 1; 628 break; 629 case SET_ES: 630 es = strtoul(optarg, NULL, 0); 631 set_es = 1; 632 break; 633 case SET_FS: 634 fs = strtoul(optarg, NULL, 0); 635 set_fs = 1; 636 break; 637 case SET_GS: 638 gs = strtoul(optarg, NULL, 0); 639 set_gs = 1; 640 break; 641 case SET_SS: 642 ss = strtoul(optarg, NULL, 0); 643 set_ss = 1; 644 break; 645 case SET_TR: 646 tr = strtoul(optarg, NULL, 0); 647 set_tr = 1; 648 break; 649 case SET_LDTR: 650 ldtr = strtoul(optarg, NULL, 0); 651 set_ldtr = 1; 652 break; 653 case SET_X2APIC_STATE: 654 x2apic_state = strtol(optarg, NULL, 0); 655 set_x2apic_state = 1; 656 break; 657 case SET_VMCS_EXCEPTION_BITMAP: 658 exception_bitmap = strtoul(optarg, NULL, 0); 659 set_exception_bitmap = 1; 660 break; 661 case SET_VMCS_ENTRY_INTERRUPTION_INFO: 662 vmcs_entry_interruption_info = strtoul(optarg, NULL, 0); 663 set_vmcs_entry_interruption_info = 1; 664 break; 665 case SET_CAP: 666 capval = strtoul(optarg, NULL, 0); 667 setcap = 1; 668 break; 669 case CAPNAME: 670 capname = optarg; 671 break; 672 case UNASSIGN_PPTDEV: 673 unassign_pptdev = 1; 674 if (sscanf(optarg, "%d/%d/%d", &bus, &slot, &func) != 3) 675 usage(); 676 break; 677 default: 678 usage(); 679 } 680 } 681 argc -= optind; 682 argv += optind; 683 684 if (vmname == NULL) 685 usage(); 686 687 error = 0; 688 689 if (!error && create) 690 error = vm_create(vmname); 691 692 if (!error) { 693 ctx = vm_open(vmname); 694 if (ctx == NULL) 695 error = -1; 696 } 697 698 if (!error && memsize) 699 error = vm_setup_memory(ctx, memsize, VM_MMAP_NONE); 700 701 if (!error && set_efer) 702 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_EFER, efer); 703 704 if (!error && set_cr0) 705 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR0, cr0); 706 707 if (!error && set_cr3) 708 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR3, cr3); 709 710 if (!error && set_cr4) 711 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR4, cr4); 712 713 if (!error && set_dr7) 714 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR7, dr7); 715 716 if (!error && set_rsp) 717 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RSP, rsp); 718 719 if (!error && set_rip) 720 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, rip); 721 722 if (!error && set_rax) 723 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, rax); 724 725 if (!error && set_rflags) { 726 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, 727 rflags); 728 } 729 730 if (!error && set_desc_ds) { 731 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_DS, 732 desc_base, desc_limit, desc_access); 733 } 734 735 if (!error && set_desc_es) { 736 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_ES, 737 desc_base, desc_limit, desc_access); 738 } 739 740 if (!error && set_desc_ss) { 741 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_SS, 742 desc_base, desc_limit, desc_access); 743 } 744 745 if (!error && set_desc_cs) { 746 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_CS, 747 desc_base, desc_limit, desc_access); 748 } 749 750 if (!error && set_desc_fs) { 751 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_FS, 752 desc_base, desc_limit, desc_access); 753 } 754 755 if (!error && set_desc_gs) { 756 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GS, 757 desc_base, desc_limit, desc_access); 758 } 759 760 if (!error && set_desc_tr) { 761 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_TR, 762 desc_base, desc_limit, desc_access); 763 } 764 765 if (!error && set_desc_ldtr) { 766 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_LDTR, 767 desc_base, desc_limit, desc_access); 768 } 769 770 if (!error && set_desc_gdtr) { 771 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GDTR, 772 desc_base, desc_limit, 0); 773 } 774 775 if (!error && set_desc_idtr) { 776 error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_IDTR, 777 desc_base, desc_limit, 0); 778 } 779 780 if (!error && set_cs) 781 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CS, cs); 782 783 if (!error && set_ds) 784 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DS, ds); 785 786 if (!error && set_es) 787 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_ES, es); 788 789 if (!error && set_fs) 790 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_FS, fs); 791 792 if (!error && set_gs) 793 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_GS, gs); 794 795 if (!error && set_ss) 796 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_SS, ss); 797 798 if (!error && set_tr) 799 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_TR, tr); 800 801 if (!error && set_ldtr) 802 error = vm_set_register(ctx, vcpu, VM_REG_GUEST_LDTR, ldtr); 803 804 if (!error && set_x2apic_state) 805 error = vm_set_x2apic_state(ctx, vcpu, x2apic_state); 806 807 if (!error && unassign_pptdev) 808 error = vm_unassign_pptdev(ctx, bus, slot, func); 809 810 if (!error && set_exception_bitmap) { 811 error = vm_set_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP, 812 exception_bitmap); 813 } 814 815 if (!error && set_vmcs_entry_interruption_info) { 816 error = vm_set_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO, 817 vmcs_entry_interruption_info); 818 } 819 820 if (!error && (get_lowmem || get_all)) { 821 gpa = 0; 822 error = vm_get_memory_seg(ctx, gpa, &len); 823 if (error == 0) 824 printf("lowmem\t\t0x%016lx/%ld\n", gpa, len); 825 } 826 827 if (!error && (get_highmem || get_all)) { 828 gpa = 4 * GB; 829 error = vm_get_memory_seg(ctx, gpa, &len); 830 if (error == 0) 831 printf("highmem\t\t0x%016lx/%ld\n", gpa, len); 832 } 833 834 if (!error && (get_efer || get_all)) { 835 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_EFER, &efer); 836 if (error == 0) 837 printf("efer[%d]\t\t0x%016lx\n", vcpu, efer); 838 } 839 840 if (!error && (get_cr0 || get_all)) { 841 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR0, &cr0); 842 if (error == 0) 843 printf("cr0[%d]\t\t0x%016lx\n", vcpu, cr0); 844 } 845 846 if (!error && (get_cr3 || get_all)) { 847 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR3, &cr3); 848 if (error == 0) 849 printf("cr3[%d]\t\t0x%016lx\n", vcpu, cr3); 850 } 851 852 if (!error && (get_cr4 || get_all)) { 853 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR4, &cr4); 854 if (error == 0) 855 printf("cr4[%d]\t\t0x%016lx\n", vcpu, cr4); 856 } 857 858 if (!error && (get_dr7 || get_all)) { 859 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR7, &dr7); 860 if (error == 0) 861 printf("dr7[%d]\t\t0x%016lx\n", vcpu, dr7); 862 } 863 864 if (!error && (get_rsp || get_all)) { 865 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSP, &rsp); 866 if (error == 0) 867 printf("rsp[%d]\t\t0x%016lx\n", vcpu, rsp); 868 } 869 870 if (!error && (get_rip || get_all)) { 871 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip); 872 if (error == 0) 873 printf("rip[%d]\t\t0x%016lx\n", vcpu, rip); 874 } 875 876 if (!error && (get_rax || get_all)) { 877 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &rax); 878 if (error == 0) 879 printf("rax[%d]\t\t0x%016lx\n", vcpu, rax); 880 } 881 882 if (!error && (get_rbx || get_all)) { 883 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBX, &rbx); 884 if (error == 0) 885 printf("rbx[%d]\t\t0x%016lx\n", vcpu, rbx); 886 } 887 888 if (!error && (get_rcx || get_all)) { 889 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RCX, &rcx); 890 if (error == 0) 891 printf("rcx[%d]\t\t0x%016lx\n", vcpu, rcx); 892 } 893 894 if (!error && (get_rdx || get_all)) { 895 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDX, &rdx); 896 if (error == 0) 897 printf("rdx[%d]\t\t0x%016lx\n", vcpu, rdx); 898 } 899 900 if (!error && (get_rsi || get_all)) { 901 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSI, &rsi); 902 if (error == 0) 903 printf("rsi[%d]\t\t0x%016lx\n", vcpu, rsi); 904 } 905 906 if (!error && (get_rdi || get_all)) { 907 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDI, &rdi); 908 if (error == 0) 909 printf("rdi[%d]\t\t0x%016lx\n", vcpu, rdi); 910 } 911 912 if (!error && (get_rbp || get_all)) { 913 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBP, &rbp); 914 if (error == 0) 915 printf("rbp[%d]\t\t0x%016lx\n", vcpu, rbp); 916 } 917 918 if (!error && (get_r8 || get_all)) { 919 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R8, &r8); 920 if (error == 0) 921 printf("r8[%d]\t\t0x%016lx\n", vcpu, r8); 922 } 923 924 if (!error && (get_r9 || get_all)) { 925 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R9, &r9); 926 if (error == 0) 927 printf("r9[%d]\t\t0x%016lx\n", vcpu, r9); 928 } 929 930 if (!error && (get_r10 || get_all)) { 931 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R10, &r10); 932 if (error == 0) 933 printf("r10[%d]\t\t0x%016lx\n", vcpu, r10); 934 } 935 936 if (!error && (get_r11 || get_all)) { 937 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R11, &r11); 938 if (error == 0) 939 printf("r11[%d]\t\t0x%016lx\n", vcpu, r11); 940 } 941 942 if (!error && (get_r12 || get_all)) { 943 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R12, &r12); 944 if (error == 0) 945 printf("r12[%d]\t\t0x%016lx\n", vcpu, r12); 946 } 947 948 if (!error && (get_r13 || get_all)) { 949 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R13, &r13); 950 if (error == 0) 951 printf("r13[%d]\t\t0x%016lx\n", vcpu, r13); 952 } 953 954 if (!error && (get_r14 || get_all)) { 955 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R14, &r14); 956 if (error == 0) 957 printf("r14[%d]\t\t0x%016lx\n", vcpu, r14); 958 } 959 960 if (!error && (get_r15 || get_all)) { 961 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R15, &r15); 962 if (error == 0) 963 printf("r15[%d]\t\t0x%016lx\n", vcpu, r15); 964 } 965 966 if (!error && (get_rflags || get_all)) { 967 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, 968 &rflags); 969 if (error == 0) 970 printf("rflags[%d]\t0x%016lx\n", vcpu, rflags); 971 } 972 973 if (!error && (get_stats || get_all)) { 974 int i, num_stats; 975 uint64_t *stats; 976 struct timeval tv; 977 const char *desc; 978 979 stats = vm_get_stats(ctx, vcpu, &tv, &num_stats); 980 if (stats != NULL) { 981 printf("vcpu%d\n", vcpu); 982 for (i = 0; i < num_stats; i++) { 983 desc = vm_get_stat_desc(ctx, i); 984 printf("%-40s\t%ld\n", desc, stats[i]); 985 } 986 } 987 } 988 989 if (!error && (get_desc_ds || get_all)) { 990 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_DS, 991 &desc_base, &desc_limit, &desc_access); 992 if (error == 0) { 993 printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n", 994 vcpu, desc_base, desc_limit, desc_access); 995 } 996 } 997 998 if (!error && (get_desc_es || get_all)) { 999 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_ES, 1000 &desc_base, &desc_limit, &desc_access); 1001 if (error == 0) { 1002 printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n", 1003 vcpu, desc_base, desc_limit, desc_access); 1004 } 1005 } 1006 1007 if (!error && (get_desc_fs || get_all)) { 1008 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_FS, 1009 &desc_base, &desc_limit, &desc_access); 1010 if (error == 0) { 1011 printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", 1012 vcpu, desc_base, desc_limit, desc_access); 1013 } 1014 } 1015 1016 if (!error && (get_desc_gs || get_all)) { 1017 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GS, 1018 &desc_base, &desc_limit, &desc_access); 1019 if (error == 0) { 1020 printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", 1021 vcpu, desc_base, desc_limit, desc_access); 1022 } 1023 } 1024 1025 if (!error && (get_desc_ss || get_all)) { 1026 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_SS, 1027 &desc_base, &desc_limit, &desc_access); 1028 if (error == 0) { 1029 printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n", 1030 vcpu, desc_base, desc_limit, desc_access); 1031 } 1032 } 1033 1034 if (!error && (get_desc_cs || get_all)) { 1035 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_CS, 1036 &desc_base, &desc_limit, &desc_access); 1037 if (error == 0) { 1038 printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", 1039 vcpu, desc_base, desc_limit, desc_access); 1040 } 1041 } 1042 1043 if (!error && (get_desc_tr || get_all)) { 1044 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_TR, 1045 &desc_base, &desc_limit, &desc_access); 1046 if (error == 0) { 1047 printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n", 1048 vcpu, desc_base, desc_limit, desc_access); 1049 } 1050 } 1051 1052 if (!error && (get_desc_ldtr || get_all)) { 1053 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_LDTR, 1054 &desc_base, &desc_limit, &desc_access); 1055 if (error == 0) { 1056 printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n", 1057 vcpu, desc_base, desc_limit, desc_access); 1058 } 1059 } 1060 1061 if (!error && (get_desc_gdtr || get_all)) { 1062 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GDTR, 1063 &desc_base, &desc_limit, &desc_access); 1064 if (error == 0) { 1065 printf("gdtr[%d]\t\t0x%016lx/0x%08x\n", 1066 vcpu, desc_base, desc_limit); 1067 } 1068 } 1069 1070 if (!error && (get_desc_idtr || get_all)) { 1071 error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_IDTR, 1072 &desc_base, &desc_limit, &desc_access); 1073 if (error == 0) { 1074 printf("idtr[%d]\t\t0x%016lx/0x%08x\n", 1075 vcpu, desc_base, desc_limit); 1076 } 1077 } 1078 1079 if (!error && (get_cs || get_all)) { 1080 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CS, &cs); 1081 if (error == 0) 1082 printf("cs[%d]\t\t0x%04lx\n", vcpu, cs); 1083 } 1084 1085 if (!error && (get_ds || get_all)) { 1086 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DS, &ds); 1087 if (error == 0) 1088 printf("ds[%d]\t\t0x%04lx\n", vcpu, ds); 1089 } 1090 1091 if (!error && (get_es || get_all)) { 1092 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_ES, &es); 1093 if (error == 0) 1094 printf("es[%d]\t\t0x%04lx\n", vcpu, es); 1095 } 1096 1097 if (!error && (get_fs || get_all)) { 1098 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_FS, &fs); 1099 if (error == 0) 1100 printf("fs[%d]\t\t0x%04lx\n", vcpu, fs); 1101 } 1102 1103 if (!error && (get_gs || get_all)) { 1104 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_GS, &gs); 1105 if (error == 0) 1106 printf("gs[%d]\t\t0x%04lx\n", vcpu, gs); 1107 } 1108 1109 if (!error && (get_ss || get_all)) { 1110 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_SS, &ss); 1111 if (error == 0) 1112 printf("ss[%d]\t\t0x%04lx\n", vcpu, ss); 1113 } 1114 1115 if (!error && (get_tr || get_all)) { 1116 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_TR, &tr); 1117 if (error == 0) 1118 printf("tr[%d]\t\t0x%04lx\n", vcpu, tr); 1119 } 1120 1121 if (!error && (get_ldtr || get_all)) { 1122 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_LDTR, &ldtr); 1123 if (error == 0) 1124 printf("ldtr[%d]\t\t0x%04lx\n", vcpu, ldtr); 1125 } 1126 1127 if (!error && (get_x2apic_state || get_all)) { 1128 error = vm_get_x2apic_state(ctx, vcpu, &x2apic_state); 1129 if (error == 0) 1130 printf("x2apic_state[%d]\t%d\n", vcpu, x2apic_state); 1131 } 1132 1133 if (!error && (get_pinbased_ctls || get_all)) { 1134 error = vm_get_vmcs_field(ctx, vcpu, VMCS_PIN_BASED_CTLS, &ctl); 1135 if (error == 0) 1136 printf("pinbased_ctls[%d]\t0x%08lx\n", vcpu, ctl); 1137 } 1138 1139 if (!error && (get_procbased_ctls || get_all)) { 1140 error = vm_get_vmcs_field(ctx, vcpu, 1141 VMCS_PRI_PROC_BASED_CTLS, &ctl); 1142 if (error == 0) 1143 printf("procbased_ctls[%d]\t0x%08lx\n", vcpu, ctl); 1144 } 1145 1146 if (!error && (get_procbased_ctls2 || get_all)) { 1147 error = vm_get_vmcs_field(ctx, vcpu, 1148 VMCS_SEC_PROC_BASED_CTLS, &ctl); 1149 if (error == 0) 1150 printf("procbased_ctls2[%d]\t0x%08lx\n", vcpu, ctl); 1151 } 1152 1153 if (!error && (get_vmcs_gla || get_all)) { 1154 error = vm_get_vmcs_field(ctx, vcpu, 1155 VMCS_GUEST_LINEAR_ADDRESS, &u64); 1156 if (error == 0) 1157 printf("gla[%d]\t\t0x%016lx\n", vcpu, u64); 1158 } 1159 1160 if (!error && (get_vmcs_gpa || get_all)) { 1161 error = vm_get_vmcs_field(ctx, vcpu, 1162 VMCS_GUEST_PHYSICAL_ADDRESS, &u64); 1163 if (error == 0) 1164 printf("gpa[%d]\t\t0x%016lx\n", vcpu, u64); 1165 } 1166 1167 if (!error && (get_vmcs_entry_interruption_info || get_all)) { 1168 error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,&u64); 1169 if (error == 0) { 1170 printf("entry_interruption_info[%d]\t0x%08lx\n", 1171 vcpu, u64); 1172 } 1173 } 1174 1175 if (!error && (get_eptp || get_all)) { 1176 error = vm_get_vmcs_field(ctx, vcpu, VMCS_EPTP, &eptp); 1177 if (error == 0) 1178 printf("eptp[%d]\t\t0x%016lx\n", vcpu, eptp); 1179 } 1180 1181 if (!error && (get_exception_bitmap || get_all)) { 1182 error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP, 1183 &bm); 1184 if (error == 0) 1185 printf("exception_bitmap[%d]\t0x%08lx\n", vcpu, bm); 1186 } 1187 1188 if (!error && (get_io_bitmap || get_all)) { 1189 error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_A, &bm); 1190 if (error == 0) 1191 printf("io_bitmap_a[%d]\t0x%08lx\n", vcpu, bm); 1192 error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_B, &bm); 1193 if (error == 0) 1194 printf("io_bitmap_b[%d]\t0x%08lx\n", vcpu, bm); 1195 } 1196 1197 if (!error && (get_tsc_offset || get_all)) { 1198 uint64_t tscoff; 1199 error = vm_get_vmcs_field(ctx, vcpu, VMCS_TSC_OFFSET, &tscoff); 1200 if (error == 0) 1201 printf("tsc_offset[%d]\t0x%016lx\n", vcpu, tscoff); 1202 } 1203 1204 if (!error && (get_cr0_mask || get_all)) { 1205 uint64_t cr0mask; 1206 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_MASK, &cr0mask); 1207 if (error == 0) 1208 printf("cr0_mask[%d]\t\t0x%016lx\n", vcpu, cr0mask); 1209 } 1210 1211 if (!error && (get_cr0_shadow || get_all)) { 1212 uint64_t cr0shadow; 1213 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_SHADOW, 1214 &cr0shadow); 1215 if (error == 0) 1216 printf("cr0_shadow[%d]\t\t0x%016lx\n", vcpu, cr0shadow); 1217 } 1218 1219 if (!error && (get_cr4_mask || get_all)) { 1220 uint64_t cr4mask; 1221 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_MASK, &cr4mask); 1222 if (error == 0) 1223 printf("cr4_mask[%d]\t\t0x%016lx\n", vcpu, cr4mask); 1224 } 1225 1226 if (!error && (get_cr4_shadow || get_all)) { 1227 uint64_t cr4shadow; 1228 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_SHADOW, 1229 &cr4shadow); 1230 if (error == 0) 1231 printf("cr4_shadow[%d]\t\t0x%016lx\n", vcpu, cr4shadow); 1232 } 1233 1234 if (!error && (get_cr3_targets || get_all)) { 1235 uint64_t target_count, target_addr; 1236 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET_COUNT, 1237 &target_count); 1238 if (error == 0) { 1239 printf("cr3_target_count[%d]\t0x%08lx\n", 1240 vcpu, target_count); 1241 } 1242 1243 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET0, 1244 &target_addr); 1245 if (error == 0) { 1246 printf("cr3_target0[%d]\t\t0x%016lx\n", 1247 vcpu, target_addr); 1248 } 1249 1250 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET1, 1251 &target_addr); 1252 if (error == 0) { 1253 printf("cr3_target1[%d]\t\t0x%016lx\n", 1254 vcpu, target_addr); 1255 } 1256 1257 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET2, 1258 &target_addr); 1259 if (error == 0) { 1260 printf("cr3_target2[%d]\t\t0x%016lx\n", 1261 vcpu, target_addr); 1262 } 1263 1264 error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET3, 1265 &target_addr); 1266 if (error == 0) { 1267 printf("cr3_target3[%d]\t\t0x%016lx\n", 1268 vcpu, target_addr); 1269 } 1270 } 1271 1272 if (!error && (get_apic_access_addr || get_all)) { 1273 error = vm_get_vmcs_field(ctx, vcpu, VMCS_APIC_ACCESS, &addr); 1274 if (error == 0) 1275 printf("apic_access_addr[%d]\t0x%016lx\n", vcpu, addr); 1276 } 1277 1278 if (!error && (get_virtual_apic_addr || get_all)) { 1279 error = vm_get_vmcs_field(ctx, vcpu, VMCS_VIRTUAL_APIC, &addr); 1280 if (error == 0) 1281 printf("virtual_apic_addr[%d]\t0x%016lx\n", vcpu, addr); 1282 } 1283 1284 if (!error && (get_tpr_threshold || get_all)) { 1285 uint64_t threshold; 1286 error = vm_get_vmcs_field(ctx, vcpu, VMCS_TPR_THRESHOLD, 1287 &threshold); 1288 if (error == 0) 1289 printf("tpr_threshold[%d]\t0x%08lx\n", vcpu, threshold); 1290 } 1291 1292 if (!error && (get_msr_bitmap_address || get_all)) { 1293 error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, &addr); 1294 if (error == 0) 1295 printf("msr_bitmap[%d]\t\t0x%016lx\n", vcpu, addr); 1296 } 1297 1298 if (!error && (get_msr_bitmap || get_all)) { 1299 error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, &addr); 1300 if (error == 0) 1301 error = dump_vmcs_msr_bitmap(vcpu, addr); 1302 } 1303 1304 if (!error && (get_vpid || get_all)) { 1305 uint64_t vpid; 1306 error = vm_get_vmcs_field(ctx, vcpu, VMCS_VPID, &vpid); 1307 if (error == 0) 1308 printf("vpid[%d]\t\t0x%04lx\n", vcpu, vpid); 1309 } 1310 1311 if (!error && (get_ple_window || get_all)) { 1312 uint64_t window; 1313 error = vm_get_vmcs_field(ctx, vcpu, VMCS_PLE_WINDOW, &window); 1314 if (error == 0) 1315 printf("ple_window[%d]\t\t0x%08lx\n", vcpu, window); 1316 } 1317 1318 if (!error && (get_ple_gap || get_all)) { 1319 uint64_t gap; 1320 error = vm_get_vmcs_field(ctx, vcpu, VMCS_PLE_GAP, &gap); 1321 if (error == 0) 1322 printf("ple_gap[%d]\t\t0x%08lx\n", vcpu, gap); 1323 } 1324 1325 if (!error && (get_inst_err || get_all)) { 1326 uint64_t insterr; 1327 error = vm_get_vmcs_field(ctx, vcpu, VMCS_INSTRUCTION_ERROR, 1328 &insterr); 1329 if (error == 0) { 1330 printf("instruction_error[%d]\t0x%08lx\n", 1331 vcpu, insterr); 1332 } 1333 } 1334 1335 if (!error && (get_exit_ctls || get_all)) { 1336 error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_CTLS, &ctl); 1337 if (error == 0) 1338 printf("exit_ctls[%d]\t\t0x%08lx\n", vcpu, ctl); 1339 } 1340 1341 if (!error && (get_entry_ctls || get_all)) { 1342 error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_CTLS, &ctl); 1343 if (error == 0) 1344 printf("entry_ctls[%d]\t\t0x%08lx\n", vcpu, ctl); 1345 } 1346 1347 if (!error && (get_host_pat || get_all)) { 1348 error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_IA32_PAT, &pat); 1349 if (error == 0) 1350 printf("host_pat[%d]\t\t0x%016lx\n", vcpu, pat); 1351 } 1352 1353 if (!error && (get_guest_pat || get_all)) { 1354 error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_IA32_PAT, &pat); 1355 if (error == 0) 1356 printf("guest_pat[%d]\t\t0x%016lx\n", vcpu, pat); 1357 } 1358 1359 if (!error && (get_host_cr0 || get_all)) { 1360 error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR0, &cr0); 1361 if (error == 0) 1362 printf("host_cr0[%d]\t\t0x%016lx\n", vcpu, cr0); 1363 } 1364 1365 if (!error && (get_host_cr3 || get_all)) { 1366 error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR3, &cr3); 1367 if (error == 0) 1368 printf("host_cr3[%d]\t\t0x%016lx\n", vcpu, cr3); 1369 } 1370 1371 if (!error && (get_host_cr4 || get_all)) { 1372 error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR4, &cr4); 1373 if (error == 0) 1374 printf("host_cr4[%d]\t\t0x%016lx\n", vcpu, cr4); 1375 } 1376 1377 if (!error && (get_host_rip || get_all)) { 1378 error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RIP, &rip); 1379 if (error == 0) 1380 printf("host_rip[%d]\t\t0x%016lx\n", vcpu, rip); 1381 } 1382 1383 if (!error && (get_host_rsp || get_all)) { 1384 error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RSP, &rsp); 1385 if (error == 0) 1386 printf("host_rsp[%d]\t\t0x%016lx\n", vcpu, rsp); 1387 } 1388 1389 if (!error && (get_guest_sysenter || get_all)) { 1390 error = vm_get_vmcs_field(ctx, vcpu, 1391 VMCS_GUEST_IA32_SYSENTER_CS, &cs); 1392 if (error == 0) 1393 printf("guest_sysenter_cs[%d]\t0x%08lx\n", vcpu, cs); 1394 1395 error = vm_get_vmcs_field(ctx, vcpu, 1396 VMCS_GUEST_IA32_SYSENTER_ESP, &rsp); 1397 if (error == 0) 1398 printf("guest_sysenter_sp[%d]\t0x%016lx\n", vcpu, rsp); 1399 error = vm_get_vmcs_field(ctx, vcpu, 1400 VMCS_GUEST_IA32_SYSENTER_EIP, &rip); 1401 if (error == 0) 1402 printf("guest_sysenter_ip[%d]\t0x%016lx\n", vcpu, rip); 1403 } 1404 1405 if (!error && (get_vmcs_link || get_all)) { 1406 error = vm_get_vmcs_field(ctx, vcpu, VMCS_LINK_POINTER, &addr); 1407 if (error == 0) 1408 printf("vmcs_pointer[%d]\t0x%016lx\n", vcpu, addr); 1409 } 1410 1411 if (!error && (get_vmcs_exit_reason || get_all)) { 1412 error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_REASON, &u64); 1413 if (error == 0) 1414 printf("vmcs_exit_reason[%d]\t0x%016lx\n", vcpu, u64); 1415 } 1416 1417 if (!error && (get_vmcs_exit_qualification || get_all)) { 1418 error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_QUALIFICATION, 1419 &u64); 1420 if (error == 0) 1421 printf("vmcs_exit_qualification[%d]\t0x%016lx\n", 1422 vcpu, u64); 1423 } 1424 1425 if (!error && (get_vmcs_exit_interruption_info || get_all)) { 1426 error = vm_get_vmcs_field(ctx, vcpu, 1427 VMCS_EXIT_INTERRUPTION_INFO, &u64); 1428 if (error == 0) { 1429 printf("vmcs_exit_interruption_info[%d]\t0x%08lx\n", 1430 vcpu, u64); 1431 } 1432 } 1433 1434 if (!error && (get_vmcs_exit_interruption_error || get_all)) { 1435 error = vm_get_vmcs_field(ctx, vcpu, 1436 VMCS_EXIT_INTERRUPTION_ERROR, &u64); 1437 if (error == 0) { 1438 printf("vmcs_exit_interruption_error[%d]\t0x%08lx\n", 1439 vcpu, u64); 1440 } 1441 } 1442 1443 if (!error && (get_vmcs_interruptibility || get_all)) { 1444 error = vm_get_vmcs_field(ctx, vcpu, 1445 VMCS_GUEST_INTERRUPTIBILITY, &u64); 1446 if (error == 0) { 1447 printf("vmcs_guest_interruptibility[%d]\t0x%08lx\n", 1448 vcpu, u64); 1449 } 1450 } 1451 1452 if (!error && setcap) { 1453 int captype; 1454 captype = vm_capability_name2type(capname); 1455 error = vm_set_capability(ctx, vcpu, captype, capval); 1456 if (error != 0 && errno == ENOENT) 1457 printf("Capability \"%s\" is not available\n", capname); 1458 } 1459 1460 if (!error && (getcap || get_all)) { 1461 int captype, val, getcaptype; 1462 1463 if (getcap && capname) 1464 getcaptype = vm_capability_name2type(capname); 1465 else 1466 getcaptype = -1; 1467 1468 for (captype = 0; captype < VM_CAP_MAX; captype++) { 1469 if (getcaptype >= 0 && captype != getcaptype) 1470 continue; 1471 error = vm_get_capability(ctx, vcpu, captype, &val); 1472 if (error == 0) { 1473 printf("Capability \"%s\" is %s on vcpu %d\n", 1474 vm_capability_type2name(captype), 1475 val ? "set" : "not set", vcpu); 1476 } else if (errno == ENOENT) { 1477 printf("Capability \"%s\" is not available\n", 1478 vm_capability_type2name(captype)); 1479 } else { 1480 break; 1481 } 1482 } 1483 } 1484 1485 if (!error && run) { 1486 error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip); 1487 assert(error == 0); 1488 1489 error = vm_run(ctx, vcpu, rip, &vmexit); 1490 if (error == 0) 1491 dump_vm_run_exitcode(&vmexit, vcpu); 1492 else 1493 printf("vm_run error %d\n", error); 1494 } 1495 1496 if (error) 1497 printf("errno = %d\n", errno); 1498 1499 if (!error && destroy) 1500 vm_destroy(ctx); 1501 1502 exit(error); 1503 } 1504