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