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