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