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