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