Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


major VMX update
[palacios.git] / palacios / src / palacios / vmcs.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmcs.h>
21 #include <palacios/vmx_lowlevel.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vmx.h>
24 #include <palacios/vm_guest_mem.h>
25 #include <palacios/vmm_ctrl_regs.h>
26 #include <palacios/vmm_lowlevel.h>
27
28
29
30
31
32 static int inline check_vmcs_write(vmcs_field_t field, addr_t val) {
33     int ret = 0;
34     ret = vmcs_write(field, val);
35
36     if (ret != VMX_SUCCESS) {
37         PrintError("VMWRITE error on %s!: %d\n", v3_vmcs_field_to_str(field), ret);
38         return 1;
39     }
40
41     return 0;
42 }
43
44 static int inline check_vmcs_read(vmcs_field_t field, void * val) {
45     int ret = 0;
46     ret = vmcs_read(field, val);
47
48     if (ret != VMX_SUCCESS) {
49         PrintError("VMREAD error on %s!: %d\n", v3_vmcs_field_to_str(field), ret);
50     }
51
52     return ret;
53 }
54
55
56
57
58
59
60
61 typedef enum { ES = 0, 
62                CS = 2,
63                SS = 4,
64                DS = 6, 
65                FS = 8, 
66                GS = 10, 
67                LDTR = 12, 
68                TR = 14, 
69                GDTR = 16, 
70                IDTR = 18} vmcs_seg_offsets_t;
71
72 typedef enum {BASE = VMCS_GUEST_ES_BASE,
73               LIMIT = VMCS_GUEST_ES_LIMIT, 
74               ACCESS = VMCS_GUEST_ES_ACCESS, 
75               SELECTOR = VMCS_GUEST_ES_SELECTOR } vmcs_seg_bases_t;
76  
77
78
79 static int v3_read_vmcs_segment(struct v3_segment * seg, vmcs_seg_offsets_t seg_type) {
80     vmcs_field_t selector = VMCS_GUEST_ES_SELECTOR + seg_type;
81     vmcs_field_t base = VMCS_GUEST_ES_BASE + seg_type;
82     vmcs_field_t limit = VMCS_GUEST_ES_LIMIT + seg_type;
83     vmcs_field_t access = VMCS_GUEST_ES_ACCESS + seg_type;
84     struct vmcs_segment vmcs_seg;
85
86     memset(&vmcs_seg, 0, sizeof(struct vmcs_segment));
87
88     check_vmcs_read(limit, &(vmcs_seg.limit));
89     check_vmcs_read(base, &(vmcs_seg.base));
90
91     if ((seg_type != GDTR) && (seg_type != IDTR)) {
92         check_vmcs_read(selector, &(vmcs_seg.selector));
93         check_vmcs_read(access, &(vmcs_seg.access.val)); 
94     }
95
96     v3_vmxseg_to_seg(&vmcs_seg, seg);
97
98     return 0;
99 }
100
101 static int v3_write_vmcs_segment(struct v3_segment * seg, vmcs_seg_offsets_t seg_type) {
102     vmcs_field_t selector = VMCS_GUEST_ES_SELECTOR + seg_type;
103     vmcs_field_t base = VMCS_GUEST_ES_BASE + seg_type;
104     vmcs_field_t limit = VMCS_GUEST_ES_LIMIT + seg_type;
105     vmcs_field_t access = VMCS_GUEST_ES_ACCESS + seg_type;
106     struct vmcs_segment vmcs_seg;
107
108     v3_seg_to_vmxseg(seg, &vmcs_seg);
109
110     check_vmcs_write(limit, vmcs_seg.limit);
111     check_vmcs_write(base, vmcs_seg.base);
112
113     if ((seg_type != GDTR) && (seg_type != IDTR)) {
114         check_vmcs_write(access, vmcs_seg.access.val); 
115         check_vmcs_write(selector, vmcs_seg.selector);
116     }
117
118     return 0;
119 }
120
121 int v3_read_vmcs_segments(struct v3_segments * segs) {
122     v3_read_vmcs_segment(&(segs->cs), CS);
123     v3_read_vmcs_segment(&(segs->ds), DS);
124     v3_read_vmcs_segment(&(segs->es), ES);
125     v3_read_vmcs_segment(&(segs->fs), FS);
126     v3_read_vmcs_segment(&(segs->gs), GS);
127     v3_read_vmcs_segment(&(segs->ss), SS);
128     v3_read_vmcs_segment(&(segs->ldtr), LDTR);
129     v3_read_vmcs_segment(&(segs->gdtr), GDTR);
130     v3_read_vmcs_segment(&(segs->idtr), IDTR);
131     v3_read_vmcs_segment(&(segs->tr), TR);
132
133     return 0;
134 }
135
136 int v3_write_vmcs_segments(struct v3_segments * segs) {
137     v3_write_vmcs_segment(&(segs->cs), CS);
138     v3_write_vmcs_segment(&(segs->ds), DS);
139     v3_write_vmcs_segment(&(segs->es), ES);
140     v3_write_vmcs_segment(&(segs->fs), FS);
141     v3_write_vmcs_segment(&(segs->gs), GS);
142     v3_write_vmcs_segment(&(segs->ss), SS);
143     v3_write_vmcs_segment(&(segs->ldtr), LDTR);
144     v3_write_vmcs_segment(&(segs->gdtr), GDTR);
145     v3_write_vmcs_segment(&(segs->idtr), IDTR);
146     v3_write_vmcs_segment(&(segs->tr), TR);
147
148     return 0;
149 }
150
151
152 void v3_vmxseg_to_seg(struct vmcs_segment * vmcs_seg, struct v3_segment * seg) {
153     memset(seg, 0, sizeof(struct v3_segment));
154
155     seg->selector = vmcs_seg->selector;
156     seg->limit = vmcs_seg->limit;
157     seg->base = vmcs_seg->base;
158
159     seg->type = vmcs_seg->access.type;
160     seg->system = vmcs_seg->access.desc_type;
161     seg->dpl = vmcs_seg->access.dpl;
162     seg->present = vmcs_seg->access.present;
163     seg->avail = vmcs_seg->access.avail;
164     seg->long_mode = vmcs_seg->access.long_mode;
165     seg->db = vmcs_seg->access.db;
166     seg->granularity = vmcs_seg->access.granularity;
167     seg->unusable = vmcs_seg->access.unusable;
168
169 }
170
171 void v3_seg_to_vmxseg(struct v3_segment * seg, struct vmcs_segment * vmcs_seg) {
172     memset(vmcs_seg, 0, sizeof(struct vmcs_segment));
173
174     vmcs_seg->selector = seg->selector;
175     vmcs_seg->limit = seg->limit;
176     vmcs_seg->base = seg->base;
177
178     vmcs_seg->access.type = seg->type;
179     vmcs_seg->access.desc_type = seg->system;
180     vmcs_seg->access.dpl = seg->dpl;
181     vmcs_seg->access.present = seg->present;
182     vmcs_seg->access.avail = seg->avail;
183     vmcs_seg->access.long_mode = seg->long_mode;
184     vmcs_seg->access.db = seg->db;
185     vmcs_seg->access.granularity = seg->granularity;
186     vmcs_seg->access.unusable = seg->unusable;
187 }
188
189
190
191
192 int v3_update_vmcs_ctrl_fields(struct guest_info * info) {
193     int vmx_ret = 0;
194     struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data);
195
196     vmx_ret |= check_vmcs_write(VMCS_PIN_CTRLS, arch_data->pin_ctrls.value);
197     vmx_ret |= check_vmcs_write(VMCS_PROC_CTRLS, arch_data->pri_proc_ctrls.value);
198
199     if (arch_data->pri_proc_ctrls.sec_ctrls) {
200         vmx_ret |= check_vmcs_write(VMCS_SEC_PROC_CTRLS, arch_data->sec_proc_ctrls.value);
201     }
202
203     vmx_ret |= check_vmcs_write(VMCS_EXIT_CTRLS, arch_data->exit_ctrls.value);
204     vmx_ret |= check_vmcs_write(VMCS_ENTRY_CTRLS, arch_data->entry_ctrls.value);
205
206     return vmx_ret;
207 }
208
209
210
211
212
213
214 int v3_vmx_save_vmcs(struct guest_info * info) {
215     struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
216     int error = 0;
217
218     check_vmcs_read(VMCS_GUEST_RIP, &(info->rip));
219     check_vmcs_read(VMCS_GUEST_RSP, &(info->vm_regs.rsp));
220
221     check_vmcs_read(VMCS_GUEST_CR0, &(info->ctrl_regs.cr0));
222     check_vmcs_read(VMCS_CR0_READ_SHDW, &(info->shdw_pg_state.guest_cr0));
223     check_vmcs_read(VMCS_GUEST_CR3, &(info->ctrl_regs.cr3));
224     check_vmcs_read(VMCS_GUEST_CR4, &(info->ctrl_regs.cr4));
225     check_vmcs_read(VMCS_CR4_READ_SHDW, &(vmx_info->guest_cr4));
226     check_vmcs_read(VMCS_GUEST_DR7, &(info->dbg_regs.dr7));
227
228     check_vmcs_read(VMCS_GUEST_RFLAGS, &(info->ctrl_regs.rflags));
229     if (((struct vmx_data *)info->vmm_data)->ia32e_avail) {
230         check_vmcs_read(VMCS_GUEST_EFER, &(info->ctrl_regs.efer));
231     }
232
233     error =  v3_read_vmcs_segments(&(info->segments));
234
235     return error;
236 }
237
238
239 int v3_vmx_restore_vmcs(struct guest_info * info) {
240     struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
241     int error = 0;
242
243     check_vmcs_write(VMCS_GUEST_RIP, info->rip);
244     check_vmcs_write(VMCS_GUEST_RSP, info->vm_regs.rsp);
245
246     check_vmcs_write(VMCS_GUEST_CR0, info->ctrl_regs.cr0);
247     check_vmcs_write(VMCS_CR0_READ_SHDW, info->shdw_pg_state.guest_cr0);
248     check_vmcs_write(VMCS_GUEST_CR3, info->ctrl_regs.cr3);
249     check_vmcs_write(VMCS_GUEST_CR4, info->ctrl_regs.cr4);
250     check_vmcs_write(VMCS_CR4_READ_SHDW, vmx_info->guest_cr4);
251     check_vmcs_write(VMCS_GUEST_DR7, info->dbg_regs.dr7);
252
253     check_vmcs_write(VMCS_GUEST_RFLAGS, info->ctrl_regs.rflags);
254
255     if (((struct vmx_data *)info->vmm_data)->ia32e_avail) {
256         check_vmcs_write(VMCS_GUEST_EFER, info->ctrl_regs.efer);
257     }
258
259     error = v3_write_vmcs_segments(&(info->segments));
260
261     return error;
262
263 }
264
265
266
267 int v3_update_vmcs_host_state(struct guest_info * info) {
268     int vmx_ret = 0;
269     addr_t tmp;
270     struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data);
271     struct v3_msr tmp_msr;
272
273     __asm__ __volatile__ ( "movq    %%cr0, %0; "                
274                            : "=q"(tmp)
275                            :
276     );
277     vmx_ret |= check_vmcs_write(VMCS_HOST_CR0, tmp);
278
279
280     __asm__ __volatile__ ( "movq %%cr3, %0; "           
281                            : "=q"(tmp)
282                            :
283     );
284     vmx_ret |= check_vmcs_write(VMCS_HOST_CR3, tmp);
285
286
287     __asm__ __volatile__ ( "movq %%cr4, %0; "           
288                            : "=q"(tmp)
289                            :
290     );
291     vmx_ret |= check_vmcs_write(VMCS_HOST_CR4, tmp);
292
293
294
295     vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, arch_data->host_state.gdtr.base);
296     vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, arch_data->host_state.idtr.base);
297     vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, arch_data->host_state.tr.base);
298
299 #define FS_BASE_MSR 0xc0000100
300 #define GS_BASE_MSR 0xc0000101
301
302     // FS.BASE MSR
303     v3_get_msr(FS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
304     vmx_ret |= check_vmcs_write(VMCS_HOST_FS_BASE, tmp_msr.value);    
305
306     // GS.BASE MSR
307     v3_get_msr(GS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
308     vmx_ret |= check_vmcs_write(VMCS_HOST_GS_BASE, tmp_msr.value);    
309
310
311
312     __asm__ __volatile__ ( "movq %%cs, %0; "            
313                            : "=q"(tmp)
314                            :
315     );
316     vmx_ret |= check_vmcs_write(VMCS_HOST_CS_SELECTOR, tmp);
317
318     __asm__ __volatile__ ( "movq %%ss, %0; "            
319                            : "=q"(tmp)
320                            :
321     );
322     vmx_ret |= check_vmcs_write(VMCS_HOST_SS_SELECTOR, tmp);
323
324     __asm__ __volatile__ ( "movq %%ds, %0; "            
325                            : "=q"(tmp)
326                            :
327     );
328     vmx_ret |= check_vmcs_write(VMCS_HOST_DS_SELECTOR, tmp);
329
330     __asm__ __volatile__ ( "movq %%es, %0; "            
331                            : "=q"(tmp)
332                            :
333     );
334     vmx_ret |= check_vmcs_write(VMCS_HOST_ES_SELECTOR, tmp);
335
336     __asm__ __volatile__ ( "movq %%fs, %0; "            
337                            : "=q"(tmp)
338                            :
339     );
340     vmx_ret |= check_vmcs_write(VMCS_HOST_FS_SELECTOR, tmp);
341
342     __asm__ __volatile__ ( "movq %%gs, %0; "            
343                            : "=q"(tmp)
344                            :
345     );
346     vmx_ret |= check_vmcs_write(VMCS_HOST_GS_SELECTOR, tmp);
347
348     vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, arch_data->host_state.tr.selector);
349
350
351 #define SYSENTER_CS_MSR 0x00000174
352 #define SYSENTER_ESP_MSR 0x00000175
353 #define SYSENTER_EIP_MSR 0x00000176
354
355    // SYSENTER CS MSR
356     v3_get_msr(SYSENTER_CS_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
357     vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_CS, tmp_msr.lo);
358
359     // SYSENTER_ESP MSR
360     v3_get_msr(SYSENTER_ESP_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
361     vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_ESP, tmp_msr.value);
362
363     // SYSENTER_EIP MSR
364     v3_get_msr(SYSENTER_EIP_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
365     vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_EIP, tmp_msr.value);
366
367     return vmx_ret;
368 }
369
370
371
372
373
374
375 static inline void print_vmcs_field(vmcs_field_t vmcs_index) {
376     int len = v3_vmcs_get_field_len(vmcs_index);
377     addr_t val;
378     
379     if (vmcs_read(vmcs_index, &val) != VMX_SUCCESS) {
380         PrintError("VMCS_READ error for %s\n", v3_vmcs_field_to_str(vmcs_index));
381         return;
382     };
383     
384     if (len == 2) {
385         PrintDebug("\t%s: 0x%.4x\n", v3_vmcs_field_to_str(vmcs_index), (uint16_t)val);
386     } else if (len == 4) {
387         PrintDebug("\t%s: 0x%.8x\n", v3_vmcs_field_to_str(vmcs_index), (uint32_t)val);
388     } else if (len == 8) {
389         PrintDebug("\t%s: 0x%p\n", v3_vmcs_field_to_str(vmcs_index), (void *)(addr_t)val);
390     }
391 }
392
393
394 static void print_vmcs_segments() {
395     struct v3_segments segs; 
396
397     v3_read_vmcs_segments(&segs);
398     v3_print_segments(&segs);
399
400
401     PrintDebug("   ==> CS\n");
402     print_vmcs_field(VMCS_GUEST_CS_SELECTOR);
403     print_vmcs_field(VMCS_GUEST_CS_BASE);
404     print_vmcs_field(VMCS_GUEST_CS_LIMIT);
405     print_vmcs_field(VMCS_GUEST_CS_ACCESS);
406
407     PrintDebug("   ==> SS\n");
408     print_vmcs_field(VMCS_GUEST_SS_SELECTOR);
409     print_vmcs_field(VMCS_GUEST_SS_BASE);
410     print_vmcs_field(VMCS_GUEST_SS_LIMIT);
411     print_vmcs_field(VMCS_GUEST_SS_ACCESS);
412
413     PrintDebug("   ==> DS\n");
414     print_vmcs_field(VMCS_GUEST_DS_SELECTOR);
415     print_vmcs_field(VMCS_GUEST_DS_BASE);
416     print_vmcs_field(VMCS_GUEST_DS_LIMIT);
417     print_vmcs_field(VMCS_GUEST_DS_ACCESS);
418
419     PrintDebug("   ==> ES\n");
420     print_vmcs_field(VMCS_GUEST_ES_SELECTOR);
421     print_vmcs_field(VMCS_GUEST_ES_BASE);
422     print_vmcs_field(VMCS_GUEST_ES_LIMIT);
423     print_vmcs_field(VMCS_GUEST_ES_ACCESS);
424
425     PrintDebug("   ==> FS\n");
426     print_vmcs_field(VMCS_GUEST_FS_SELECTOR);
427     print_vmcs_field(VMCS_GUEST_FS_BASE);
428     print_vmcs_field(VMCS_GUEST_FS_LIMIT);
429     print_vmcs_field(VMCS_GUEST_FS_ACCESS);
430
431     PrintDebug("   ==> GS\n");
432     print_vmcs_field(VMCS_GUEST_GS_SELECTOR);
433     print_vmcs_field(VMCS_GUEST_GS_BASE);
434     print_vmcs_field(VMCS_GUEST_GS_LIMIT);
435     print_vmcs_field(VMCS_GUEST_GS_ACCESS);
436
437     PrintDebug("   ==> LDTR\n");
438     print_vmcs_field(VMCS_GUEST_LDTR_SELECTOR);
439     print_vmcs_field(VMCS_GUEST_LDTR_BASE);
440     print_vmcs_field(VMCS_GUEST_LDTR_LIMIT);
441     print_vmcs_field(VMCS_GUEST_LDTR_ACCESS);
442
443     PrintDebug("   ==> TR\n");
444     print_vmcs_field(VMCS_GUEST_TR_SELECTOR);
445     print_vmcs_field(VMCS_GUEST_TR_BASE);
446     print_vmcs_field(VMCS_GUEST_TR_LIMIT);
447     print_vmcs_field(VMCS_GUEST_TR_ACCESS);
448
449     PrintDebug("   ==> GDTR\n");
450     print_vmcs_field(VMCS_GUEST_GDTR_BASE);
451     print_vmcs_field(VMCS_GUEST_GDTR_LIMIT);
452
453     PrintDebug("   ==> IDTR\n");
454     print_vmcs_field(VMCS_GUEST_IDTR_BASE);
455     print_vmcs_field(VMCS_GUEST_IDTR_LIMIT);
456
457
458 }
459
460
461
462
463 static void print_guest_state()
464 {
465     PrintDebug("VMCS_GUEST_STATE\n");
466     print_vmcs_field(VMCS_GUEST_RIP);
467     print_vmcs_field(VMCS_GUEST_RSP);
468     print_vmcs_field(VMCS_GUEST_RFLAGS);
469     print_vmcs_field(VMCS_GUEST_CR0);
470     print_vmcs_field(VMCS_GUEST_CR3);
471     print_vmcs_field(VMCS_GUEST_CR4);
472     print_vmcs_field(VMCS_GUEST_DR7);
473
474
475     PrintDebug("\n");
476
477     print_vmcs_segments();
478
479     PrintDebug("\n");
480
481     print_vmcs_field(VMCS_GUEST_DBG_CTL);
482 #ifdef __V3_32BIT__
483     print_vmcs_field(VMCS_GUEST_DBG_CTL_HIGH);
484 #endif
485     print_vmcs_field(VMCS_GUEST_SYSENTER_CS);
486     print_vmcs_field(VMCS_GUEST_SYSENTER_ESP);
487     print_vmcs_field(VMCS_GUEST_SYSENTER_EIP);
488
489     print_vmcs_field(VMCS_GUEST_PERF_GLOBAL_CTRL);
490 #ifdef __V3_32BIT__
491     print_vmcs_field(VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH);
492 #endif
493
494     print_vmcs_field(VMCS_GUEST_SMBASE);
495
496
497     PrintDebug("GUEST_NON_REGISTER_STATE\n");
498
499     print_vmcs_field(VMCS_GUEST_ACTIVITY_STATE);
500     print_vmcs_field(VMCS_GUEST_INT_STATE);
501     print_vmcs_field(VMCS_GUEST_PENDING_DBG_EXCP);
502
503 }
504        
505 static void print_host_state()
506 {
507     PrintDebug("VMCS_HOST_STATE\n");
508
509     print_vmcs_field(VMCS_HOST_RIP);
510     print_vmcs_field(VMCS_HOST_RSP);
511     print_vmcs_field(VMCS_HOST_CR0);
512     print_vmcs_field(VMCS_HOST_CR3);
513     print_vmcs_field(VMCS_HOST_CR4);
514     
515     PrintDebug("\n");
516     print_vmcs_field(VMCS_HOST_CS_SELECTOR);
517     print_vmcs_field(VMCS_HOST_SS_SELECTOR);
518     print_vmcs_field(VMCS_HOST_DS_SELECTOR);
519     print_vmcs_field(VMCS_HOST_ES_SELECTOR);
520     print_vmcs_field(VMCS_HOST_FS_SELECTOR);
521     print_vmcs_field(VMCS_HOST_GS_SELECTOR);
522     print_vmcs_field(VMCS_HOST_TR_SELECTOR);
523
524     PrintDebug("\n");
525     print_vmcs_field(VMCS_HOST_FS_BASE);
526     print_vmcs_field(VMCS_HOST_GS_BASE);
527     print_vmcs_field(VMCS_HOST_TR_BASE);
528     print_vmcs_field(VMCS_HOST_GDTR_BASE);
529     print_vmcs_field(VMCS_HOST_IDTR_BASE);
530
531     PrintDebug("\n");
532     print_vmcs_field(VMCS_HOST_SYSENTER_CS);
533     print_vmcs_field(VMCS_HOST_SYSENTER_ESP);
534     print_vmcs_field(VMCS_HOST_SYSENTER_EIP);
535
536     print_vmcs_field(VMCS_HOST_PERF_GLOBAL_CTRL);
537 #ifdef __V3_32BIT__
538     print_vmcs_field(VMCS_HOST_PERF_GLOBAL_CTRL_HIGH);
539 #endif
540 }
541
542
543 static void print_exec_ctrls() {
544     PrintDebug("VMCS_EXEC_CTRL_FIELDS\n");
545     print_vmcs_field(VMCS_PIN_CTRLS);
546     print_vmcs_field(VMCS_PROC_CTRLS);
547     print_vmcs_field(VMCS_SEC_PROC_CTRLS);
548     
549     print_vmcs_field(VMCS_EXCP_BITMAP);
550     print_vmcs_field(VMCS_PG_FAULT_ERR_MASK);
551     print_vmcs_field(VMCS_PG_FAULT_ERR_MATCH);
552
553     print_vmcs_field(VMCS_IO_BITMAP_A_ADDR);
554 #ifdef __V3_32BIT__
555     print_vmcs_field(VMCS_IO_BITMAP_A_ADDR_HIGH);
556 #endif
557     print_vmcs_field(VMCS_IO_BITMAP_B_ADDR);
558 #ifdef __V3_32BIT__
559     print_vmcs_field(VMCS_IO_BITMAP_B_ADDR_HIGH);
560 #endif
561
562     print_vmcs_field(VMCS_TSC_OFFSET);
563 #ifdef __V3_32BIT__
564     print_vmcs_field(VMCS_TSC_OFFSET_HIGH);
565 #endif
566
567     PrintDebug("\n");
568
569     print_vmcs_field(VMCS_CR0_MASK);
570     print_vmcs_field(VMCS_CR0_READ_SHDW);
571     print_vmcs_field(VMCS_CR4_MASK);
572     print_vmcs_field(VMCS_CR4_READ_SHDW);
573
574     print_vmcs_field(VMCS_CR3_TGT_CNT);
575     print_vmcs_field(VMCS_CR3_TGT_VAL_0);
576     print_vmcs_field(VMCS_CR3_TGT_VAL_1);
577     print_vmcs_field(VMCS_CR3_TGT_VAL_2);
578     print_vmcs_field(VMCS_CR3_TGT_VAL_3);
579
580     PrintDebug("\n");
581
582     print_vmcs_field(VMCS_APIC_ACCESS_ADDR);    
583 #ifdef __V3_32BIT__
584     print_vmcs_field(VMCS_APIC_ACCESS_ADDR_HIGH);
585 #endif
586
587     print_vmcs_field(VMCS_VAPIC_ADDR);    
588 #ifdef __V3_32BIT__
589     print_vmcs_field(VMCS_VAPIC_ADDR_HIGH);
590 #endif
591
592     print_vmcs_field(VMCS_TPR_THRESHOLD);
593
594     print_vmcs_field(VMCS_MSR_BITMAP);
595 #ifdef __V3_32BIT__
596     print_vmcs_field(VMCS_MSR_BITMAP_HIGH);
597 #endif
598
599     print_vmcs_field(VMCS_EXEC_PTR);
600 #ifdef __V3_32BIT__
601     print_vmcs_field(VMCS_EXEC_PTR_HIGH);
602 #endif
603 }
604
605
606 static void print_exit_ctrls() {
607     PrintDebug("VMCS_EXIT_CTRLS\n");
608
609     print_vmcs_field(VMCS_EXIT_CTRLS);
610
611
612     print_vmcs_field(VMCS_EXIT_MSR_STORE_CNT);
613     print_vmcs_field(VMCS_EXIT_MSR_STORE_ADDR);
614 #ifdef __V3_32BIT__
615     print_vmcs_field(VMCS_EXIT_MSR_STORE_ADDR_HIGH);
616 #endif
617
618     print_vmcs_field(VMCS_EXIT_MSR_LOAD_CNT);
619     print_vmcs_field(VMCS_EXIT_MSR_LOAD_ADDR);
620 #ifdef __V3_32BIT__
621     print_vmcs_field(VMCS_EXIT_MSR_LOAD_ADDR_HIGH);
622 #endif
623
624 }
625
626
627 static void print_entry_ctrls() {
628     PrintDebug("VMCS_ENTRY_CTRLS\n");
629     
630     print_vmcs_field(VMCS_ENTRY_CTRLS);
631
632     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_CNT);
633     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_ADDR);
634 #ifdef __V3_32BIT__
635     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_ADDR_HIGH);
636 #endif
637
638     print_vmcs_field(VMCS_ENTRY_INT_INFO);
639     print_vmcs_field(VMCS_ENTRY_EXCP_ERR);
640     print_vmcs_field(VMCS_ENTRY_INSTR_LEN);
641
642
643 }
644
645
646 static void print_exit_info() {
647     PrintDebug("VMCS_EXIT_INFO\n");
648
649     print_vmcs_field(VMCS_EXIT_REASON);
650     print_vmcs_field(VMCS_EXIT_QUAL);
651
652     print_vmcs_field(VMCS_EXIT_INT_INFO);
653     print_vmcs_field(VMCS_EXIT_INT_ERR);
654
655     print_vmcs_field(VMCS_IDT_VECTOR_INFO);
656     print_vmcs_field(VMCS_IDT_VECTOR_ERR);
657
658     print_vmcs_field(VMCS_EXIT_INSTR_LEN);
659
660     print_vmcs_field(VMCS_GUEST_LINEAR_ADDR);
661     print_vmcs_field(VMCS_EXIT_INSTR_INFO);
662
663     print_vmcs_field(VMCS_IO_RCX);
664     print_vmcs_field(VMCS_IO_RSI);
665     print_vmcs_field(VMCS_IO_RDI);
666     print_vmcs_field(VMCS_IO_RIP);
667
668
669     print_vmcs_field(VMCS_INSTR_ERR);
670 }
671
672 void v3_print_vmcs() {
673
674     print_vmcs_field(VMCS_LINK_PTR);
675 #ifdef __V3_32BIT__
676     print_vmcs_field(VMCS_LINK_PTR_HIGH);
677 #endif
678
679     print_guest_state();
680     print_host_state();
681
682     print_exec_ctrls();
683     print_exit_ctrls();
684     print_entry_ctrls();
685     print_exit_info();
686
687
688
689
690 }
691
692
693 /*
694  * Returns the field length in bytes
695  */
696 int v3_vmcs_get_field_len(vmcs_field_t field) {
697     switch(field)  {
698         /* 16 bit Control Fields */
699         case VMCS_GUEST_ES_SELECTOR:
700         case VMCS_GUEST_CS_SELECTOR:
701         case VMCS_GUEST_SS_SELECTOR:
702         case VMCS_GUEST_DS_SELECTOR:
703         case VMCS_GUEST_FS_SELECTOR:
704         case VMCS_GUEST_GS_SELECTOR:
705         case VMCS_GUEST_LDTR_SELECTOR:
706         case VMCS_GUEST_TR_SELECTOR:
707         case VMCS_HOST_ES_SELECTOR:
708         case VMCS_HOST_CS_SELECTOR:
709         case VMCS_HOST_SS_SELECTOR:
710         case VMCS_HOST_DS_SELECTOR:
711         case VMCS_HOST_FS_SELECTOR:
712         case VMCS_HOST_GS_SELECTOR:
713         case VMCS_HOST_TR_SELECTOR:
714             return 2;
715
716         /* 32 bit Control Fields */
717         case VMCS_PIN_CTRLS:
718         case VMCS_PROC_CTRLS:
719         case VMCS_SEC_PROC_CTRLS:
720         case VMCS_EXCP_BITMAP:
721         case VMCS_PG_FAULT_ERR_MASK:
722         case VMCS_PG_FAULT_ERR_MATCH:
723         case VMCS_CR3_TGT_CNT:
724         case VMCS_EXIT_CTRLS:
725         case VMCS_EXIT_MSR_STORE_CNT:
726         case VMCS_EXIT_MSR_LOAD_CNT:
727         case VMCS_ENTRY_CTRLS:
728         case VMCS_ENTRY_MSR_LOAD_CNT:
729         case VMCS_ENTRY_INT_INFO:
730         case VMCS_ENTRY_EXCP_ERR:
731         case VMCS_ENTRY_INSTR_LEN:
732         case VMCS_TPR_THRESHOLD:
733         case VMCS_INSTR_ERR:
734         case VMCS_EXIT_REASON:
735         case VMCS_EXIT_INT_INFO:
736         case VMCS_EXIT_INT_ERR:
737         case VMCS_IDT_VECTOR_INFO:
738         case VMCS_IDT_VECTOR_ERR:
739         case VMCS_EXIT_INSTR_LEN:
740         case VMCS_EXIT_INSTR_INFO:
741         case VMCS_GUEST_ES_LIMIT:
742         case VMCS_GUEST_CS_LIMIT:
743         case VMCS_GUEST_SS_LIMIT:
744         case VMCS_GUEST_DS_LIMIT:
745         case VMCS_GUEST_FS_LIMIT:
746         case VMCS_GUEST_GS_LIMIT:
747         case VMCS_GUEST_LDTR_LIMIT:
748         case VMCS_GUEST_TR_LIMIT:
749         case VMCS_GUEST_GDTR_LIMIT:
750         case VMCS_GUEST_IDTR_LIMIT:
751         case VMCS_GUEST_ES_ACCESS:
752         case VMCS_GUEST_CS_ACCESS:
753         case VMCS_GUEST_SS_ACCESS:
754         case VMCS_GUEST_DS_ACCESS:
755         case VMCS_GUEST_FS_ACCESS:
756         case VMCS_GUEST_GS_ACCESS:
757         case VMCS_GUEST_LDTR_ACCESS:
758         case VMCS_GUEST_TR_ACCESS:
759         case VMCS_GUEST_INT_STATE:
760         case VMCS_GUEST_ACTIVITY_STATE:
761         case VMCS_GUEST_SMBASE:
762         case VMCS_GUEST_SYSENTER_CS:
763         case VMCS_HOST_SYSENTER_CS:
764             return 4;
765
766
767         /* high bits of variable width fields
768          * We can probably just delete most of these....
769          */
770         case VMCS_IO_BITMAP_A_ADDR_HIGH:
771         case VMCS_IO_BITMAP_B_ADDR_HIGH:
772         case VMCS_MSR_BITMAP_HIGH:
773         case VMCS_EXIT_MSR_STORE_ADDR_HIGH:
774         case VMCS_EXIT_MSR_LOAD_ADDR_HIGH:
775         case VMCS_ENTRY_MSR_LOAD_ADDR_HIGH:
776         case VMCS_EXEC_PTR_HIGH:
777         case VMCS_TSC_OFFSET_HIGH:
778         case VMCS_VAPIC_ADDR_HIGH:
779         case VMCS_APIC_ACCESS_ADDR_HIGH:
780         case VMCS_LINK_PTR_HIGH:
781         case VMCS_GUEST_DBG_CTL_HIGH:
782         case VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH:
783         case VMCS_HOST_PERF_GLOBAL_CTRL_HIGH:
784             return 4;
785
786             /* Natural Width Control Fields */
787         case VMCS_IO_BITMAP_A_ADDR:
788         case VMCS_IO_BITMAP_B_ADDR:
789         case VMCS_MSR_BITMAP:
790         case VMCS_EXIT_MSR_STORE_ADDR:
791         case VMCS_EXIT_MSR_LOAD_ADDR:
792         case VMCS_ENTRY_MSR_LOAD_ADDR:
793         case VMCS_EXEC_PTR:
794         case VMCS_TSC_OFFSET:
795         case VMCS_VAPIC_ADDR:
796         case VMCS_APIC_ACCESS_ADDR:
797         case VMCS_LINK_PTR:
798         case VMCS_GUEST_DBG_CTL:
799         case VMCS_GUEST_PERF_GLOBAL_CTRL:
800         case VMCS_HOST_PERF_GLOBAL_CTRL:
801         case VMCS_CR0_MASK:
802         case VMCS_CR4_MASK:
803         case VMCS_CR0_READ_SHDW:
804         case VMCS_CR4_READ_SHDW:
805         case VMCS_CR3_TGT_VAL_0:
806         case VMCS_CR3_TGT_VAL_1:
807         case VMCS_CR3_TGT_VAL_2:
808         case VMCS_CR3_TGT_VAL_3:
809         case VMCS_EXIT_QUAL:
810         case VMCS_IO_RCX:
811         case VMCS_IO_RSI:
812         case VMCS_IO_RDI:
813         case VMCS_IO_RIP:
814         case VMCS_GUEST_LINEAR_ADDR:
815         case VMCS_GUEST_CR0:
816         case VMCS_GUEST_CR3:
817         case VMCS_GUEST_CR4:
818         case VMCS_GUEST_ES_BASE:
819         case VMCS_GUEST_CS_BASE:
820         case VMCS_GUEST_SS_BASE:
821         case VMCS_GUEST_DS_BASE:
822         case VMCS_GUEST_FS_BASE:
823         case VMCS_GUEST_GS_BASE:
824         case VMCS_GUEST_LDTR_BASE:
825         case VMCS_GUEST_TR_BASE:
826         case VMCS_GUEST_GDTR_BASE:
827         case VMCS_GUEST_IDTR_BASE:
828         case VMCS_GUEST_DR7:
829         case VMCS_GUEST_RSP:
830         case VMCS_GUEST_RIP:
831         case VMCS_GUEST_RFLAGS:
832         case VMCS_GUEST_PENDING_DBG_EXCP:
833         case VMCS_GUEST_SYSENTER_ESP:
834         case VMCS_GUEST_SYSENTER_EIP:
835         case VMCS_HOST_CR0:
836         case VMCS_HOST_CR3:
837         case VMCS_HOST_CR4:
838         case VMCS_HOST_FS_BASE:
839         case VMCS_HOST_GS_BASE:
840         case VMCS_HOST_TR_BASE:
841         case VMCS_HOST_GDTR_BASE:
842         case VMCS_HOST_IDTR_BASE:
843         case VMCS_HOST_SYSENTER_ESP:
844         case VMCS_HOST_SYSENTER_EIP:
845         case VMCS_HOST_RSP:
846         case VMCS_HOST_RIP:
847             return sizeof(addr_t);
848
849         default:
850             PrintError("Invalid VMCS field\n");
851             return -1;
852     }
853 }
854
855
856
857
858
859
860
861
862
863
864
865
866 static const char VMCS_GUEST_ES_SELECTOR_STR[] = "GUEST_ES_SELECTOR";
867 static const char VMCS_GUEST_CS_SELECTOR_STR[] = "GUEST_CS_SELECTOR";
868 static const char VMCS_GUEST_SS_SELECTOR_STR[] = "GUEST_SS_SELECTOR";
869 static const char VMCS_GUEST_DS_SELECTOR_STR[] = "GUEST_DS_SELECTOR";
870 static const char VMCS_GUEST_FS_SELECTOR_STR[] = "GUEST_FS_SELECTOR";
871 static const char VMCS_GUEST_GS_SELECTOR_STR[] = "GUEST_GS_SELECTOR";
872 static const char VMCS_GUEST_LDTR_SELECTOR_STR[] = "GUEST_LDTR_SELECTOR";
873 static const char VMCS_GUEST_TR_SELECTOR_STR[] = "GUEST_TR_SELECTOR";
874 static const char VMCS_HOST_ES_SELECTOR_STR[] = "HOST_ES_SELECTOR";
875 static const char VMCS_HOST_CS_SELECTOR_STR[] = "HOST_CS_SELECTOR";
876 static const char VMCS_HOST_SS_SELECTOR_STR[] = "HOST_SS_SELECTOR";
877 static const char VMCS_HOST_DS_SELECTOR_STR[] = "HOST_DS_SELECTOR";
878 static const char VMCS_HOST_FS_SELECTOR_STR[] = "HOST_FS_SELECTOR";
879 static const char VMCS_HOST_GS_SELECTOR_STR[] = "HOST_GS_SELECTOR";
880 static const char VMCS_HOST_TR_SELECTOR_STR[] = "HOST_TR_SELECTOR";
881 static const char VMCS_IO_BITMAP_A_ADDR_STR[] = "IO_BITMAP_A_ADDR";
882 static const char VMCS_IO_BITMAP_A_ADDR_HIGH_STR[] = "IO_BITMAP_A_ADDR_HIGH";
883 static const char VMCS_IO_BITMAP_B_ADDR_STR[] = "IO_BITMAP_B_ADDR";
884 static const char VMCS_IO_BITMAP_B_ADDR_HIGH_STR[] = "IO_BITMAP_B_ADDR_HIGH";
885 static const char VMCS_MSR_BITMAP_STR[] = "MSR_BITMAPS";
886 static const char VMCS_MSR_BITMAP_HIGH_STR[] = "MSR_BITMAPS_HIGH";
887 static const char VMCS_EXIT_MSR_STORE_ADDR_STR[] = "EXIT_MSR_STORE_ADDR";
888 static const char VMCS_EXIT_MSR_STORE_ADDR_HIGH_STR[] = "EXIT_MSR_STORE_ADDR_HIGH";
889 static const char VMCS_EXIT_MSR_LOAD_ADDR_STR[] = "EXIT_MSR_LOAD_ADDR";
890 static const char VMCS_EXIT_MSR_LOAD_ADDR_HIGH_STR[] = "EXIT_MSR_LOAD_ADDR_HIGH";
891 static const char VMCS_ENTRY_MSR_LOAD_ADDR_STR[] = "ENTRY_MSR_LOAD_ADDR";
892 static const char VMCS_ENTRY_MSR_LOAD_ADDR_HIGH_STR[] = "ENTRY_MSR_LOAD_ADDR_HIGH";
893 static const char VMCS_EXEC_PTR_STR[] = "VMCS_EXEC_PTR";
894 static const char VMCS_EXEC_PTR_HIGH_STR[] = "VMCS_EXEC_PTR_HIGH";
895 static const char VMCS_TSC_OFFSET_STR[] = "TSC_OFFSET";
896 static const char VMCS_TSC_OFFSET_HIGH_STR[] = "TSC_OFFSET_HIGH";
897 static const char VMCS_VAPIC_ADDR_STR[] = "VAPIC_PAGE_ADDR";
898 static const char VMCS_VAPIC_ADDR_HIGH_STR[] = "VAPIC_PAGE_ADDR_HIGH";
899 static const char VMCS_APIC_ACCESS_ADDR_STR[] = "APIC_ACCESS_ADDR";
900 static const char VMCS_APIC_ACCESS_ADDR_HIGH_STR[] = "APIC_ACCESS_ADDR_HIGH";
901 static const char VMCS_LINK_PTR_STR[] = "VMCS_LINK_PTR";
902 static const char VMCS_LINK_PTR_HIGH_STR[] = "VMCS_LINK_PTR_HIGH";
903 static const char VMCS_GUEST_DBG_CTL_STR[] = "GUEST_DEBUG_CTL";
904 static const char VMCS_GUEST_DBG_CTL_HIGH_STR[] = "GUEST_DEBUG_CTL_HIGH";
905 static const char VMCS_GUEST_PERF_GLOBAL_CTRL_STR[] = "GUEST_PERF_GLOBAL_CTRL";
906 static const char VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH_STR[] = "GUEST_PERF_GLOBAL_CTRL_HIGH";
907 static const char VMCS_HOST_PERF_GLOBAL_CTRL_STR[] = "HOST_PERF_GLOBAL_CTRL";
908 static const char VMCS_HOST_PERF_GLOBAL_CTRL_HIGH_STR[] = "HOST_PERF_GLOBAL_CTRL_HIGH";
909 static const char VMCS_PIN_CTRLS_STR[] = "PIN_VM_EXEC_CTRLS";
910 static const char VMCS_PROC_CTRLS_STR[] = "PROC_VM_EXEC_CTRLS";
911 static const char VMCS_EXCP_BITMAP_STR[] = "EXCEPTION_BITMAP";
912 static const char VMCS_PG_FAULT_ERR_MASK_STR[] = "PAGE_FAULT_ERROR_MASK";
913 static const char VMCS_PG_FAULT_ERR_MATCH_STR[] = "PAGE_FAULT_ERROR_MATCH";
914 static const char VMCS_CR3_TGT_CNT_STR[] = "CR3_TARGET_COUNT";
915 static const char VMCS_EXIT_CTRLS_STR[] = "VM_EXIT_CTRLS";
916 static const char VMCS_EXIT_MSR_STORE_CNT_STR[] = "VM_EXIT_MSR_STORE_COUNT";
917 static const char VMCS_EXIT_MSR_LOAD_CNT_STR[] = "VM_EXIT_MSR_LOAD_COUNT";
918 static const char VMCS_ENTRY_CTRLS_STR[] = "VM_ENTRY_CTRLS";
919 static const char VMCS_ENTRY_MSR_LOAD_CNT_STR[] = "VM_ENTRY_MSR_LOAD_COUNT";
920 static const char VMCS_ENTRY_INT_INFO_STR[] = "VM_ENTRY_INT_INFO_FIELD";
921 static const char VMCS_ENTRY_EXCP_ERR_STR[] = "VM_ENTRY_EXCEPTION_ERROR";
922 static const char VMCS_ENTRY_INSTR_LEN_STR[] = "VM_ENTRY_INSTR_LENGTH";
923 static const char VMCS_TPR_THRESHOLD_STR[] = "TPR_THRESHOLD";
924 static const char VMCS_SEC_PROC_CTRLS_STR[] = "VMCS_SEC_PROC_CTRLS";
925 static const char VMCS_INSTR_ERR_STR[] = "VM_INSTR_ERROR";
926 static const char VMCS_EXIT_REASON_STR[] = "EXIT_REASON";
927 static const char VMCS_EXIT_INT_INFO_STR[] = "VM_EXIT_INT_INFO";
928 static const char VMCS_EXIT_INT_ERR_STR[] = "VM_EXIT_INT_ERROR";
929 static const char VMCS_IDT_VECTOR_INFO_STR[] = "IDT_VECTOR_INFO";
930 static const char VMCS_IDT_VECTOR_ERR_STR[] = "IDT_VECTOR_ERROR";
931 static const char VMCS_EXIT_INSTR_LEN_STR[] = "VM_EXIT_INSTR_LENGTH";
932 static const char VMCS_EXIT_INSTR_INFO_STR[] = "VMX_INSTR_INFO";
933 static const char VMCS_GUEST_ES_LIMIT_STR[] = "GUEST_ES_LIMIT";
934 static const char VMCS_GUEST_CS_LIMIT_STR[] = "GUEST_CS_LIMIT";
935 static const char VMCS_GUEST_SS_LIMIT_STR[] = "GUEST_SS_LIMIT";
936 static const char VMCS_GUEST_DS_LIMIT_STR[] = "GUEST_DS_LIMIT";
937 static const char VMCS_GUEST_FS_LIMIT_STR[] = "GUEST_FS_LIMIT";
938 static const char VMCS_GUEST_GS_LIMIT_STR[] = "GUEST_GS_LIMIT";
939 static const char VMCS_GUEST_LDTR_LIMIT_STR[] = "GUEST_LDTR_LIMIT";
940 static const char VMCS_GUEST_TR_LIMIT_STR[] = "GUEST_TR_LIMIT";
941 static const char VMCS_GUEST_GDTR_LIMIT_STR[] = "GUEST_GDTR_LIMIT";
942 static const char VMCS_GUEST_IDTR_LIMIT_STR[] = "GUEST_IDTR_LIMIT";
943 static const char VMCS_GUEST_ES_ACCESS_STR[] = "GUEST_ES_ACCESS";
944 static const char VMCS_GUEST_CS_ACCESS_STR[] = "GUEST_CS_ACCESS";
945 static const char VMCS_GUEST_SS_ACCESS_STR[] = "GUEST_SS_ACCESS";
946 static const char VMCS_GUEST_DS_ACCESS_STR[] = "GUEST_DS_ACCESS";
947 static const char VMCS_GUEST_FS_ACCESS_STR[] = "GUEST_FS_ACCESS";
948 static const char VMCS_GUEST_GS_ACCESS_STR[] = "GUEST_GS_ACCESS";
949 static const char VMCS_GUEST_LDTR_ACCESS_STR[] = "GUEST_LDTR_ACCESS";
950 static const char VMCS_GUEST_TR_ACCESS_STR[] = "GUEST_TR_ACCESS";
951 static const char VMCS_GUEST_INT_STATE_STR[] = "GUEST_INT_STATE";
952 static const char VMCS_GUEST_ACTIVITY_STATE_STR[] = "GUEST_ACTIVITY_STATE";
953 static const char VMCS_GUEST_SMBASE_STR[] = "GUEST_SMBASE";
954 static const char VMCS_GUEST_SYSENTER_CS_STR[] = "GUEST_SYSENTER_CS";
955 static const char VMCS_HOST_SYSENTER_CS_STR[] = "HOST_SYSENTER_CS";
956 static const char VMCS_CR0_MASK_STR[] = "CR0_GUEST_HOST_MASK";
957 static const char VMCS_CR4_MASK_STR[] = "CR4_GUEST_HOST_MASK";
958 static const char VMCS_CR0_READ_SHDW_STR[] = "CR0_READ_SHADOW";
959 static const char VMCS_CR4_READ_SHDW_STR[] = "CR4_READ_SHADOW";
960 static const char VMCS_CR3_TGT_VAL_0_STR[] = "CR3_TARGET_VALUE_0";
961 static const char VMCS_CR3_TGT_VAL_1_STR[] = "CR3_TARGET_VALUE_1";
962 static const char VMCS_CR3_TGT_VAL_2_STR[] = "CR3_TARGET_VALUE_2";
963 static const char VMCS_CR3_TGT_VAL_3_STR[] = "CR3_TARGET_VALUE_3";
964 static const char VMCS_EXIT_QUAL_STR[] = "EXIT_QUALIFICATION";
965 static const char VMCS_IO_RCX_STR[] = "IO_RCX";
966 static const char VMCS_IO_RSI_STR[] = "IO_RSI";
967 static const char VMCS_IO_RDI_STR[] = "IO_RDI";
968 static const char VMCS_IO_RIP_STR[] = "IO_RIP";
969 static const char VMCS_GUEST_LINEAR_ADDR_STR[] = "GUEST_LINEAR_ADDR";
970 static const char VMCS_GUEST_CR0_STR[] = "GUEST_CR0";
971 static const char VMCS_GUEST_CR3_STR[] = "GUEST_CR3";
972 static const char VMCS_GUEST_CR4_STR[] = "GUEST_CR4";
973 static const char VMCS_GUEST_ES_BASE_STR[] = "GUEST_ES_BASE";
974 static const char VMCS_GUEST_CS_BASE_STR[] = "GUEST_CS_BASE";
975 static const char VMCS_GUEST_SS_BASE_STR[] = "GUEST_SS_BASE";
976 static const char VMCS_GUEST_DS_BASE_STR[] = "GUEST_DS_BASE";
977 static const char VMCS_GUEST_FS_BASE_STR[] = "GUEST_FS_BASE";
978 static const char VMCS_GUEST_GS_BASE_STR[] = "GUEST_GS_BASE";
979 static const char VMCS_GUEST_LDTR_BASE_STR[] = "GUEST_LDTR_BASE";
980 static const char VMCS_GUEST_TR_BASE_STR[] = "GUEST_TR_BASE";
981 static const char VMCS_GUEST_GDTR_BASE_STR[] = "GUEST_GDTR_BASE";
982 static const char VMCS_GUEST_IDTR_BASE_STR[] = "GUEST_IDTR_BASE";
983 static const char VMCS_GUEST_DR7_STR[] = "GUEST_DR7";
984 static const char VMCS_GUEST_RSP_STR[] = "GUEST_RSP";
985 static const char VMCS_GUEST_RIP_STR[] = "GUEST_RIP";
986 static const char VMCS_GUEST_RFLAGS_STR[] = "GUEST_RFLAGS";
987 static const char VMCS_GUEST_PENDING_DBG_EXCP_STR[] = "GUEST_PENDING_DEBUG_EXCS";
988 static const char VMCS_GUEST_SYSENTER_ESP_STR[] = "GUEST_SYSENTER_ESP";
989 static const char VMCS_GUEST_SYSENTER_EIP_STR[] = "GUEST_SYSENTER_EIP";
990 static const char VMCS_HOST_CR0_STR[] = "HOST_CR0";
991 static const char VMCS_HOST_CR3_STR[] = "HOST_CR3";
992 static const char VMCS_HOST_CR4_STR[] = "HOST_CR4";
993 static const char VMCS_HOST_FS_BASE_STR[] = "HOST_FS_BASE";
994 static const char VMCS_HOST_GS_BASE_STR[] = "HOST_GS_BASE";
995 static const char VMCS_HOST_TR_BASE_STR[] = "HOST_TR_BASE";
996 static const char VMCS_HOST_GDTR_BASE_STR[] = "HOST_GDTR_BASE";
997 static const char VMCS_HOST_IDTR_BASE_STR[] = "HOST_IDTR_BASE";
998 static const char VMCS_HOST_SYSENTER_ESP_STR[] = "HOST_SYSENTER_ESP";
999 static const char VMCS_HOST_SYSENTER_EIP_STR[] = "HOST_SYSENTER_EIP";
1000 static const char VMCS_HOST_RSP_STR[] = "HOST_RSP";
1001 static const char VMCS_HOST_RIP_STR[] = "HOST_RIP";
1002
1003
1004
1005 const char * v3_vmcs_field_to_str(vmcs_field_t field) {   
1006     switch (field) {
1007         case VMCS_GUEST_ES_SELECTOR:
1008             return VMCS_GUEST_ES_SELECTOR_STR;
1009         case VMCS_GUEST_CS_SELECTOR:
1010             return VMCS_GUEST_CS_SELECTOR_STR;
1011         case VMCS_GUEST_SS_SELECTOR:
1012             return VMCS_GUEST_SS_SELECTOR_STR;
1013         case VMCS_GUEST_DS_SELECTOR:
1014             return VMCS_GUEST_DS_SELECTOR_STR;
1015         case VMCS_GUEST_FS_SELECTOR:
1016             return VMCS_GUEST_FS_SELECTOR_STR;
1017         case VMCS_GUEST_GS_SELECTOR:
1018             return VMCS_GUEST_GS_SELECTOR_STR;
1019         case VMCS_GUEST_LDTR_SELECTOR:
1020             return VMCS_GUEST_LDTR_SELECTOR_STR;
1021         case VMCS_GUEST_TR_SELECTOR:
1022             return VMCS_GUEST_TR_SELECTOR_STR;
1023         case VMCS_HOST_ES_SELECTOR:
1024             return VMCS_HOST_ES_SELECTOR_STR;
1025         case VMCS_HOST_CS_SELECTOR:
1026             return VMCS_HOST_CS_SELECTOR_STR;
1027         case VMCS_HOST_SS_SELECTOR:
1028             return VMCS_HOST_SS_SELECTOR_STR;
1029         case VMCS_HOST_DS_SELECTOR:
1030             return VMCS_HOST_DS_SELECTOR_STR;
1031         case VMCS_HOST_FS_SELECTOR:
1032             return VMCS_HOST_FS_SELECTOR_STR;
1033         case VMCS_HOST_GS_SELECTOR:
1034             return VMCS_HOST_GS_SELECTOR_STR;
1035         case VMCS_HOST_TR_SELECTOR:
1036             return VMCS_HOST_TR_SELECTOR_STR;
1037         case VMCS_IO_BITMAP_A_ADDR:
1038             return VMCS_IO_BITMAP_A_ADDR_STR;
1039         case VMCS_IO_BITMAP_A_ADDR_HIGH:
1040             return VMCS_IO_BITMAP_A_ADDR_HIGH_STR;
1041         case VMCS_IO_BITMAP_B_ADDR:
1042             return VMCS_IO_BITMAP_B_ADDR_STR;
1043         case VMCS_IO_BITMAP_B_ADDR_HIGH:
1044             return VMCS_IO_BITMAP_B_ADDR_HIGH_STR;
1045         case VMCS_MSR_BITMAP:
1046             return VMCS_MSR_BITMAP_STR;
1047         case VMCS_MSR_BITMAP_HIGH:
1048             return VMCS_MSR_BITMAP_HIGH_STR;
1049         case VMCS_EXIT_MSR_STORE_ADDR:
1050             return VMCS_EXIT_MSR_STORE_ADDR_STR;
1051         case VMCS_EXIT_MSR_STORE_ADDR_HIGH:
1052             return VMCS_EXIT_MSR_STORE_ADDR_HIGH_STR;
1053         case VMCS_EXIT_MSR_LOAD_ADDR:
1054             return VMCS_EXIT_MSR_LOAD_ADDR_STR;
1055         case VMCS_EXIT_MSR_LOAD_ADDR_HIGH:
1056             return VMCS_EXIT_MSR_LOAD_ADDR_HIGH_STR;
1057         case VMCS_ENTRY_MSR_LOAD_ADDR:
1058             return VMCS_ENTRY_MSR_LOAD_ADDR_STR;
1059         case VMCS_ENTRY_MSR_LOAD_ADDR_HIGH:
1060             return VMCS_ENTRY_MSR_LOAD_ADDR_HIGH_STR;
1061         case VMCS_EXEC_PTR:
1062             return VMCS_EXEC_PTR_STR;
1063         case VMCS_EXEC_PTR_HIGH:
1064             return VMCS_EXEC_PTR_HIGH_STR;
1065         case VMCS_TSC_OFFSET:
1066             return VMCS_TSC_OFFSET_STR;
1067         case VMCS_TSC_OFFSET_HIGH:
1068             return VMCS_TSC_OFFSET_HIGH_STR;
1069         case VMCS_VAPIC_ADDR:
1070             return VMCS_VAPIC_ADDR_STR;
1071         case VMCS_VAPIC_ADDR_HIGH:
1072             return VMCS_VAPIC_ADDR_HIGH_STR;
1073         case VMCS_APIC_ACCESS_ADDR:
1074             return VMCS_APIC_ACCESS_ADDR_STR;
1075         case VMCS_APIC_ACCESS_ADDR_HIGH:
1076             return VMCS_APIC_ACCESS_ADDR_HIGH_STR;
1077         case VMCS_LINK_PTR:
1078             return VMCS_LINK_PTR_STR;
1079         case VMCS_LINK_PTR_HIGH:
1080             return VMCS_LINK_PTR_HIGH_STR;
1081         case VMCS_GUEST_DBG_CTL:
1082             return VMCS_GUEST_DBG_CTL_STR;
1083         case VMCS_GUEST_DBG_CTL_HIGH:
1084             return VMCS_GUEST_DBG_CTL_HIGH_STR;
1085         case VMCS_GUEST_PERF_GLOBAL_CTRL:
1086             return VMCS_GUEST_PERF_GLOBAL_CTRL_STR;
1087         case VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH:
1088             return VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH_STR;
1089         case VMCS_HOST_PERF_GLOBAL_CTRL:
1090             return VMCS_HOST_PERF_GLOBAL_CTRL_STR;
1091         case VMCS_HOST_PERF_GLOBAL_CTRL_HIGH:
1092             return VMCS_HOST_PERF_GLOBAL_CTRL_HIGH_STR;
1093         case VMCS_PIN_CTRLS:
1094             return VMCS_PIN_CTRLS_STR;
1095         case VMCS_PROC_CTRLS:
1096             return VMCS_PROC_CTRLS_STR;
1097         case VMCS_EXCP_BITMAP:
1098             return VMCS_EXCP_BITMAP_STR;
1099         case VMCS_PG_FAULT_ERR_MASK:
1100             return VMCS_PG_FAULT_ERR_MASK_STR;
1101         case VMCS_PG_FAULT_ERR_MATCH:
1102             return VMCS_PG_FAULT_ERR_MATCH_STR;
1103         case VMCS_CR3_TGT_CNT:
1104             return VMCS_CR3_TGT_CNT_STR;
1105         case VMCS_EXIT_CTRLS:
1106             return VMCS_EXIT_CTRLS_STR;
1107         case VMCS_EXIT_MSR_STORE_CNT:
1108             return VMCS_EXIT_MSR_STORE_CNT_STR;
1109         case VMCS_EXIT_MSR_LOAD_CNT:
1110             return VMCS_EXIT_MSR_LOAD_CNT_STR;
1111         case VMCS_ENTRY_CTRLS:
1112             return VMCS_ENTRY_CTRLS_STR;
1113         case VMCS_ENTRY_MSR_LOAD_CNT:
1114             return VMCS_ENTRY_MSR_LOAD_CNT_STR;
1115         case VMCS_ENTRY_INT_INFO:
1116             return VMCS_ENTRY_INT_INFO_STR;
1117         case VMCS_ENTRY_EXCP_ERR:
1118             return VMCS_ENTRY_EXCP_ERR_STR;
1119         case VMCS_ENTRY_INSTR_LEN:
1120             return VMCS_ENTRY_INSTR_LEN_STR;
1121         case VMCS_TPR_THRESHOLD:
1122             return VMCS_TPR_THRESHOLD_STR;
1123         case VMCS_SEC_PROC_CTRLS:
1124             return VMCS_SEC_PROC_CTRLS_STR;
1125         case VMCS_INSTR_ERR:
1126             return VMCS_INSTR_ERR_STR;
1127         case VMCS_EXIT_REASON:
1128             return VMCS_EXIT_REASON_STR;
1129         case VMCS_EXIT_INT_INFO:
1130             return VMCS_EXIT_INT_INFO_STR;
1131         case VMCS_EXIT_INT_ERR:
1132             return VMCS_EXIT_INT_ERR_STR;
1133         case VMCS_IDT_VECTOR_INFO:
1134             return VMCS_IDT_VECTOR_INFO_STR;
1135         case VMCS_IDT_VECTOR_ERR:
1136             return VMCS_IDT_VECTOR_ERR_STR;
1137         case VMCS_EXIT_INSTR_LEN:
1138             return VMCS_EXIT_INSTR_LEN_STR;
1139         case VMCS_EXIT_INSTR_INFO:
1140             return VMCS_EXIT_INSTR_INFO_STR;
1141         case VMCS_GUEST_ES_LIMIT:
1142             return VMCS_GUEST_ES_LIMIT_STR;
1143         case VMCS_GUEST_CS_LIMIT:
1144             return VMCS_GUEST_CS_LIMIT_STR;
1145         case VMCS_GUEST_SS_LIMIT:
1146             return VMCS_GUEST_SS_LIMIT_STR;
1147         case VMCS_GUEST_DS_LIMIT:
1148             return VMCS_GUEST_DS_LIMIT_STR;
1149         case VMCS_GUEST_FS_LIMIT:
1150             return VMCS_GUEST_FS_LIMIT_STR;
1151         case VMCS_GUEST_GS_LIMIT:
1152             return VMCS_GUEST_GS_LIMIT_STR;
1153         case VMCS_GUEST_LDTR_LIMIT:
1154             return VMCS_GUEST_LDTR_LIMIT_STR;
1155         case VMCS_GUEST_TR_LIMIT:
1156             return VMCS_GUEST_TR_LIMIT_STR;
1157         case VMCS_GUEST_GDTR_LIMIT:
1158             return VMCS_GUEST_GDTR_LIMIT_STR;
1159         case VMCS_GUEST_IDTR_LIMIT:
1160             return VMCS_GUEST_IDTR_LIMIT_STR;
1161         case VMCS_GUEST_ES_ACCESS:
1162             return VMCS_GUEST_ES_ACCESS_STR;
1163         case VMCS_GUEST_CS_ACCESS:
1164             return VMCS_GUEST_CS_ACCESS_STR;
1165         case VMCS_GUEST_SS_ACCESS:
1166             return VMCS_GUEST_SS_ACCESS_STR;
1167         case VMCS_GUEST_DS_ACCESS:
1168             return VMCS_GUEST_DS_ACCESS_STR;
1169         case VMCS_GUEST_FS_ACCESS:
1170             return VMCS_GUEST_FS_ACCESS_STR;
1171         case VMCS_GUEST_GS_ACCESS:
1172             return VMCS_GUEST_GS_ACCESS_STR;
1173         case VMCS_GUEST_LDTR_ACCESS:
1174             return VMCS_GUEST_LDTR_ACCESS_STR;
1175         case VMCS_GUEST_TR_ACCESS:
1176             return VMCS_GUEST_TR_ACCESS_STR;
1177         case VMCS_GUEST_INT_STATE:
1178             return VMCS_GUEST_INT_STATE_STR;
1179         case VMCS_GUEST_ACTIVITY_STATE:
1180             return VMCS_GUEST_ACTIVITY_STATE_STR;
1181         case VMCS_GUEST_SMBASE:
1182             return VMCS_GUEST_SMBASE_STR;
1183         case VMCS_GUEST_SYSENTER_CS:
1184             return VMCS_GUEST_SYSENTER_CS_STR;
1185         case VMCS_HOST_SYSENTER_CS:
1186             return VMCS_HOST_SYSENTER_CS_STR;
1187         case VMCS_CR0_MASK:
1188             return VMCS_CR0_MASK_STR;
1189         case VMCS_CR4_MASK:
1190             return VMCS_CR4_MASK_STR;
1191         case VMCS_CR0_READ_SHDW:
1192             return VMCS_CR0_READ_SHDW_STR;
1193         case VMCS_CR4_READ_SHDW:
1194             return VMCS_CR4_READ_SHDW_STR;
1195         case VMCS_CR3_TGT_VAL_0:
1196             return VMCS_CR3_TGT_VAL_0_STR;
1197         case VMCS_CR3_TGT_VAL_1:
1198             return VMCS_CR3_TGT_VAL_1_STR;
1199         case VMCS_CR3_TGT_VAL_2:
1200             return VMCS_CR3_TGT_VAL_2_STR;
1201         case VMCS_CR3_TGT_VAL_3:
1202             return VMCS_CR3_TGT_VAL_3_STR;
1203         case VMCS_EXIT_QUAL:
1204             return VMCS_EXIT_QUAL_STR;
1205         case VMCS_IO_RCX:
1206             return VMCS_IO_RCX_STR;
1207         case VMCS_IO_RSI:
1208             return VMCS_IO_RSI_STR;
1209         case VMCS_IO_RDI:
1210             return VMCS_IO_RDI_STR;
1211         case VMCS_IO_RIP:
1212             return VMCS_IO_RIP_STR;
1213         case VMCS_GUEST_LINEAR_ADDR:
1214             return VMCS_GUEST_LINEAR_ADDR_STR;
1215         case VMCS_GUEST_CR0:
1216             return VMCS_GUEST_CR0_STR;
1217         case VMCS_GUEST_CR3:
1218             return VMCS_GUEST_CR3_STR;
1219         case VMCS_GUEST_CR4:
1220             return VMCS_GUEST_CR4_STR;
1221         case VMCS_GUEST_ES_BASE:
1222             return VMCS_GUEST_ES_BASE_STR;
1223         case VMCS_GUEST_CS_BASE:
1224             return VMCS_GUEST_CS_BASE_STR;
1225         case VMCS_GUEST_SS_BASE:
1226             return VMCS_GUEST_SS_BASE_STR;
1227         case VMCS_GUEST_DS_BASE:
1228             return VMCS_GUEST_DS_BASE_STR;
1229         case VMCS_GUEST_FS_BASE:
1230             return VMCS_GUEST_FS_BASE_STR;
1231         case VMCS_GUEST_GS_BASE:
1232             return VMCS_GUEST_GS_BASE_STR;
1233         case VMCS_GUEST_LDTR_BASE:
1234             return VMCS_GUEST_LDTR_BASE_STR;
1235         case VMCS_GUEST_TR_BASE:
1236             return VMCS_GUEST_TR_BASE_STR;
1237         case VMCS_GUEST_GDTR_BASE:
1238             return VMCS_GUEST_GDTR_BASE_STR;
1239         case VMCS_GUEST_IDTR_BASE:
1240             return VMCS_GUEST_IDTR_BASE_STR;
1241         case VMCS_GUEST_DR7:
1242             return VMCS_GUEST_DR7_STR;
1243         case VMCS_GUEST_RSP:
1244             return VMCS_GUEST_RSP_STR;
1245         case VMCS_GUEST_RIP:
1246             return VMCS_GUEST_RIP_STR;
1247         case VMCS_GUEST_RFLAGS:
1248             return VMCS_GUEST_RFLAGS_STR;
1249         case VMCS_GUEST_PENDING_DBG_EXCP:
1250             return VMCS_GUEST_PENDING_DBG_EXCP_STR;
1251         case VMCS_GUEST_SYSENTER_ESP:
1252             return VMCS_GUEST_SYSENTER_ESP_STR;
1253         case VMCS_GUEST_SYSENTER_EIP:
1254             return VMCS_GUEST_SYSENTER_EIP_STR;
1255         case VMCS_HOST_CR0:
1256             return VMCS_HOST_CR0_STR;
1257         case VMCS_HOST_CR3:
1258             return VMCS_HOST_CR3_STR;
1259         case VMCS_HOST_CR4:
1260             return VMCS_HOST_CR4_STR;
1261         case VMCS_HOST_FS_BASE:
1262             return VMCS_HOST_FS_BASE_STR;
1263         case VMCS_HOST_GS_BASE:
1264             return VMCS_HOST_GS_BASE_STR;
1265         case VMCS_HOST_TR_BASE:
1266             return VMCS_HOST_TR_BASE_STR;
1267         case VMCS_HOST_GDTR_BASE:
1268             return VMCS_HOST_GDTR_BASE_STR;
1269         case VMCS_HOST_IDTR_BASE:
1270             return VMCS_HOST_IDTR_BASE_STR;
1271         case VMCS_HOST_SYSENTER_ESP:
1272             return VMCS_HOST_SYSENTER_ESP_STR;
1273         case VMCS_HOST_SYSENTER_EIP:
1274             return VMCS_HOST_SYSENTER_EIP_STR;
1275         case VMCS_HOST_RSP:
1276             return VMCS_HOST_RSP_STR;
1277         case VMCS_HOST_RIP:
1278             return VMCS_HOST_RIP_STR;
1279         default:
1280             return NULL;
1281     }
1282 }
1283
1284
1285