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.


vmx updates
[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     vmx_ret |= check_vmcs_write(VMCS_EXCP_BITMAP, arch_data->excp_bmap.value);
206
207     return vmx_ret;
208 }
209
210
211
212
213
214
215 int v3_vmx_save_vmcs(struct guest_info * info) {
216     struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
217     int error = 0;
218
219     check_vmcs_read(VMCS_GUEST_RIP, &(info->rip));
220     check_vmcs_read(VMCS_GUEST_RSP, &(info->vm_regs.rsp));
221
222     check_vmcs_read(VMCS_GUEST_CR0, &(info->ctrl_regs.cr0));
223     check_vmcs_read(VMCS_CR0_READ_SHDW, &(info->shdw_pg_state.guest_cr0));
224     check_vmcs_read(VMCS_GUEST_CR3, &(info->ctrl_regs.cr3));
225     check_vmcs_read(VMCS_GUEST_CR4, &(info->ctrl_regs.cr4));
226     check_vmcs_read(VMCS_CR4_READ_SHDW, &(vmx_info->guest_cr4));
227     check_vmcs_read(VMCS_GUEST_DR7, &(info->dbg_regs.dr7));
228
229     check_vmcs_read(VMCS_GUEST_RFLAGS, &(info->ctrl_regs.rflags));
230     if (((struct vmx_data *)info->vmm_data)->ia32e_avail) {
231 #ifdef __V3_64BIT__
232         check_vmcs_read(VMCS_GUEST_EFER, &(info->ctrl_regs.efer));
233 #else
234         uint32_t hi, lo;
235         check_vmcs_read(VMCS_GUEST_EFER, &hi);
236         check_vmcs_read(VMCS_GUEST_EFER_HIGH, &lo);
237         info->ctrl_regs.efer = ((uint64_t) hi << 32) | lo;
238 #endif
239     }
240
241     error =  v3_read_vmcs_segments(&(info->segments));
242
243     return error;
244 }
245
246
247 int v3_vmx_restore_vmcs(struct guest_info * info) {
248     struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
249     int error = 0;
250
251     check_vmcs_write(VMCS_GUEST_RIP, info->rip);
252     check_vmcs_write(VMCS_GUEST_RSP, info->vm_regs.rsp);
253
254     check_vmcs_write(VMCS_GUEST_CR0, info->ctrl_regs.cr0);
255     check_vmcs_write(VMCS_CR0_READ_SHDW, info->shdw_pg_state.guest_cr0);
256     check_vmcs_write(VMCS_GUEST_CR3, info->ctrl_regs.cr3);
257     check_vmcs_write(VMCS_GUEST_CR4, info->ctrl_regs.cr4);
258     check_vmcs_write(VMCS_CR4_READ_SHDW, vmx_info->guest_cr4);
259     check_vmcs_write(VMCS_GUEST_DR7, info->dbg_regs.dr7);
260
261     check_vmcs_write(VMCS_GUEST_RFLAGS, info->ctrl_regs.rflags);
262
263     if (((struct vmx_data *)info->vmm_data)->ia32e_avail) {
264         check_vmcs_write(VMCS_GUEST_EFER, info->ctrl_regs.efer);
265     }
266
267     error = v3_write_vmcs_segments(&(info->segments));
268
269     return error;
270
271 }
272
273
274
275 int v3_update_vmcs_host_state(struct guest_info * info) {
276     int vmx_ret = 0;
277     addr_t tmp;
278     struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data);
279     struct v3_msr tmp_msr;
280
281 #ifdef __V3_64BIT__
282     __asm__ __volatile__ ( "movq    %%cr0, %0; "                
283                            : "=q"(tmp)
284                            :
285     );
286 #else
287     __asm__ __volatile__ ( "movl    %%cr0, %0; "                
288                            : "=q"(tmp)
289                            :
290     );
291 #endif    
292     vmx_ret |= check_vmcs_write(VMCS_HOST_CR0, tmp);
293
294
295 #ifdef __V3_64BIT__
296     __asm__ __volatile__ ( "movq %%cr3, %0; "           
297                            : "=q"(tmp)
298                            :
299     );
300 #else
301     __asm__ __volatile__ ( "movl %%cr3, %0; "           
302                            : "=q"(tmp)
303                            :
304     );
305 #endif
306     vmx_ret |= check_vmcs_write(VMCS_HOST_CR3, tmp);
307
308
309 #ifdef __V3_64BIT__
310     __asm__ __volatile__ ( "movq %%cr4, %0; "           
311                            : "=q"(tmp)
312                            :
313     );
314 #else
315     __asm__ __volatile__ ( "movl %%cr4, %0; "           
316                            : "=q"(tmp)
317                            :
318     );
319 #endif
320     vmx_ret |= check_vmcs_write(VMCS_HOST_CR4, tmp);
321
322
323
324     vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, arch_data->host_state.gdtr.base);
325     vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, arch_data->host_state.idtr.base);
326     vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, arch_data->host_state.tr.base);
327
328 #define FS_BASE_MSR 0xc0000100
329 #define GS_BASE_MSR 0xc0000101
330
331     // FS.BASE MSR
332     v3_get_msr(FS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
333     vmx_ret |= check_vmcs_write(VMCS_HOST_FS_BASE, tmp_msr.value);    
334
335     // GS.BASE MSR
336     v3_get_msr(GS_BASE_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
337     vmx_ret |= check_vmcs_write(VMCS_HOST_GS_BASE, tmp_msr.value);    
338
339
340
341 #ifdef __V3_64BIT__
342     __asm__ __volatile__ ( "movq %%cs, %0; "            
343                            : "=q"(tmp)
344                            :
345     );
346 #else
347     __asm__ __volatile__ ( "movl %%cs, %0; "            
348                            : "=q"(tmp)
349                            :
350     );
351 #endif
352     vmx_ret |= check_vmcs_write(VMCS_HOST_CS_SELECTOR, tmp);
353
354 #ifdef __V3_64BIT__
355     __asm__ __volatile__ ( "movq %%ss, %0; "            
356                            : "=q"(tmp)
357                            :
358     );
359 #else
360     __asm__ __volatile__ ( "movl %%ss, %0; "            
361                            : "=q"(tmp)
362                            :
363     );
364 #endif
365     vmx_ret |= check_vmcs_write(VMCS_HOST_SS_SELECTOR, tmp);
366
367 #ifdef __V3_64BIT__
368     __asm__ __volatile__ ( "movq %%ds, %0; "            
369                            : "=q"(tmp)
370                            :
371     );
372 #else
373     __asm__ __volatile__ ( "movl %%ds, %0; "            
374                            : "=q"(tmp)
375                            :
376     );
377 #endif
378     vmx_ret |= check_vmcs_write(VMCS_HOST_DS_SELECTOR, tmp);
379
380 #ifdef __V3_64BIT__
381     __asm__ __volatile__ ( "movq %%es, %0; "            
382                            : "=q"(tmp)
383                            :
384     );
385 #else
386     __asm__ __volatile__ ( "movl %%es, %0; "            
387                            : "=q"(tmp)
388                            :
389     );
390 #endif
391     vmx_ret |= check_vmcs_write(VMCS_HOST_ES_SELECTOR, tmp);
392
393 #ifdef __V3_64BIT__
394     __asm__ __volatile__ ( "movq %%fs, %0; "            
395                            : "=q"(tmp)
396                            :
397     );
398 #else
399     __asm__ __volatile__ ( "movl %%fs, %0; "            
400                            : "=q"(tmp)
401                            :
402     );
403 #endif
404     vmx_ret |= check_vmcs_write(VMCS_HOST_FS_SELECTOR, tmp);
405
406 #ifdef __V3_64BIT__
407     __asm__ __volatile__ ( "movq %%gs, %0; "            
408                            : "=q"(tmp)
409                            :
410     );
411 #else
412     __asm__ __volatile__ ( "movl %%gs, %0; "            
413                            : "=q"(tmp)
414                            :
415     );
416 #endif
417     vmx_ret |= check_vmcs_write(VMCS_HOST_GS_SELECTOR, tmp);
418
419     vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, arch_data->host_state.tr.selector);
420
421
422 #define SYSENTER_CS_MSR 0x00000174
423 #define SYSENTER_ESP_MSR 0x00000175
424 #define SYSENTER_EIP_MSR 0x00000176
425
426     // SYSENTER CS MSR
427     v3_get_msr(SYSENTER_CS_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
428     vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_CS, tmp_msr.lo);
429
430     // SYSENTER_ESP MSR
431     v3_get_msr(SYSENTER_ESP_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
432     vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_ESP, tmp_msr.value);
433
434     // SYSENTER_EIP MSR
435     v3_get_msr(SYSENTER_EIP_MSR, &(tmp_msr.hi), &(tmp_msr.lo));
436     vmx_ret |= check_vmcs_write(VMCS_HOST_SYSENTER_EIP, tmp_msr.value);
437
438     return vmx_ret;
439 }
440
441
442
443
444
445
446 static inline void print_vmcs_field(vmcs_field_t vmcs_index) {
447     int len = v3_vmcs_get_field_len(vmcs_index);
448     addr_t val;
449     
450     if (vmcs_read(vmcs_index, &val) != VMX_SUCCESS) {
451         PrintError("VMCS_READ error for %s\n", v3_vmcs_field_to_str(vmcs_index));
452         return;
453     };
454     
455     if (len == 2) {
456         PrintDebug("\t%s: 0x%.4x\n", v3_vmcs_field_to_str(vmcs_index), (uint16_t)val);
457     } else if (len == 4) {
458         PrintDebug("\t%s: 0x%.8x\n", v3_vmcs_field_to_str(vmcs_index), (uint32_t)val);
459     } else if (len == 8) {
460         PrintDebug("\t%s: 0x%p\n", v3_vmcs_field_to_str(vmcs_index), (void *)(addr_t)val);
461     }
462 }
463
464
465 static void print_vmcs_segments() {
466     struct v3_segments segs; 
467
468     v3_read_vmcs_segments(&segs);
469     v3_print_segments(&segs);
470
471
472     PrintDebug("   ==> CS\n");
473     print_vmcs_field(VMCS_GUEST_CS_SELECTOR);
474     print_vmcs_field(VMCS_GUEST_CS_BASE);
475     print_vmcs_field(VMCS_GUEST_CS_LIMIT);
476     print_vmcs_field(VMCS_GUEST_CS_ACCESS);
477
478     PrintDebug("   ==> SS\n");
479     print_vmcs_field(VMCS_GUEST_SS_SELECTOR);
480     print_vmcs_field(VMCS_GUEST_SS_BASE);
481     print_vmcs_field(VMCS_GUEST_SS_LIMIT);
482     print_vmcs_field(VMCS_GUEST_SS_ACCESS);
483
484     PrintDebug("   ==> DS\n");
485     print_vmcs_field(VMCS_GUEST_DS_SELECTOR);
486     print_vmcs_field(VMCS_GUEST_DS_BASE);
487     print_vmcs_field(VMCS_GUEST_DS_LIMIT);
488     print_vmcs_field(VMCS_GUEST_DS_ACCESS);
489
490     PrintDebug("   ==> ES\n");
491     print_vmcs_field(VMCS_GUEST_ES_SELECTOR);
492     print_vmcs_field(VMCS_GUEST_ES_BASE);
493     print_vmcs_field(VMCS_GUEST_ES_LIMIT);
494     print_vmcs_field(VMCS_GUEST_ES_ACCESS);
495
496     PrintDebug("   ==> FS\n");
497     print_vmcs_field(VMCS_GUEST_FS_SELECTOR);
498     print_vmcs_field(VMCS_GUEST_FS_BASE);
499     print_vmcs_field(VMCS_GUEST_FS_LIMIT);
500     print_vmcs_field(VMCS_GUEST_FS_ACCESS);
501
502     PrintDebug("   ==> GS\n");
503     print_vmcs_field(VMCS_GUEST_GS_SELECTOR);
504     print_vmcs_field(VMCS_GUEST_GS_BASE);
505     print_vmcs_field(VMCS_GUEST_GS_LIMIT);
506     print_vmcs_field(VMCS_GUEST_GS_ACCESS);
507
508     PrintDebug("   ==> LDTR\n");
509     print_vmcs_field(VMCS_GUEST_LDTR_SELECTOR);
510     print_vmcs_field(VMCS_GUEST_LDTR_BASE);
511     print_vmcs_field(VMCS_GUEST_LDTR_LIMIT);
512     print_vmcs_field(VMCS_GUEST_LDTR_ACCESS);
513
514     PrintDebug("   ==> TR\n");
515     print_vmcs_field(VMCS_GUEST_TR_SELECTOR);
516     print_vmcs_field(VMCS_GUEST_TR_BASE);
517     print_vmcs_field(VMCS_GUEST_TR_LIMIT);
518     print_vmcs_field(VMCS_GUEST_TR_ACCESS);
519
520     PrintDebug("   ==> GDTR\n");
521     print_vmcs_field(VMCS_GUEST_GDTR_BASE);
522     print_vmcs_field(VMCS_GUEST_GDTR_LIMIT);
523
524     PrintDebug("   ==> IDTR\n");
525     print_vmcs_field(VMCS_GUEST_IDTR_BASE);
526     print_vmcs_field(VMCS_GUEST_IDTR_LIMIT);
527
528
529 }
530
531
532
533
534 static void print_guest_state()
535 {
536     PrintDebug("VMCS_GUEST_STATE\n");
537     print_vmcs_field(VMCS_GUEST_RIP);
538     print_vmcs_field(VMCS_GUEST_RSP);
539     print_vmcs_field(VMCS_GUEST_RFLAGS);
540     print_vmcs_field(VMCS_GUEST_CR0);
541     print_vmcs_field(VMCS_GUEST_CR3);
542     print_vmcs_field(VMCS_GUEST_CR4);
543     print_vmcs_field(VMCS_GUEST_DR7);
544
545     // if save IA32_EFER
546     print_vmcs_field(VMCS_GUEST_EFER);
547 #ifdef __V3_32BIT__
548     print_vmcs_field(VMCS_GUEST_EFER_HIGH);
549 #endif
550
551
552     PrintDebug("\n");
553
554     print_vmcs_segments();
555
556     PrintDebug("\n");
557
558     print_vmcs_field(VMCS_GUEST_DBG_CTL);
559 #ifdef __V3_32BIT__
560     print_vmcs_field(VMCS_GUEST_DBG_CTL_HIGH);
561 #endif
562     print_vmcs_field(VMCS_GUEST_SYSENTER_CS);
563     print_vmcs_field(VMCS_GUEST_SYSENTER_ESP);
564     print_vmcs_field(VMCS_GUEST_SYSENTER_EIP);
565
566
567     // if save IA32_PAT
568     print_vmcs_field(VMCS_GUEST_PAT);
569 #ifdef __V3_32BIT__
570     print_vmcs_field(VMCS_GUEST_PAT_HIGH);
571 #endif
572
573     //if load  IA32_PERF_GLOBAL_CTRL
574     print_vmcs_field(VMCS_GUEST_PERF_GLOBAL_CTRL);
575 #ifdef __V3_32BIT__
576     print_vmcs_field(VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH);
577 #endif
578
579     print_vmcs_field(VMCS_GUEST_SMBASE);
580
581
582
583
584     PrintDebug("GUEST_NON_REGISTER_STATE\n");
585
586     print_vmcs_field(VMCS_GUEST_ACTIVITY_STATE);
587     print_vmcs_field(VMCS_GUEST_INT_STATE);
588     print_vmcs_field(VMCS_GUEST_PENDING_DBG_EXCP);
589
590     // if VMX preempt timer
591     print_vmcs_field(VMCS_PREEMPT_TIMER);
592
593 }
594        
595 static void print_host_state()
596 {
597     PrintDebug("VMCS_HOST_STATE\n");
598
599     print_vmcs_field(VMCS_HOST_RIP);
600     print_vmcs_field(VMCS_HOST_RSP);
601     print_vmcs_field(VMCS_HOST_CR0);
602     print_vmcs_field(VMCS_HOST_CR3);
603     print_vmcs_field(VMCS_HOST_CR4);
604     
605
606
607     // if load IA32_EFER
608     print_vmcs_field(VMCS_HOST_EFER);
609 #ifdef __V3_32BIT__
610     print_vmcs_field(VMCS_HOST_EFER_HIGH);
611 #endif
612
613
614     PrintDebug("\n");
615     print_vmcs_field(VMCS_HOST_CS_SELECTOR);
616     print_vmcs_field(VMCS_HOST_SS_SELECTOR);
617     print_vmcs_field(VMCS_HOST_DS_SELECTOR);
618     print_vmcs_field(VMCS_HOST_ES_SELECTOR);
619     print_vmcs_field(VMCS_HOST_FS_SELECTOR);
620     print_vmcs_field(VMCS_HOST_GS_SELECTOR);
621     print_vmcs_field(VMCS_HOST_TR_SELECTOR);
622
623     PrintDebug("\n");
624     print_vmcs_field(VMCS_HOST_FS_BASE);
625     print_vmcs_field(VMCS_HOST_GS_BASE);
626     print_vmcs_field(VMCS_HOST_TR_BASE);
627     print_vmcs_field(VMCS_HOST_GDTR_BASE);
628     print_vmcs_field(VMCS_HOST_IDTR_BASE);
629
630     PrintDebug("\n");
631     print_vmcs_field(VMCS_HOST_SYSENTER_CS);
632     print_vmcs_field(VMCS_HOST_SYSENTER_ESP);
633     print_vmcs_field(VMCS_HOST_SYSENTER_EIP);
634
635
636     // if load IA32_PAT
637     print_vmcs_field(VMCS_HOST_PAT);
638 #ifdef __V3_32BIT__
639     print_vmcs_field(VMCS_HOST_PAT_HIGH);
640 #endif
641
642     // if load IA32_PERF_GLOBAL_CTRL
643     print_vmcs_field(VMCS_HOST_PERF_GLOBAL_CTRL);
644 #ifdef __V3_32BIT__
645     print_vmcs_field(VMCS_HOST_PERF_GLOBAL_CTRL_HIGH);
646 #endif
647 }
648
649
650 static void print_exec_ctrls() {
651     PrintDebug("VMCS_EXEC_CTRL_FIELDS\n");
652     print_vmcs_field(VMCS_PIN_CTRLS);
653     print_vmcs_field(VMCS_PROC_CTRLS);
654     
655     // if activate secondary controls
656     print_vmcs_field(VMCS_SEC_PROC_CTRLS);
657     
658     print_vmcs_field(VMCS_EXCP_BITMAP);
659     print_vmcs_field(VMCS_PG_FAULT_ERR_MASK);
660     print_vmcs_field(VMCS_PG_FAULT_ERR_MATCH);
661
662     print_vmcs_field(VMCS_IO_BITMAP_A_ADDR);
663 #ifdef __V3_32BIT__
664     print_vmcs_field(VMCS_IO_BITMAP_A_ADDR_HIGH);
665 #endif
666
667     print_vmcs_field(VMCS_IO_BITMAP_B_ADDR);
668 #ifdef __V3_32BIT__
669     print_vmcs_field(VMCS_IO_BITMAP_B_ADDR_HIGH);
670 #endif
671
672     print_vmcs_field(VMCS_TSC_OFFSET);
673 #ifdef __V3_32BIT__
674     print_vmcs_field(VMCS_TSC_OFFSET_HIGH);
675 #endif
676
677     PrintDebug("\n");
678
679     print_vmcs_field(VMCS_CR0_MASK);
680     print_vmcs_field(VMCS_CR0_READ_SHDW);
681     print_vmcs_field(VMCS_CR4_MASK);
682     print_vmcs_field(VMCS_CR4_READ_SHDW);
683
684     print_vmcs_field(VMCS_CR3_TGT_CNT);
685     print_vmcs_field(VMCS_CR3_TGT_VAL_0);
686     print_vmcs_field(VMCS_CR3_TGT_VAL_1);
687     print_vmcs_field(VMCS_CR3_TGT_VAL_2);
688     print_vmcs_field(VMCS_CR3_TGT_VAL_3);
689
690     // Check max number of CR3 targets... may continue...
691
692
693     PrintDebug("\n");
694
695     // if virtualize apic accesses
696     print_vmcs_field(VMCS_APIC_ACCESS_ADDR);    
697 #ifdef __V3_32BIT__
698     print_vmcs_field(VMCS_APIC_ACCESS_ADDR_HIGH);
699 #endif
700
701     // if use tpr shadow
702     print_vmcs_field(VMCS_VAPIC_ADDR);    
703 #ifdef __V3_32BIT__
704     print_vmcs_field(VMCS_VAPIC_ADDR_HIGH);
705 #endif
706
707     // if use tpr shadow
708     print_vmcs_field(VMCS_TPR_THRESHOLD);
709
710
711     // if use MSR bitmaps
712     print_vmcs_field(VMCS_MSR_BITMAP);
713 #ifdef __V3_32BIT__
714     print_vmcs_field(VMCS_MSR_BITMAP_HIGH);
715 #endif
716
717     print_vmcs_field(VMCS_EXEC_PTR);
718 #ifdef __V3_32BIT__
719     print_vmcs_field(VMCS_EXEC_PTR_HIGH);
720 #endif
721
722
723 }
724
725 static void print_ept_state() {
726     V3_Print("VMCS EPT INFO\n");
727
728     // if enable vpid
729     print_vmcs_field(VMCS_VPID);
730
731     print_vmcs_field(VMCS_EPT_PTR);
732 #ifdef __V3_32BIT__
733     print_vmcs_field(VMCS_EPT_PTR_HIGH);
734 #endif
735
736     print_vmcs_field(VMCS_GUEST_PHYS_ADDR);
737 #ifdef __V3_32BIT__
738     print_vmcs_field(VMCS_GUEST_PHYS_ADDR_HIGH);
739 #endif
740
741
742
743     print_vmcs_field(VMCS_GUEST_PDPTE0);
744 #ifdef __V3_32BIT__
745     print_vmcs_field(VMCS_GUEST_PDPTE0_HIGH);
746 #endif
747
748     print_vmcs_field(VMCS_GUEST_PDPTE1);
749 #ifdef __V3_32BIT__
750     print_vmcs_field(VMCS_GUEST_PDPTE1_HIGH);
751 #endif
752
753     print_vmcs_field(VMCS_GUEST_PDPTE2);
754 #ifdef __V3_32BIT__
755     print_vmcs_field(VMCS_GUEST_PDPTE2_HIGH);
756 #endif
757
758     print_vmcs_field(VMCS_GUEST_PDPTE3);
759 #ifdef __V3_32BIT__
760     print_vmcs_field(VMCS_GUEST_PDPTE3_HIGH);
761 #endif
762
763
764
765 }
766
767
768 static void print_exit_ctrls() {
769     PrintDebug("VMCS_EXIT_CTRLS\n");
770
771     print_vmcs_field(VMCS_EXIT_CTRLS);
772
773
774     print_vmcs_field(VMCS_EXIT_MSR_STORE_CNT);
775     print_vmcs_field(VMCS_EXIT_MSR_STORE_ADDR);
776 #ifdef __V3_32BIT__
777     print_vmcs_field(VMCS_EXIT_MSR_STORE_ADDR_HIGH);
778 #endif
779
780     print_vmcs_field(VMCS_EXIT_MSR_LOAD_CNT);
781     print_vmcs_field(VMCS_EXIT_MSR_LOAD_ADDR);
782 #ifdef __V3_32BIT__
783     print_vmcs_field(VMCS_EXIT_MSR_LOAD_ADDR_HIGH);
784 #endif
785
786
787     // if pause loop exiting
788     print_vmcs_field(VMCS_PLE_GAP);
789     print_vmcs_field(VMCS_PLE_WINDOW);
790
791 }
792
793
794 static void print_entry_ctrls() {
795     PrintDebug("VMCS_ENTRY_CTRLS\n");
796     
797     print_vmcs_field(VMCS_ENTRY_CTRLS);
798
799     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_CNT);
800     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_ADDR);
801 #ifdef __V3_32BIT__
802     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_ADDR_HIGH);
803 #endif
804
805     print_vmcs_field(VMCS_ENTRY_INT_INFO);
806     print_vmcs_field(VMCS_ENTRY_EXCP_ERR);
807     print_vmcs_field(VMCS_ENTRY_INSTR_LEN);
808
809
810 }
811
812
813 static void print_exit_info() {
814     PrintDebug("VMCS_EXIT_INFO\n");
815
816     print_vmcs_field(VMCS_EXIT_REASON);
817     print_vmcs_field(VMCS_EXIT_QUAL);
818
819     print_vmcs_field(VMCS_EXIT_INT_INFO);
820     print_vmcs_field(VMCS_EXIT_INT_ERR);
821
822     print_vmcs_field(VMCS_IDT_VECTOR_INFO);
823     print_vmcs_field(VMCS_IDT_VECTOR_ERR);
824
825     print_vmcs_field(VMCS_EXIT_INSTR_LEN);
826
827     print_vmcs_field(VMCS_GUEST_LINEAR_ADDR);
828     print_vmcs_field(VMCS_EXIT_INSTR_INFO);
829
830     print_vmcs_field(VMCS_IO_RCX);
831     print_vmcs_field(VMCS_IO_RSI);
832     print_vmcs_field(VMCS_IO_RDI);
833     print_vmcs_field(VMCS_IO_RIP);
834
835
836     print_vmcs_field(VMCS_INSTR_ERR);
837 }
838
839 void v3_print_vmcs() {
840
841     print_vmcs_field(VMCS_LINK_PTR);
842 #ifdef __V3_32BIT__
843     print_vmcs_field(VMCS_LINK_PTR_HIGH);
844 #endif
845
846     print_guest_state();
847     print_host_state();
848
849     print_ept_state();
850
851     print_exec_ctrls();
852     print_exit_ctrls();
853     print_entry_ctrls();
854     print_exit_info();
855
856 }
857
858
859 /*
860  * Returns the field length in bytes
861  *   It doesn't get much uglier than this... Thanks Intel
862  */
863 int v3_vmcs_get_field_len(vmcs_field_t field) {
864     struct vmcs_field_encoding * enc = (struct vmcs_field_encoding *)&field;
865
866     switch (enc->width)  {
867         case 0:
868             return 2;
869         case 1: {
870             if (enc->access_type == 1) {
871                 return 4;
872             } else {
873                 return sizeof(addr_t);
874             }
875         }
876         case 2:
877             return 4;
878         case 3:
879             return sizeof(addr_t);
880         default:
881             PrintError("Invalid VMCS field: 0x%x\n", field);
882             return -1;
883     }
884 }
885
886
887
888
889
890
891
892
893
894
895
896 static const char VMCS_VPID_STR[] = "VPID";
897 static const char VMCS_GUEST_ES_SELECTOR_STR[] = "GUEST_ES_SELECTOR";
898 static const char VMCS_GUEST_CS_SELECTOR_STR[] = "GUEST_CS_SELECTOR";
899 static const char VMCS_GUEST_SS_SELECTOR_STR[] = "GUEST_SS_SELECTOR";
900 static const char VMCS_GUEST_DS_SELECTOR_STR[] = "GUEST_DS_SELECTOR";
901 static const char VMCS_GUEST_FS_SELECTOR_STR[] = "GUEST_FS_SELECTOR";
902 static const char VMCS_GUEST_GS_SELECTOR_STR[] = "GUEST_GS_SELECTOR";
903 static const char VMCS_GUEST_LDTR_SELECTOR_STR[] = "GUEST_LDTR_SELECTOR";
904 static const char VMCS_GUEST_TR_SELECTOR_STR[] = "GUEST_TR_SELECTOR";
905 static const char VMCS_HOST_ES_SELECTOR_STR[] = "HOST_ES_SELECTOR";
906 static const char VMCS_HOST_CS_SELECTOR_STR[] = "HOST_CS_SELECTOR";
907 static const char VMCS_HOST_SS_SELECTOR_STR[] = "HOST_SS_SELECTOR";
908 static const char VMCS_HOST_DS_SELECTOR_STR[] = "HOST_DS_SELECTOR";
909 static const char VMCS_HOST_FS_SELECTOR_STR[] = "HOST_FS_SELECTOR";
910 static const char VMCS_HOST_GS_SELECTOR_STR[] = "HOST_GS_SELECTOR";
911 static const char VMCS_HOST_TR_SELECTOR_STR[] = "HOST_TR_SELECTOR";
912 static const char VMCS_IO_BITMAP_A_ADDR_STR[] = "IO_BITMAP_A_ADDR";
913 static const char VMCS_IO_BITMAP_A_ADDR_HIGH_STR[] = "IO_BITMAP_A_ADDR_HIGH";
914 static const char VMCS_IO_BITMAP_B_ADDR_STR[] = "IO_BITMAP_B_ADDR";
915 static const char VMCS_IO_BITMAP_B_ADDR_HIGH_STR[] = "IO_BITMAP_B_ADDR_HIGH";
916 static const char VMCS_MSR_BITMAP_STR[] = "MSR_BITMAPS";
917 static const char VMCS_MSR_BITMAP_HIGH_STR[] = "MSR_BITMAPS_HIGH";
918 static const char VMCS_EXIT_MSR_STORE_ADDR_STR[] = "EXIT_MSR_STORE_ADDR";
919 static const char VMCS_EXIT_MSR_STORE_ADDR_HIGH_STR[] = "EXIT_MSR_STORE_ADDR_HIGH";
920 static const char VMCS_EXIT_MSR_LOAD_ADDR_STR[] = "EXIT_MSR_LOAD_ADDR";
921 static const char VMCS_EXIT_MSR_LOAD_ADDR_HIGH_STR[] = "EXIT_MSR_LOAD_ADDR_HIGH";
922 static const char VMCS_ENTRY_MSR_LOAD_ADDR_STR[] = "ENTRY_MSR_LOAD_ADDR";
923 static const char VMCS_ENTRY_MSR_LOAD_ADDR_HIGH_STR[] = "ENTRY_MSR_LOAD_ADDR_HIGH";
924 static const char VMCS_EXEC_PTR_STR[] = "VMCS_EXEC_PTR";
925 static const char VMCS_EXEC_PTR_HIGH_STR[] = "VMCS_EXEC_PTR_HIGH";
926 static const char VMCS_TSC_OFFSET_STR[] = "TSC_OFFSET";
927 static const char VMCS_TSC_OFFSET_HIGH_STR[] = "TSC_OFFSET_HIGH";
928 static const char VMCS_VAPIC_ADDR_STR[] = "VAPIC_PAGE_ADDR";
929 static const char VMCS_VAPIC_ADDR_HIGH_STR[] = "VAPIC_PAGE_ADDR_HIGH";
930 static const char VMCS_APIC_ACCESS_ADDR_STR[] = "APIC_ACCESS_ADDR";
931 static const char VMCS_APIC_ACCESS_ADDR_HIGH_STR[] = "APIC_ACCESS_ADDR_HIGH";
932 static const char VMCS_EPT_PTR_STR[] = "VMCS_EPT_PTR";
933 static const char VMCS_EPT_PTR_HIGH_STR[] = "VMCS_EPT_PTR_HIGH";
934 static const char VMCS_GUEST_PHYS_ADDR_STR[] = "VMCS_GUEST_PHYS_ADDR";
935 static const char VMCS_GUEST_PHYS_ADDR_HIGH_STR[] = "VMCS_GUEST_PHYS_ADDR_HIGH";
936 static const char VMCS_LINK_PTR_STR[] = "VMCS_LINK_PTR";
937 static const char VMCS_LINK_PTR_HIGH_STR[] = "VMCS_LINK_PTR_HIGH";
938 static const char VMCS_GUEST_DBG_CTL_STR[] = "GUEST_DEBUG_CTL";
939 static const char VMCS_GUEST_DBG_CTL_HIGH_STR[] = "GUEST_DEBUG_CTL_HIGH";
940 static const char VMCS_GUEST_PAT_STR[] = "GUEST_PAT";
941 static const char VMCS_GUEST_PAT_HIGH_STR[] = "GUEST_PAT_HIGH";
942 static const char VMCS_GUEST_EFER_STR[] = "GUEST_EFER";
943 static const char VMCS_GUEST_EFER_HIGH_STR[] = "GUEST_EFER_HIGH";
944 static const char VMCS_GUEST_PERF_GLOBAL_CTRL_STR[] = "GUEST_PERF_GLOBAL_CTRL";
945 static const char VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH_STR[] = "GUEST_PERF_GLOBAL_CTRL_HIGH";
946 static const char VMCS_GUEST_PDPTE0_STR[] = "GUEST_PDPTE0";
947 static const char VMCS_GUEST_PDPTE0_HIGH_STR[] = "GUEST_PDPTE0_HIGH";
948 static const char VMCS_GUEST_PDPTE1_STR[] = "GUEST_PDPTE1";
949 static const char VMCS_GUEST_PDPTE1_HIGH_STR[] = "GUEST_PDPTE1_HIGH";
950 static const char VMCS_GUEST_PDPTE2_STR[] = "GUEST_PDPTE2";
951 static const char VMCS_GUEST_PDPTE2_HIGH_STR[] = "GUEST_PDPTE2_HIGH";
952 static const char VMCS_GUEST_PDPTE3_STR[] = "GUEST_PDPTE3";
953 static const char VMCS_GUEST_PDPTE3_HIGH_STR[] = "GUEST_PDPTE3_HIGH";
954 static const char VMCS_HOST_PAT_STR[] = "HOST_PAT";
955 static const char VMCS_HOST_PAT_HIGH_STR[] = "HOST_PAT_HIGH";
956 static const char VMCS_HOST_EFER_STR[] = "VMCS_HOST_EFER";
957 static const char VMCS_HOST_EFER_HIGH_STR[] = "VMCS_HOST_EFER_HIGH";
958 static const char VMCS_HOST_PERF_GLOBAL_CTRL_STR[] = "HOST_PERF_GLOBAL_CTRL";
959 static const char VMCS_HOST_PERF_GLOBAL_CTRL_HIGH_STR[] = "HOST_PERF_GLOBAL_CTRL_HIGH";
960 static const char VMCS_PIN_CTRLS_STR[] = "PIN_VM_EXEC_CTRLS";
961 static const char VMCS_PROC_CTRLS_STR[] = "PROC_VM_EXEC_CTRLS";
962 static const char VMCS_EXCP_BITMAP_STR[] = "EXCEPTION_BITMAP";
963 static const char VMCS_PG_FAULT_ERR_MASK_STR[] = "PAGE_FAULT_ERROR_MASK";
964 static const char VMCS_PG_FAULT_ERR_MATCH_STR[] = "PAGE_FAULT_ERROR_MATCH";
965 static const char VMCS_CR3_TGT_CNT_STR[] = "CR3_TARGET_COUNT";
966 static const char VMCS_EXIT_CTRLS_STR[] = "VM_EXIT_CTRLS";
967 static const char VMCS_EXIT_MSR_STORE_CNT_STR[] = "VM_EXIT_MSR_STORE_COUNT";
968 static const char VMCS_EXIT_MSR_LOAD_CNT_STR[] = "VM_EXIT_MSR_LOAD_COUNT";
969 static const char VMCS_ENTRY_CTRLS_STR[] = "VM_ENTRY_CTRLS";
970 static const char VMCS_ENTRY_MSR_LOAD_CNT_STR[] = "VM_ENTRY_MSR_LOAD_COUNT";
971 static const char VMCS_ENTRY_INT_INFO_STR[] = "VM_ENTRY_INT_INFO_FIELD";
972 static const char VMCS_ENTRY_EXCP_ERR_STR[] = "VM_ENTRY_EXCEPTION_ERROR";
973 static const char VMCS_ENTRY_INSTR_LEN_STR[] = "VM_ENTRY_INSTR_LENGTH";
974 static const char VMCS_TPR_THRESHOLD_STR[] = "TPR_THRESHOLD";
975 static const char VMCS_SEC_PROC_CTRLS_STR[] = "VMCS_SEC_PROC_CTRLS";
976 static const char VMCS_PLE_GAP_STR[] = "PLE_GAP";
977 static const char VMCS_PLE_WINDOW_STR[] = "PLE_WINDOW";
978 static const char VMCS_INSTR_ERR_STR[] = "VM_INSTR_ERROR";
979 static const char VMCS_EXIT_REASON_STR[] = "EXIT_REASON";
980 static const char VMCS_EXIT_INT_INFO_STR[] = "VM_EXIT_INT_INFO";
981 static const char VMCS_EXIT_INT_ERR_STR[] = "VM_EXIT_INT_ERROR";
982 static const char VMCS_IDT_VECTOR_INFO_STR[] = "IDT_VECTOR_INFO";
983 static const char VMCS_IDT_VECTOR_ERR_STR[] = "IDT_VECTOR_ERROR";
984 static const char VMCS_EXIT_INSTR_LEN_STR[] = "VM_EXIT_INSTR_LENGTH";
985 static const char VMCS_EXIT_INSTR_INFO_STR[] = "VMX_INSTR_INFO";
986 static const char VMCS_GUEST_ES_LIMIT_STR[] = "GUEST_ES_LIMIT";
987 static const char VMCS_GUEST_CS_LIMIT_STR[] = "GUEST_CS_LIMIT";
988 static const char VMCS_GUEST_SS_LIMIT_STR[] = "GUEST_SS_LIMIT";
989 static const char VMCS_GUEST_DS_LIMIT_STR[] = "GUEST_DS_LIMIT";
990 static const char VMCS_GUEST_FS_LIMIT_STR[] = "GUEST_FS_LIMIT";
991 static const char VMCS_GUEST_GS_LIMIT_STR[] = "GUEST_GS_LIMIT";
992 static const char VMCS_GUEST_LDTR_LIMIT_STR[] = "GUEST_LDTR_LIMIT";
993 static const char VMCS_GUEST_TR_LIMIT_STR[] = "GUEST_TR_LIMIT";
994 static const char VMCS_GUEST_GDTR_LIMIT_STR[] = "GUEST_GDTR_LIMIT";
995 static const char VMCS_GUEST_IDTR_LIMIT_STR[] = "GUEST_IDTR_LIMIT";
996 static const char VMCS_GUEST_ES_ACCESS_STR[] = "GUEST_ES_ACCESS";
997 static const char VMCS_GUEST_CS_ACCESS_STR[] = "GUEST_CS_ACCESS";
998 static const char VMCS_GUEST_SS_ACCESS_STR[] = "GUEST_SS_ACCESS";
999 static const char VMCS_GUEST_DS_ACCESS_STR[] = "GUEST_DS_ACCESS";
1000 static const char VMCS_GUEST_FS_ACCESS_STR[] = "GUEST_FS_ACCESS";
1001 static const char VMCS_GUEST_GS_ACCESS_STR[] = "GUEST_GS_ACCESS";
1002 static const char VMCS_GUEST_LDTR_ACCESS_STR[] = "GUEST_LDTR_ACCESS";
1003 static const char VMCS_GUEST_TR_ACCESS_STR[] = "GUEST_TR_ACCESS";
1004 static const char VMCS_GUEST_INT_STATE_STR[] = "GUEST_INT_STATE";
1005 static const char VMCS_GUEST_ACTIVITY_STATE_STR[] = "GUEST_ACTIVITY_STATE";
1006 static const char VMCS_GUEST_SMBASE_STR[] = "GUEST_SMBASE";
1007 static const char VMCS_GUEST_SYSENTER_CS_STR[] = "GUEST_SYSENTER_CS";
1008 static const char VMCS_PREEMPT_TIMER_STR[] = "PREEMPT_TIMER";
1009 static const char VMCS_HOST_SYSENTER_CS_STR[] = "HOST_SYSENTER_CS";
1010 static const char VMCS_CR0_MASK_STR[] = "CR0_GUEST_HOST_MASK";
1011 static const char VMCS_CR4_MASK_STR[] = "CR4_GUEST_HOST_MASK";
1012 static const char VMCS_CR0_READ_SHDW_STR[] = "CR0_READ_SHADOW";
1013 static const char VMCS_CR4_READ_SHDW_STR[] = "CR4_READ_SHADOW";
1014 static const char VMCS_CR3_TGT_VAL_0_STR[] = "CR3_TARGET_VALUE_0";
1015 static const char VMCS_CR3_TGT_VAL_1_STR[] = "CR3_TARGET_VALUE_1";
1016 static const char VMCS_CR3_TGT_VAL_2_STR[] = "CR3_TARGET_VALUE_2";
1017 static const char VMCS_CR3_TGT_VAL_3_STR[] = "CR3_TARGET_VALUE_3";
1018 static const char VMCS_EXIT_QUAL_STR[] = "EXIT_QUALIFICATION";
1019 static const char VMCS_IO_RCX_STR[] = "IO_RCX";
1020 static const char VMCS_IO_RSI_STR[] = "IO_RSI";
1021 static const char VMCS_IO_RDI_STR[] = "IO_RDI";
1022 static const char VMCS_IO_RIP_STR[] = "IO_RIP";
1023 static const char VMCS_GUEST_LINEAR_ADDR_STR[] = "GUEST_LINEAR_ADDR";
1024 static const char VMCS_GUEST_CR0_STR[] = "GUEST_CR0";
1025 static const char VMCS_GUEST_CR3_STR[] = "GUEST_CR3";
1026 static const char VMCS_GUEST_CR4_STR[] = "GUEST_CR4";
1027 static const char VMCS_GUEST_ES_BASE_STR[] = "GUEST_ES_BASE";
1028 static const char VMCS_GUEST_CS_BASE_STR[] = "GUEST_CS_BASE";
1029 static const char VMCS_GUEST_SS_BASE_STR[] = "GUEST_SS_BASE";
1030 static const char VMCS_GUEST_DS_BASE_STR[] = "GUEST_DS_BASE";
1031 static const char VMCS_GUEST_FS_BASE_STR[] = "GUEST_FS_BASE";
1032 static const char VMCS_GUEST_GS_BASE_STR[] = "GUEST_GS_BASE";
1033 static const char VMCS_GUEST_LDTR_BASE_STR[] = "GUEST_LDTR_BASE";
1034 static const char VMCS_GUEST_TR_BASE_STR[] = "GUEST_TR_BASE";
1035 static const char VMCS_GUEST_GDTR_BASE_STR[] = "GUEST_GDTR_BASE";
1036 static const char VMCS_GUEST_IDTR_BASE_STR[] = "GUEST_IDTR_BASE";
1037 static const char VMCS_GUEST_DR7_STR[] = "GUEST_DR7";
1038 static const char VMCS_GUEST_RSP_STR[] = "GUEST_RSP";
1039 static const char VMCS_GUEST_RIP_STR[] = "GUEST_RIP";
1040 static const char VMCS_GUEST_RFLAGS_STR[] = "GUEST_RFLAGS";
1041 static const char VMCS_GUEST_PENDING_DBG_EXCP_STR[] = "GUEST_PENDING_DEBUG_EXCS";
1042 static const char VMCS_GUEST_SYSENTER_ESP_STR[] = "GUEST_SYSENTER_ESP";
1043 static const char VMCS_GUEST_SYSENTER_EIP_STR[] = "GUEST_SYSENTER_EIP";
1044 static const char VMCS_HOST_CR0_STR[] = "HOST_CR0";
1045 static const char VMCS_HOST_CR3_STR[] = "HOST_CR3";
1046 static const char VMCS_HOST_CR4_STR[] = "HOST_CR4";
1047 static const char VMCS_HOST_FS_BASE_STR[] = "HOST_FS_BASE";
1048 static const char VMCS_HOST_GS_BASE_STR[] = "HOST_GS_BASE";
1049 static const char VMCS_HOST_TR_BASE_STR[] = "HOST_TR_BASE";
1050 static const char VMCS_HOST_GDTR_BASE_STR[] = "HOST_GDTR_BASE";
1051 static const char VMCS_HOST_IDTR_BASE_STR[] = "HOST_IDTR_BASE";
1052 static const char VMCS_HOST_SYSENTER_ESP_STR[] = "HOST_SYSENTER_ESP";
1053 static const char VMCS_HOST_SYSENTER_EIP_STR[] = "HOST_SYSENTER_EIP";
1054 static const char VMCS_HOST_RSP_STR[] = "HOST_RSP";
1055 static const char VMCS_HOST_RIP_STR[] = "HOST_RIP";
1056
1057
1058
1059 const char * v3_vmcs_field_to_str(vmcs_field_t field) {   
1060     switch (field) {
1061         case VMCS_VPID:
1062             return VMCS_VPID_STR;
1063         case VMCS_GUEST_ES_SELECTOR:
1064             return VMCS_GUEST_ES_SELECTOR_STR;
1065         case VMCS_GUEST_CS_SELECTOR:
1066             return VMCS_GUEST_CS_SELECTOR_STR;
1067         case VMCS_GUEST_SS_SELECTOR:
1068             return VMCS_GUEST_SS_SELECTOR_STR;
1069         case VMCS_GUEST_DS_SELECTOR:
1070             return VMCS_GUEST_DS_SELECTOR_STR;
1071         case VMCS_GUEST_FS_SELECTOR:
1072             return VMCS_GUEST_FS_SELECTOR_STR;
1073         case VMCS_GUEST_GS_SELECTOR:
1074             return VMCS_GUEST_GS_SELECTOR_STR;
1075         case VMCS_GUEST_LDTR_SELECTOR:
1076             return VMCS_GUEST_LDTR_SELECTOR_STR;
1077         case VMCS_GUEST_TR_SELECTOR:
1078             return VMCS_GUEST_TR_SELECTOR_STR;
1079         case VMCS_HOST_ES_SELECTOR:
1080             return VMCS_HOST_ES_SELECTOR_STR;
1081         case VMCS_HOST_CS_SELECTOR:
1082             return VMCS_HOST_CS_SELECTOR_STR;
1083         case VMCS_HOST_SS_SELECTOR:
1084             return VMCS_HOST_SS_SELECTOR_STR;
1085         case VMCS_HOST_DS_SELECTOR:
1086             return VMCS_HOST_DS_SELECTOR_STR;
1087         case VMCS_HOST_FS_SELECTOR:
1088             return VMCS_HOST_FS_SELECTOR_STR;
1089         case VMCS_HOST_GS_SELECTOR:
1090             return VMCS_HOST_GS_SELECTOR_STR;
1091         case VMCS_HOST_TR_SELECTOR:
1092             return VMCS_HOST_TR_SELECTOR_STR;
1093         case VMCS_IO_BITMAP_A_ADDR:
1094             return VMCS_IO_BITMAP_A_ADDR_STR;
1095         case VMCS_IO_BITMAP_A_ADDR_HIGH:
1096             return VMCS_IO_BITMAP_A_ADDR_HIGH_STR;
1097         case VMCS_IO_BITMAP_B_ADDR:
1098             return VMCS_IO_BITMAP_B_ADDR_STR;
1099         case VMCS_IO_BITMAP_B_ADDR_HIGH:
1100             return VMCS_IO_BITMAP_B_ADDR_HIGH_STR;
1101         case VMCS_MSR_BITMAP:
1102             return VMCS_MSR_BITMAP_STR;
1103         case VMCS_MSR_BITMAP_HIGH:
1104             return VMCS_MSR_BITMAP_HIGH_STR;
1105         case VMCS_EXIT_MSR_STORE_ADDR:
1106             return VMCS_EXIT_MSR_STORE_ADDR_STR;
1107         case VMCS_EXIT_MSR_STORE_ADDR_HIGH:
1108             return VMCS_EXIT_MSR_STORE_ADDR_HIGH_STR;
1109         case VMCS_EXIT_MSR_LOAD_ADDR:
1110             return VMCS_EXIT_MSR_LOAD_ADDR_STR;
1111         case VMCS_EXIT_MSR_LOAD_ADDR_HIGH:
1112             return VMCS_EXIT_MSR_LOAD_ADDR_HIGH_STR;
1113         case VMCS_ENTRY_MSR_LOAD_ADDR:
1114             return VMCS_ENTRY_MSR_LOAD_ADDR_STR;
1115         case VMCS_ENTRY_MSR_LOAD_ADDR_HIGH:
1116             return VMCS_ENTRY_MSR_LOAD_ADDR_HIGH_STR;
1117         case VMCS_EXEC_PTR:
1118             return VMCS_EXEC_PTR_STR;
1119         case VMCS_EXEC_PTR_HIGH:
1120             return VMCS_EXEC_PTR_HIGH_STR;
1121         case VMCS_TSC_OFFSET:
1122             return VMCS_TSC_OFFSET_STR;
1123         case VMCS_TSC_OFFSET_HIGH:
1124             return VMCS_TSC_OFFSET_HIGH_STR;
1125         case VMCS_VAPIC_ADDR:
1126             return VMCS_VAPIC_ADDR_STR;
1127         case VMCS_VAPIC_ADDR_HIGH:
1128             return VMCS_VAPIC_ADDR_HIGH_STR;
1129         case VMCS_APIC_ACCESS_ADDR:
1130             return VMCS_APIC_ACCESS_ADDR_STR;
1131         case VMCS_APIC_ACCESS_ADDR_HIGH:
1132             return VMCS_APIC_ACCESS_ADDR_HIGH_STR;
1133         case VMCS_EPT_PTR:
1134             return VMCS_EPT_PTR_STR;
1135         case VMCS_EPT_PTR_HIGH:
1136             return VMCS_EPT_PTR_HIGH_STR;
1137         case VMCS_GUEST_PHYS_ADDR:
1138             return VMCS_GUEST_PHYS_ADDR_STR;
1139         case VMCS_GUEST_PHYS_ADDR_HIGH:
1140             return VMCS_GUEST_PHYS_ADDR_HIGH_STR;
1141         case VMCS_LINK_PTR:
1142             return VMCS_LINK_PTR_STR;
1143         case VMCS_LINK_PTR_HIGH:
1144             return VMCS_LINK_PTR_HIGH_STR;
1145         case VMCS_GUEST_DBG_CTL:
1146             return VMCS_GUEST_DBG_CTL_STR;
1147         case VMCS_GUEST_DBG_CTL_HIGH:
1148             return VMCS_GUEST_DBG_CTL_HIGH_STR;
1149         case VMCS_GUEST_PAT:
1150             return VMCS_GUEST_PAT_STR;
1151         case VMCS_GUEST_PAT_HIGH:
1152             return VMCS_GUEST_PAT_HIGH_STR;
1153         case VMCS_GUEST_EFER:
1154             return VMCS_GUEST_EFER_STR;
1155         case VMCS_GUEST_EFER_HIGH:
1156             return VMCS_GUEST_EFER_HIGH_STR;
1157         case VMCS_GUEST_PERF_GLOBAL_CTRL:
1158             return VMCS_GUEST_PERF_GLOBAL_CTRL_STR;
1159         case VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH:
1160             return VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH_STR;
1161         case VMCS_GUEST_PDPTE0:
1162             return VMCS_GUEST_PDPTE0_STR;
1163         case VMCS_GUEST_PDPTE0_HIGH:
1164             return VMCS_GUEST_PDPTE0_HIGH_STR;
1165         case VMCS_GUEST_PDPTE1:
1166             return VMCS_GUEST_PDPTE1_STR;
1167         case VMCS_GUEST_PDPTE1_HIGH:
1168             return VMCS_GUEST_PDPTE1_HIGH_STR;
1169         case VMCS_GUEST_PDPTE2:
1170             return VMCS_GUEST_PDPTE2_STR;
1171         case VMCS_GUEST_PDPTE2_HIGH:
1172             return VMCS_GUEST_PDPTE2_HIGH_STR;
1173         case VMCS_GUEST_PDPTE3:
1174             return VMCS_GUEST_PDPTE3_STR;
1175         case VMCS_GUEST_PDPTE3_HIGH:
1176             return VMCS_GUEST_PDPTE3_HIGH_STR;
1177         case VMCS_HOST_PAT:
1178             return VMCS_HOST_PAT_STR;
1179         case VMCS_HOST_PAT_HIGH:
1180             return VMCS_HOST_PAT_HIGH_STR;
1181         case VMCS_HOST_EFER:
1182             return VMCS_HOST_EFER_STR;
1183         case VMCS_HOST_EFER_HIGH:
1184             return VMCS_HOST_EFER_HIGH_STR;
1185         case VMCS_HOST_PERF_GLOBAL_CTRL:
1186             return VMCS_HOST_PERF_GLOBAL_CTRL_STR;
1187         case VMCS_HOST_PERF_GLOBAL_CTRL_HIGH:
1188             return VMCS_HOST_PERF_GLOBAL_CTRL_HIGH_STR;
1189         case VMCS_PIN_CTRLS:
1190             return VMCS_PIN_CTRLS_STR;
1191         case VMCS_PROC_CTRLS:
1192             return VMCS_PROC_CTRLS_STR;
1193         case VMCS_EXCP_BITMAP:
1194             return VMCS_EXCP_BITMAP_STR;
1195         case VMCS_PG_FAULT_ERR_MASK:
1196             return VMCS_PG_FAULT_ERR_MASK_STR;
1197         case VMCS_PG_FAULT_ERR_MATCH:
1198             return VMCS_PG_FAULT_ERR_MATCH_STR;
1199         case VMCS_CR3_TGT_CNT:
1200             return VMCS_CR3_TGT_CNT_STR;
1201         case VMCS_EXIT_CTRLS:
1202             return VMCS_EXIT_CTRLS_STR;
1203         case VMCS_EXIT_MSR_STORE_CNT:
1204             return VMCS_EXIT_MSR_STORE_CNT_STR;
1205         case VMCS_EXIT_MSR_LOAD_CNT:
1206             return VMCS_EXIT_MSR_LOAD_CNT_STR;
1207         case VMCS_ENTRY_CTRLS:
1208             return VMCS_ENTRY_CTRLS_STR;
1209         case VMCS_ENTRY_MSR_LOAD_CNT:
1210             return VMCS_ENTRY_MSR_LOAD_CNT_STR;
1211         case VMCS_ENTRY_INT_INFO:
1212             return VMCS_ENTRY_INT_INFO_STR;
1213         case VMCS_ENTRY_EXCP_ERR:
1214             return VMCS_ENTRY_EXCP_ERR_STR;
1215         case VMCS_ENTRY_INSTR_LEN:
1216             return VMCS_ENTRY_INSTR_LEN_STR;
1217         case VMCS_TPR_THRESHOLD:
1218             return VMCS_TPR_THRESHOLD_STR;
1219         case VMCS_SEC_PROC_CTRLS:
1220             return VMCS_SEC_PROC_CTRLS_STR;
1221         case VMCS_PLE_GAP:
1222             return VMCS_PLE_GAP_STR;
1223         case VMCS_PLE_WINDOW:
1224             return VMCS_PLE_WINDOW_STR;
1225         case VMCS_INSTR_ERR:
1226             return VMCS_INSTR_ERR_STR;
1227         case VMCS_EXIT_REASON:
1228             return VMCS_EXIT_REASON_STR;
1229         case VMCS_EXIT_INT_INFO:
1230             return VMCS_EXIT_INT_INFO_STR;
1231         case VMCS_EXIT_INT_ERR:
1232             return VMCS_EXIT_INT_ERR_STR;
1233         case VMCS_IDT_VECTOR_INFO:
1234             return VMCS_IDT_VECTOR_INFO_STR;
1235         case VMCS_IDT_VECTOR_ERR:
1236             return VMCS_IDT_VECTOR_ERR_STR;
1237         case VMCS_EXIT_INSTR_LEN:
1238             return VMCS_EXIT_INSTR_LEN_STR;
1239         case VMCS_EXIT_INSTR_INFO:
1240             return VMCS_EXIT_INSTR_INFO_STR;
1241         case VMCS_GUEST_ES_LIMIT:
1242             return VMCS_GUEST_ES_LIMIT_STR;
1243         case VMCS_GUEST_CS_LIMIT:
1244             return VMCS_GUEST_CS_LIMIT_STR;
1245         case VMCS_GUEST_SS_LIMIT:
1246             return VMCS_GUEST_SS_LIMIT_STR;
1247         case VMCS_GUEST_DS_LIMIT:
1248             return VMCS_GUEST_DS_LIMIT_STR;
1249         case VMCS_GUEST_FS_LIMIT:
1250             return VMCS_GUEST_FS_LIMIT_STR;
1251         case VMCS_GUEST_GS_LIMIT:
1252             return VMCS_GUEST_GS_LIMIT_STR;
1253         case VMCS_GUEST_LDTR_LIMIT:
1254             return VMCS_GUEST_LDTR_LIMIT_STR;
1255         case VMCS_GUEST_TR_LIMIT:
1256             return VMCS_GUEST_TR_LIMIT_STR;
1257         case VMCS_GUEST_GDTR_LIMIT:
1258             return VMCS_GUEST_GDTR_LIMIT_STR;
1259         case VMCS_GUEST_IDTR_LIMIT:
1260             return VMCS_GUEST_IDTR_LIMIT_STR;
1261         case VMCS_GUEST_ES_ACCESS:
1262             return VMCS_GUEST_ES_ACCESS_STR;
1263         case VMCS_GUEST_CS_ACCESS:
1264             return VMCS_GUEST_CS_ACCESS_STR;
1265         case VMCS_GUEST_SS_ACCESS:
1266             return VMCS_GUEST_SS_ACCESS_STR;
1267         case VMCS_GUEST_DS_ACCESS:
1268             return VMCS_GUEST_DS_ACCESS_STR;
1269         case VMCS_GUEST_FS_ACCESS:
1270             return VMCS_GUEST_FS_ACCESS_STR;
1271         case VMCS_GUEST_GS_ACCESS:
1272             return VMCS_GUEST_GS_ACCESS_STR;
1273         case VMCS_GUEST_LDTR_ACCESS:
1274             return VMCS_GUEST_LDTR_ACCESS_STR;
1275         case VMCS_GUEST_TR_ACCESS:
1276             return VMCS_GUEST_TR_ACCESS_STR;
1277         case VMCS_GUEST_INT_STATE:
1278             return VMCS_GUEST_INT_STATE_STR;
1279         case VMCS_GUEST_ACTIVITY_STATE:
1280             return VMCS_GUEST_ACTIVITY_STATE_STR;
1281         case VMCS_GUEST_SMBASE:
1282             return VMCS_GUEST_SMBASE_STR;
1283         case VMCS_GUEST_SYSENTER_CS:
1284             return VMCS_GUEST_SYSENTER_CS_STR;
1285         case VMCS_PREEMPT_TIMER:
1286             return VMCS_PREEMPT_TIMER_STR;
1287         case VMCS_HOST_SYSENTER_CS:         
1288             return VMCS_HOST_SYSENTER_CS_STR;
1289         case VMCS_CR0_MASK:
1290             return VMCS_CR0_MASK_STR;
1291         case VMCS_CR4_MASK:
1292             return VMCS_CR4_MASK_STR;
1293         case VMCS_CR0_READ_SHDW:
1294             return VMCS_CR0_READ_SHDW_STR;
1295         case VMCS_CR4_READ_SHDW:
1296             return VMCS_CR4_READ_SHDW_STR;
1297         case VMCS_CR3_TGT_VAL_0:
1298             return VMCS_CR3_TGT_VAL_0_STR;
1299         case VMCS_CR3_TGT_VAL_1:
1300             return VMCS_CR3_TGT_VAL_1_STR;
1301         case VMCS_CR3_TGT_VAL_2:
1302             return VMCS_CR3_TGT_VAL_2_STR;
1303         case VMCS_CR3_TGT_VAL_3:
1304             return VMCS_CR3_TGT_VAL_3_STR;
1305         case VMCS_EXIT_QUAL:
1306             return VMCS_EXIT_QUAL_STR;
1307         case VMCS_IO_RCX:
1308             return VMCS_IO_RCX_STR;
1309         case VMCS_IO_RSI:
1310             return VMCS_IO_RSI_STR;
1311         case VMCS_IO_RDI:
1312             return VMCS_IO_RDI_STR;
1313         case VMCS_IO_RIP:
1314             return VMCS_IO_RIP_STR;
1315         case VMCS_GUEST_LINEAR_ADDR:
1316             return VMCS_GUEST_LINEAR_ADDR_STR;
1317         case VMCS_GUEST_CR0:
1318             return VMCS_GUEST_CR0_STR;
1319         case VMCS_GUEST_CR3:
1320             return VMCS_GUEST_CR3_STR;
1321         case VMCS_GUEST_CR4:
1322             return VMCS_GUEST_CR4_STR;
1323         case VMCS_GUEST_ES_BASE:
1324             return VMCS_GUEST_ES_BASE_STR;
1325         case VMCS_GUEST_CS_BASE:
1326             return VMCS_GUEST_CS_BASE_STR;
1327         case VMCS_GUEST_SS_BASE:
1328             return VMCS_GUEST_SS_BASE_STR;
1329         case VMCS_GUEST_DS_BASE:
1330             return VMCS_GUEST_DS_BASE_STR;
1331         case VMCS_GUEST_FS_BASE:
1332             return VMCS_GUEST_FS_BASE_STR;
1333         case VMCS_GUEST_GS_BASE:
1334             return VMCS_GUEST_GS_BASE_STR;
1335         case VMCS_GUEST_LDTR_BASE:
1336             return VMCS_GUEST_LDTR_BASE_STR;
1337         case VMCS_GUEST_TR_BASE:
1338             return VMCS_GUEST_TR_BASE_STR;
1339         case VMCS_GUEST_GDTR_BASE:
1340             return VMCS_GUEST_GDTR_BASE_STR;
1341         case VMCS_GUEST_IDTR_BASE:
1342             return VMCS_GUEST_IDTR_BASE_STR;
1343         case VMCS_GUEST_DR7:
1344             return VMCS_GUEST_DR7_STR;
1345         case VMCS_GUEST_RSP:
1346             return VMCS_GUEST_RSP_STR;
1347         case VMCS_GUEST_RIP:
1348             return VMCS_GUEST_RIP_STR;
1349         case VMCS_GUEST_RFLAGS:
1350             return VMCS_GUEST_RFLAGS_STR;
1351         case VMCS_GUEST_PENDING_DBG_EXCP:
1352             return VMCS_GUEST_PENDING_DBG_EXCP_STR;
1353         case VMCS_GUEST_SYSENTER_ESP:
1354             return VMCS_GUEST_SYSENTER_ESP_STR;
1355         case VMCS_GUEST_SYSENTER_EIP:
1356             return VMCS_GUEST_SYSENTER_EIP_STR;
1357         case VMCS_HOST_CR0:
1358             return VMCS_HOST_CR0_STR;
1359         case VMCS_HOST_CR3:
1360             return VMCS_HOST_CR3_STR;
1361         case VMCS_HOST_CR4:
1362             return VMCS_HOST_CR4_STR;
1363         case VMCS_HOST_FS_BASE:
1364             return VMCS_HOST_FS_BASE_STR;
1365         case VMCS_HOST_GS_BASE:
1366             return VMCS_HOST_GS_BASE_STR;
1367         case VMCS_HOST_TR_BASE:
1368             return VMCS_HOST_TR_BASE_STR;
1369         case VMCS_HOST_GDTR_BASE:
1370             return VMCS_HOST_GDTR_BASE_STR;
1371         case VMCS_HOST_IDTR_BASE:
1372             return VMCS_HOST_IDTR_BASE_STR;
1373         case VMCS_HOST_SYSENTER_ESP:
1374             return VMCS_HOST_SYSENTER_ESP_STR;
1375         case VMCS_HOST_SYSENTER_EIP:
1376             return VMCS_HOST_SYSENTER_EIP_STR;
1377         case VMCS_HOST_RSP:
1378             return VMCS_HOST_RSP_STR;
1379         case VMCS_HOST_RIP:
1380             return VMCS_HOST_RIP_STR;
1381         default:
1382             return NULL;
1383     }
1384 }
1385
1386
1387