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.


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