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 printing
[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     // if save IA32_EFER
545     print_vmcs_field(VMCS_GUEST_EFER);
546 #ifdef __V3_32BIT__
547     print_vmcs_field(VMCS_GUEST_EFER_HIGH);
548 #endif
549
550
551     PrintDebug("\n");
552
553     print_vmcs_segments();
554
555     PrintDebug("\n");
556
557     print_vmcs_field(VMCS_GUEST_DBG_CTL);
558 #ifdef __V3_32BIT__
559     print_vmcs_field(VMCS_GUEST_DBG_CTL_HIGH);
560 #endif
561     print_vmcs_field(VMCS_GUEST_SYSENTER_CS);
562     print_vmcs_field(VMCS_GUEST_SYSENTER_ESP);
563     print_vmcs_field(VMCS_GUEST_SYSENTER_EIP);
564
565
566     // if save IA32_PAT
567     print_vmcs_field(VMCS_GUEST_PAT);
568 #ifdef __V3_32BIT__
569     print_vmcs_field(VMCS_GUEST_PAT_HIGH);
570 #endif
571
572     //if load  IA32_PERF_GLOBAL_CTRL
573     print_vmcs_field(VMCS_GUEST_PERF_GLOBAL_CTRL);
574 #ifdef __V3_32BIT__
575     print_vmcs_field(VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH);
576 #endif
577
578     print_vmcs_field(VMCS_GUEST_SMBASE);
579
580
581
582
583     PrintDebug("GUEST_NON_REGISTER_STATE\n");
584
585     print_vmcs_field(VMCS_GUEST_ACTIVITY_STATE);
586     print_vmcs_field(VMCS_GUEST_INT_STATE);
587     print_vmcs_field(VMCS_GUEST_PENDING_DBG_EXCP);
588
589     // if VMX preempt timer
590     print_vmcs_field(VMCS_PREEMPT_TIMER);
591
592 }
593        
594 static void print_host_state()
595 {
596     PrintDebug("VMCS_HOST_STATE\n");
597
598     print_vmcs_field(VMCS_HOST_RIP);
599     print_vmcs_field(VMCS_HOST_RSP);
600     print_vmcs_field(VMCS_HOST_CR0);
601     print_vmcs_field(VMCS_HOST_CR3);
602     print_vmcs_field(VMCS_HOST_CR4);
603     
604
605
606     // if load IA32_EFER
607     print_vmcs_field(VMCS_HOST_EFER);
608 #ifdef __V3_32BIT__
609     print_vmcs_field(VMCS_HOST_EFER_HIGH);
610 #endif
611
612
613     PrintDebug("\n");
614     print_vmcs_field(VMCS_HOST_CS_SELECTOR);
615     print_vmcs_field(VMCS_HOST_SS_SELECTOR);
616     print_vmcs_field(VMCS_HOST_DS_SELECTOR);
617     print_vmcs_field(VMCS_HOST_ES_SELECTOR);
618     print_vmcs_field(VMCS_HOST_FS_SELECTOR);
619     print_vmcs_field(VMCS_HOST_GS_SELECTOR);
620     print_vmcs_field(VMCS_HOST_TR_SELECTOR);
621
622     PrintDebug("\n");
623     print_vmcs_field(VMCS_HOST_FS_BASE);
624     print_vmcs_field(VMCS_HOST_GS_BASE);
625     print_vmcs_field(VMCS_HOST_TR_BASE);
626     print_vmcs_field(VMCS_HOST_GDTR_BASE);
627     print_vmcs_field(VMCS_HOST_IDTR_BASE);
628
629     PrintDebug("\n");
630     print_vmcs_field(VMCS_HOST_SYSENTER_CS);
631     print_vmcs_field(VMCS_HOST_SYSENTER_ESP);
632     print_vmcs_field(VMCS_HOST_SYSENTER_EIP);
633
634
635     // if load IA32_PAT
636     print_vmcs_field(VMCS_HOST_PAT);
637 #ifdef __V3_32BIT__
638     print_vmcs_field(VMCS_HOST_PAT_HIGH);
639 #endif
640
641     // if load IA32_PERF_GLOBAL_CTRL
642     print_vmcs_field(VMCS_HOST_PERF_GLOBAL_CTRL);
643 #ifdef __V3_32BIT__
644     print_vmcs_field(VMCS_HOST_PERF_GLOBAL_CTRL_HIGH);
645 #endif
646 }
647
648
649 static void print_exec_ctrls() {
650     PrintDebug("VMCS_EXEC_CTRL_FIELDS\n");
651     print_vmcs_field(VMCS_PIN_CTRLS);
652     print_vmcs_field(VMCS_PROC_CTRLS);
653     
654     // if activate secondary controls
655     print_vmcs_field(VMCS_SEC_PROC_CTRLS);
656     
657     print_vmcs_field(VMCS_EXCP_BITMAP);
658     print_vmcs_field(VMCS_PG_FAULT_ERR_MASK);
659     print_vmcs_field(VMCS_PG_FAULT_ERR_MATCH);
660
661     print_vmcs_field(VMCS_IO_BITMAP_A_ADDR);
662 #ifdef __V3_32BIT__
663     print_vmcs_field(VMCS_IO_BITMAP_A_ADDR_HIGH);
664 #endif
665
666     print_vmcs_field(VMCS_IO_BITMAP_B_ADDR);
667 #ifdef __V3_32BIT__
668     print_vmcs_field(VMCS_IO_BITMAP_B_ADDR_HIGH);
669 #endif
670
671     print_vmcs_field(VMCS_TSC_OFFSET);
672 #ifdef __V3_32BIT__
673     print_vmcs_field(VMCS_TSC_OFFSET_HIGH);
674 #endif
675
676     PrintDebug("\n");
677
678     print_vmcs_field(VMCS_CR0_MASK);
679     print_vmcs_field(VMCS_CR0_READ_SHDW);
680     print_vmcs_field(VMCS_CR4_MASK);
681     print_vmcs_field(VMCS_CR4_READ_SHDW);
682
683     print_vmcs_field(VMCS_CR3_TGT_CNT);
684     print_vmcs_field(VMCS_CR3_TGT_VAL_0);
685     print_vmcs_field(VMCS_CR3_TGT_VAL_1);
686     print_vmcs_field(VMCS_CR3_TGT_VAL_2);
687     print_vmcs_field(VMCS_CR3_TGT_VAL_3);
688
689     // Check max number of CR3 targets... may continue...
690
691
692     PrintDebug("\n");
693
694     // if virtualize apic accesses
695     print_vmcs_field(VMCS_APIC_ACCESS_ADDR);    
696 #ifdef __V3_32BIT__
697     print_vmcs_field(VMCS_APIC_ACCESS_ADDR_HIGH);
698 #endif
699
700     // if use tpr shadow
701     print_vmcs_field(VMCS_VAPIC_ADDR);    
702 #ifdef __V3_32BIT__
703     print_vmcs_field(VMCS_VAPIC_ADDR_HIGH);
704 #endif
705
706     // if use tpr shadow
707     print_vmcs_field(VMCS_TPR_THRESHOLD);
708
709
710     // if use MSR bitmaps
711     print_vmcs_field(VMCS_MSR_BITMAP);
712 #ifdef __V3_32BIT__
713     print_vmcs_field(VMCS_MSR_BITMAP_HIGH);
714 #endif
715
716     print_vmcs_field(VMCS_EXEC_PTR);
717 #ifdef __V3_32BIT__
718     print_vmcs_field(VMCS_EXEC_PTR_HIGH);
719 #endif
720
721
722 }
723
724 static void print_ept_state() {
725     V3_Print("VMCS EPT INFO\n");
726
727     // if enable vpid
728     print_vmcs_field(VMCS_VPID);
729
730     print_vmcs_field(VMCS_EPT_PTR);
731 #ifdef __V3_32BIT__
732     print_vmcs_field(VMCS_EPT_PTR_HIGH);
733 #endif
734
735     print_vmcs_field(VMCS_GUEST_PHYS_ADDR);
736 #ifdef __V3_32BIT__
737     print_vmcs_field(VMCS_GUEST_PHYS_ADDR_HIGH);
738 #endif
739
740
741
742     print_vmcs_field(VMCS_GUEST_PDPTE0);
743 #ifdef __V3_32BIT__
744     print_vmcs_field(VMCS_GUEST_PDPTE0_HIGH);
745 #endif
746
747     print_vmcs_field(VMCS_GUEST_PDPTE1);
748 #ifdef __V3_32BIT__
749     print_vmcs_field(VMCS_GUEST_PDPTE1_HIGH);
750 #endif
751
752     print_vmcs_field(VMCS_GUEST_PDPTE2);
753 #ifdef __V3_32BIT__
754     print_vmcs_field(VMCS_GUEST_PDPTE2_HIGH);
755 #endif
756
757     print_vmcs_field(VMCS_GUEST_PDPTE3);
758 #ifdef __V3_32BIT__
759     print_vmcs_field(VMCS_GUEST_PDPTE3_HIGH);
760 #endif
761
762
763
764 }
765
766
767 static void print_exit_ctrls() {
768     PrintDebug("VMCS_EXIT_CTRLS\n");
769
770     print_vmcs_field(VMCS_EXIT_CTRLS);
771
772
773     print_vmcs_field(VMCS_EXIT_MSR_STORE_CNT);
774     print_vmcs_field(VMCS_EXIT_MSR_STORE_ADDR);
775 #ifdef __V3_32BIT__
776     print_vmcs_field(VMCS_EXIT_MSR_STORE_ADDR_HIGH);
777 #endif
778
779     print_vmcs_field(VMCS_EXIT_MSR_LOAD_CNT);
780     print_vmcs_field(VMCS_EXIT_MSR_LOAD_ADDR);
781 #ifdef __V3_32BIT__
782     print_vmcs_field(VMCS_EXIT_MSR_LOAD_ADDR_HIGH);
783 #endif
784
785
786     // if pause loop exiting
787     print_vmcs_field(VMCS_PLE_GAP);
788     print_vmcs_field(VMCS_PLE_WINDOW);
789
790 }
791
792
793 static void print_entry_ctrls() {
794     PrintDebug("VMCS_ENTRY_CTRLS\n");
795     
796     print_vmcs_field(VMCS_ENTRY_CTRLS);
797
798     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_CNT);
799     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_ADDR);
800 #ifdef __V3_32BIT__
801     print_vmcs_field(VMCS_ENTRY_MSR_LOAD_ADDR_HIGH);
802 #endif
803
804     print_vmcs_field(VMCS_ENTRY_INT_INFO);
805     print_vmcs_field(VMCS_ENTRY_EXCP_ERR);
806     print_vmcs_field(VMCS_ENTRY_INSTR_LEN);
807
808
809 }
810
811
812 static void print_exit_info() {
813     PrintDebug("VMCS_EXIT_INFO\n");
814
815     print_vmcs_field(VMCS_EXIT_REASON);
816     print_vmcs_field(VMCS_EXIT_QUAL);
817
818     print_vmcs_field(VMCS_EXIT_INT_INFO);
819     print_vmcs_field(VMCS_EXIT_INT_ERR);
820
821     print_vmcs_field(VMCS_IDT_VECTOR_INFO);
822     print_vmcs_field(VMCS_IDT_VECTOR_ERR);
823
824     print_vmcs_field(VMCS_EXIT_INSTR_LEN);
825
826     print_vmcs_field(VMCS_GUEST_LINEAR_ADDR);
827     print_vmcs_field(VMCS_EXIT_INSTR_INFO);
828
829     print_vmcs_field(VMCS_IO_RCX);
830     print_vmcs_field(VMCS_IO_RSI);
831     print_vmcs_field(VMCS_IO_RDI);
832     print_vmcs_field(VMCS_IO_RIP);
833
834
835     print_vmcs_field(VMCS_INSTR_ERR);
836 }
837
838 void v3_print_vmcs() {
839
840     print_vmcs_field(VMCS_LINK_PTR);
841 #ifdef __V3_32BIT__
842     print_vmcs_field(VMCS_LINK_PTR_HIGH);
843 #endif
844
845     print_guest_state();
846     print_host_state();
847
848     print_ept_state();
849
850     print_exec_ctrls();
851     print_exit_ctrls();
852     print_entry_ctrls();
853     print_exit_info();
854
855 }
856
857
858 /*
859  * Returns the field length in bytes
860  *   It doesn't get much uglier than this... Thanks Intel
861  */
862 int v3_vmcs_get_field_len(vmcs_field_t field) {
863     struct vmcs_field_encoding * enc = (struct vmcs_field_encoding *)&field;
864
865     switch (enc->width)  {
866         case 0:
867             return 2;
868         case 1: {
869             if (enc->access_type == 1) {
870                 return 4;
871             } else {
872                 return sizeof(addr_t);
873             }
874         }
875         case 2:
876             return 4;
877         case 3:
878             return sizeof(addr_t);
879         default:
880             PrintError("Invalid VMCS field: 0x%x\n", field);
881             return -1;
882     }
883 }
884
885
886
887
888
889
890
891
892
893
894
895 static const char VMCS_VPID_STR[] = "VPID";
896 static const char VMCS_GUEST_ES_SELECTOR_STR[] = "GUEST_ES_SELECTOR";
897 static const char VMCS_GUEST_CS_SELECTOR_STR[] = "GUEST_CS_SELECTOR";
898 static const char VMCS_GUEST_SS_SELECTOR_STR[] = "GUEST_SS_SELECTOR";
899 static const char VMCS_GUEST_DS_SELECTOR_STR[] = "GUEST_DS_SELECTOR";
900 static const char VMCS_GUEST_FS_SELECTOR_STR[] = "GUEST_FS_SELECTOR";
901 static const char VMCS_GUEST_GS_SELECTOR_STR[] = "GUEST_GS_SELECTOR";
902 static const char VMCS_GUEST_LDTR_SELECTOR_STR[] = "GUEST_LDTR_SELECTOR";
903 static const char VMCS_GUEST_TR_SELECTOR_STR[] = "GUEST_TR_SELECTOR";
904 static const char VMCS_HOST_ES_SELECTOR_STR[] = "HOST_ES_SELECTOR";
905 static const char VMCS_HOST_CS_SELECTOR_STR[] = "HOST_CS_SELECTOR";
906 static const char VMCS_HOST_SS_SELECTOR_STR[] = "HOST_SS_SELECTOR";
907 static const char VMCS_HOST_DS_SELECTOR_STR[] = "HOST_DS_SELECTOR";
908 static const char VMCS_HOST_FS_SELECTOR_STR[] = "HOST_FS_SELECTOR";
909 static const char VMCS_HOST_GS_SELECTOR_STR[] = "HOST_GS_SELECTOR";
910 static const char VMCS_HOST_TR_SELECTOR_STR[] = "HOST_TR_SELECTOR";
911 static const char VMCS_IO_BITMAP_A_ADDR_STR[] = "IO_BITMAP_A_ADDR";
912 static const char VMCS_IO_BITMAP_A_ADDR_HIGH_STR[] = "IO_BITMAP_A_ADDR_HIGH";
913 static const char VMCS_IO_BITMAP_B_ADDR_STR[] = "IO_BITMAP_B_ADDR";
914 static const char VMCS_IO_BITMAP_B_ADDR_HIGH_STR[] = "IO_BITMAP_B_ADDR_HIGH";
915 static const char VMCS_MSR_BITMAP_STR[] = "MSR_BITMAPS";
916 static const char VMCS_MSR_BITMAP_HIGH_STR[] = "MSR_BITMAPS_HIGH";
917 static const char VMCS_EXIT_MSR_STORE_ADDR_STR[] = "EXIT_MSR_STORE_ADDR";
918 static const char VMCS_EXIT_MSR_STORE_ADDR_HIGH_STR[] = "EXIT_MSR_STORE_ADDR_HIGH";
919 static const char VMCS_EXIT_MSR_LOAD_ADDR_STR[] = "EXIT_MSR_LOAD_ADDR";
920 static const char VMCS_EXIT_MSR_LOAD_ADDR_HIGH_STR[] = "EXIT_MSR_LOAD_ADDR_HIGH";
921 static const char VMCS_ENTRY_MSR_LOAD_ADDR_STR[] = "ENTRY_MSR_LOAD_ADDR";
922 static const char VMCS_ENTRY_MSR_LOAD_ADDR_HIGH_STR[] = "ENTRY_MSR_LOAD_ADDR_HIGH";
923 static const char VMCS_EXEC_PTR_STR[] = "VMCS_EXEC_PTR";
924 static const char VMCS_EXEC_PTR_HIGH_STR[] = "VMCS_EXEC_PTR_HIGH";
925 static const char VMCS_TSC_OFFSET_STR[] = "TSC_OFFSET";
926 static const char VMCS_TSC_OFFSET_HIGH_STR[] = "TSC_OFFSET_HIGH";
927 static const char VMCS_VAPIC_ADDR_STR[] = "VAPIC_PAGE_ADDR";
928 static const char VMCS_VAPIC_ADDR_HIGH_STR[] = "VAPIC_PAGE_ADDR_HIGH";
929 static const char VMCS_APIC_ACCESS_ADDR_STR[] = "APIC_ACCESS_ADDR";
930 static const char VMCS_APIC_ACCESS_ADDR_HIGH_STR[] = "APIC_ACCESS_ADDR_HIGH";
931 static const char VMCS_EPT_PTR_STR[] = "VMCS_EPT_PTR";
932 static const char VMCS_EPT_PTR_HIGH_STR[] = "VMCS_EPT_PTR_HIGH";
933 static const char VMCS_GUEST_PHYS_ADDR_STR[] = "VMCS_GUEST_PHYS_ADDR";
934 static const char VMCS_GUEST_PHYS_ADDR_HIGH_STR[] = "VMCS_GUEST_PHYS_ADDR_HIGH";
935 static const char VMCS_LINK_PTR_STR[] = "VMCS_LINK_PTR";
936 static const char VMCS_LINK_PTR_HIGH_STR[] = "VMCS_LINK_PTR_HIGH";
937 static const char VMCS_GUEST_DBG_CTL_STR[] = "GUEST_DEBUG_CTL";
938 static const char VMCS_GUEST_DBG_CTL_HIGH_STR[] = "GUEST_DEBUG_CTL_HIGH";
939 static const char VMCS_GUEST_PAT_STR[] = "GUEST_PAT";
940 static const char VMCS_GUEST_PAT_HIGH_STR[] = "GUEST_PAT_HIGH";
941 static const char VMCS_GUEST_EFER_STR[] = "GUEST_EFER";
942 static const char VMCS_GUEST_EFER_HIGH_STR[] = "GUEST_EFER_HIGH";
943 static const char VMCS_GUEST_PERF_GLOBAL_CTRL_STR[] = "GUEST_PERF_GLOBAL_CTRL";
944 static const char VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH_STR[] = "GUEST_PERF_GLOBAL_CTRL_HIGH";
945 static const char VMCS_GUEST_PDPTE0_STR[] = "GUEST_PDPTE0";
946 static const char VMCS_GUEST_PDPTE0_HIGH_STR[] = "GUEST_PDPTE0_HIGH";
947 static const char VMCS_GUEST_PDPTE1_STR[] = "GUEST_PDPTE1";
948 static const char VMCS_GUEST_PDPTE1_HIGH_STR[] = "GUEST_PDPTE1_HIGH";
949 static const char VMCS_GUEST_PDPTE2_STR[] = "GUEST_PDPTE2";
950 static const char VMCS_GUEST_PDPTE2_HIGH_STR[] = "GUEST_PDPTE2_HIGH";
951 static const char VMCS_GUEST_PDPTE3_STR[] = "GUEST_PDPTE3";
952 static const char VMCS_GUEST_PDPTE3_HIGH_STR[] = "GUEST_PDPTE3_HIGH";
953 static const char VMCS_HOST_PAT_STR[] = "HOST_PAT";
954 static const char VMCS_HOST_PAT_HIGH_STR[] = "HOST_PAT_HIGH";
955 static const char VMCS_HOST_EFER_STR[] = "VMCS_HOST_EFER";
956 static const char VMCS_HOST_EFER_HIGH_STR[] = "VMCS_HOST_EFER_HIGH";
957 static const char VMCS_HOST_PERF_GLOBAL_CTRL_STR[] = "HOST_PERF_GLOBAL_CTRL";
958 static const char VMCS_HOST_PERF_GLOBAL_CTRL_HIGH_STR[] = "HOST_PERF_GLOBAL_CTRL_HIGH";
959 static const char VMCS_PIN_CTRLS_STR[] = "PIN_VM_EXEC_CTRLS";
960 static const char VMCS_PROC_CTRLS_STR[] = "PROC_VM_EXEC_CTRLS";
961 static const char VMCS_EXCP_BITMAP_STR[] = "EXCEPTION_BITMAP";
962 static const char VMCS_PG_FAULT_ERR_MASK_STR[] = "PAGE_FAULT_ERROR_MASK";
963 static const char VMCS_PG_FAULT_ERR_MATCH_STR[] = "PAGE_FAULT_ERROR_MATCH";
964 static const char VMCS_CR3_TGT_CNT_STR[] = "CR3_TARGET_COUNT";
965 static const char VMCS_EXIT_CTRLS_STR[] = "VM_EXIT_CTRLS";
966 static const char VMCS_EXIT_MSR_STORE_CNT_STR[] = "VM_EXIT_MSR_STORE_COUNT";
967 static const char VMCS_EXIT_MSR_LOAD_CNT_STR[] = "VM_EXIT_MSR_LOAD_COUNT";
968 static const char VMCS_ENTRY_CTRLS_STR[] = "VM_ENTRY_CTRLS";
969 static const char VMCS_ENTRY_MSR_LOAD_CNT_STR[] = "VM_ENTRY_MSR_LOAD_COUNT";
970 static const char VMCS_ENTRY_INT_INFO_STR[] = "VM_ENTRY_INT_INFO_FIELD";
971 static const char VMCS_ENTRY_EXCP_ERR_STR[] = "VM_ENTRY_EXCEPTION_ERROR";
972 static const char VMCS_ENTRY_INSTR_LEN_STR[] = "VM_ENTRY_INSTR_LENGTH";
973 static const char VMCS_TPR_THRESHOLD_STR[] = "TPR_THRESHOLD";
974 static const char VMCS_SEC_PROC_CTRLS_STR[] = "VMCS_SEC_PROC_CTRLS";
975 static const char VMCS_PLE_GAP_STR[] = "PLE_GAP";
976 static const char VMCS_PLE_WINDOW_STR[] = "PLE_WINDOW";
977 static const char VMCS_INSTR_ERR_STR[] = "VM_INSTR_ERROR";
978 static const char VMCS_EXIT_REASON_STR[] = "EXIT_REASON";
979 static const char VMCS_EXIT_INT_INFO_STR[] = "VM_EXIT_INT_INFO";
980 static const char VMCS_EXIT_INT_ERR_STR[] = "VM_EXIT_INT_ERROR";
981 static const char VMCS_IDT_VECTOR_INFO_STR[] = "IDT_VECTOR_INFO";
982 static const char VMCS_IDT_VECTOR_ERR_STR[] = "IDT_VECTOR_ERROR";
983 static const char VMCS_EXIT_INSTR_LEN_STR[] = "VM_EXIT_INSTR_LENGTH";
984 static const char VMCS_EXIT_INSTR_INFO_STR[] = "VMX_INSTR_INFO";
985 static const char VMCS_GUEST_ES_LIMIT_STR[] = "GUEST_ES_LIMIT";
986 static const char VMCS_GUEST_CS_LIMIT_STR[] = "GUEST_CS_LIMIT";
987 static const char VMCS_GUEST_SS_LIMIT_STR[] = "GUEST_SS_LIMIT";
988 static const char VMCS_GUEST_DS_LIMIT_STR[] = "GUEST_DS_LIMIT";
989 static const char VMCS_GUEST_FS_LIMIT_STR[] = "GUEST_FS_LIMIT";
990 static const char VMCS_GUEST_GS_LIMIT_STR[] = "GUEST_GS_LIMIT";
991 static const char VMCS_GUEST_LDTR_LIMIT_STR[] = "GUEST_LDTR_LIMIT";
992 static const char VMCS_GUEST_TR_LIMIT_STR[] = "GUEST_TR_LIMIT";
993 static const char VMCS_GUEST_GDTR_LIMIT_STR[] = "GUEST_GDTR_LIMIT";
994 static const char VMCS_GUEST_IDTR_LIMIT_STR[] = "GUEST_IDTR_LIMIT";
995 static const char VMCS_GUEST_ES_ACCESS_STR[] = "GUEST_ES_ACCESS";
996 static const char VMCS_GUEST_CS_ACCESS_STR[] = "GUEST_CS_ACCESS";
997 static const char VMCS_GUEST_SS_ACCESS_STR[] = "GUEST_SS_ACCESS";
998 static const char VMCS_GUEST_DS_ACCESS_STR[] = "GUEST_DS_ACCESS";
999 static const char VMCS_GUEST_FS_ACCESS_STR[] = "GUEST_FS_ACCESS";
1000 static const char VMCS_GUEST_GS_ACCESS_STR[] = "GUEST_GS_ACCESS";
1001 static const char VMCS_GUEST_LDTR_ACCESS_STR[] = "GUEST_LDTR_ACCESS";
1002 static const char VMCS_GUEST_TR_ACCESS_STR[] = "GUEST_TR_ACCESS";
1003 static const char VMCS_GUEST_INT_STATE_STR[] = "GUEST_INT_STATE";
1004 static const char VMCS_GUEST_ACTIVITY_STATE_STR[] = "GUEST_ACTIVITY_STATE";
1005 static const char VMCS_GUEST_SMBASE_STR[] = "GUEST_SMBASE";
1006 static const char VMCS_GUEST_SYSENTER_CS_STR[] = "GUEST_SYSENTER_CS";
1007 static const char VMCS_PREEMPT_TIMER_STR[] = "PREEMPT_TIMER";
1008 static const char VMCS_HOST_SYSENTER_CS_STR[] = "HOST_SYSENTER_CS";
1009 static const char VMCS_CR0_MASK_STR[] = "CR0_GUEST_HOST_MASK";
1010 static const char VMCS_CR4_MASK_STR[] = "CR4_GUEST_HOST_MASK";
1011 static const char VMCS_CR0_READ_SHDW_STR[] = "CR0_READ_SHADOW";
1012 static const char VMCS_CR4_READ_SHDW_STR[] = "CR4_READ_SHADOW";
1013 static const char VMCS_CR3_TGT_VAL_0_STR[] = "CR3_TARGET_VALUE_0";
1014 static const char VMCS_CR3_TGT_VAL_1_STR[] = "CR3_TARGET_VALUE_1";
1015 static const char VMCS_CR3_TGT_VAL_2_STR[] = "CR3_TARGET_VALUE_2";
1016 static const char VMCS_CR3_TGT_VAL_3_STR[] = "CR3_TARGET_VALUE_3";
1017 static const char VMCS_EXIT_QUAL_STR[] = "EXIT_QUALIFICATION";
1018 static const char VMCS_IO_RCX_STR[] = "IO_RCX";
1019 static const char VMCS_IO_RSI_STR[] = "IO_RSI";
1020 static const char VMCS_IO_RDI_STR[] = "IO_RDI";
1021 static const char VMCS_IO_RIP_STR[] = "IO_RIP";
1022 static const char VMCS_GUEST_LINEAR_ADDR_STR[] = "GUEST_LINEAR_ADDR";
1023 static const char VMCS_GUEST_CR0_STR[] = "GUEST_CR0";
1024 static const char VMCS_GUEST_CR3_STR[] = "GUEST_CR3";
1025 static const char VMCS_GUEST_CR4_STR[] = "GUEST_CR4";
1026 static const char VMCS_GUEST_ES_BASE_STR[] = "GUEST_ES_BASE";
1027 static const char VMCS_GUEST_CS_BASE_STR[] = "GUEST_CS_BASE";
1028 static const char VMCS_GUEST_SS_BASE_STR[] = "GUEST_SS_BASE";
1029 static const char VMCS_GUEST_DS_BASE_STR[] = "GUEST_DS_BASE";
1030 static const char VMCS_GUEST_FS_BASE_STR[] = "GUEST_FS_BASE";
1031 static const char VMCS_GUEST_GS_BASE_STR[] = "GUEST_GS_BASE";
1032 static const char VMCS_GUEST_LDTR_BASE_STR[] = "GUEST_LDTR_BASE";
1033 static const char VMCS_GUEST_TR_BASE_STR[] = "GUEST_TR_BASE";
1034 static const char VMCS_GUEST_GDTR_BASE_STR[] = "GUEST_GDTR_BASE";
1035 static const char VMCS_GUEST_IDTR_BASE_STR[] = "GUEST_IDTR_BASE";
1036 static const char VMCS_GUEST_DR7_STR[] = "GUEST_DR7";
1037 static const char VMCS_GUEST_RSP_STR[] = "GUEST_RSP";
1038 static const char VMCS_GUEST_RIP_STR[] = "GUEST_RIP";
1039 static const char VMCS_GUEST_RFLAGS_STR[] = "GUEST_RFLAGS";
1040 static const char VMCS_GUEST_PENDING_DBG_EXCP_STR[] = "GUEST_PENDING_DEBUG_EXCS";
1041 static const char VMCS_GUEST_SYSENTER_ESP_STR[] = "GUEST_SYSENTER_ESP";
1042 static const char VMCS_GUEST_SYSENTER_EIP_STR[] = "GUEST_SYSENTER_EIP";
1043 static const char VMCS_HOST_CR0_STR[] = "HOST_CR0";
1044 static const char VMCS_HOST_CR3_STR[] = "HOST_CR3";
1045 static const char VMCS_HOST_CR4_STR[] = "HOST_CR4";
1046 static const char VMCS_HOST_FS_BASE_STR[] = "HOST_FS_BASE";
1047 static const char VMCS_HOST_GS_BASE_STR[] = "HOST_GS_BASE";
1048 static const char VMCS_HOST_TR_BASE_STR[] = "HOST_TR_BASE";
1049 static const char VMCS_HOST_GDTR_BASE_STR[] = "HOST_GDTR_BASE";
1050 static const char VMCS_HOST_IDTR_BASE_STR[] = "HOST_IDTR_BASE";
1051 static const char VMCS_HOST_SYSENTER_ESP_STR[] = "HOST_SYSENTER_ESP";
1052 static const char VMCS_HOST_SYSENTER_EIP_STR[] = "HOST_SYSENTER_EIP";
1053 static const char VMCS_HOST_RSP_STR[] = "HOST_RSP";
1054 static const char VMCS_HOST_RIP_STR[] = "HOST_RIP";
1055
1056
1057
1058 const char * v3_vmcs_field_to_str(vmcs_field_t field) {   
1059     switch (field) {
1060         case VMCS_VPID:
1061             return VMCS_VPID_STR;
1062         case VMCS_GUEST_ES_SELECTOR:
1063             return VMCS_GUEST_ES_SELECTOR_STR;
1064         case VMCS_GUEST_CS_SELECTOR:
1065             return VMCS_GUEST_CS_SELECTOR_STR;
1066         case VMCS_GUEST_SS_SELECTOR:
1067             return VMCS_GUEST_SS_SELECTOR_STR;
1068         case VMCS_GUEST_DS_SELECTOR:
1069             return VMCS_GUEST_DS_SELECTOR_STR;
1070         case VMCS_GUEST_FS_SELECTOR:
1071             return VMCS_GUEST_FS_SELECTOR_STR;
1072         case VMCS_GUEST_GS_SELECTOR:
1073             return VMCS_GUEST_GS_SELECTOR_STR;
1074         case VMCS_GUEST_LDTR_SELECTOR:
1075             return VMCS_GUEST_LDTR_SELECTOR_STR;
1076         case VMCS_GUEST_TR_SELECTOR:
1077             return VMCS_GUEST_TR_SELECTOR_STR;
1078         case VMCS_HOST_ES_SELECTOR:
1079             return VMCS_HOST_ES_SELECTOR_STR;
1080         case VMCS_HOST_CS_SELECTOR:
1081             return VMCS_HOST_CS_SELECTOR_STR;
1082         case VMCS_HOST_SS_SELECTOR:
1083             return VMCS_HOST_SS_SELECTOR_STR;
1084         case VMCS_HOST_DS_SELECTOR:
1085             return VMCS_HOST_DS_SELECTOR_STR;
1086         case VMCS_HOST_FS_SELECTOR:
1087             return VMCS_HOST_FS_SELECTOR_STR;
1088         case VMCS_HOST_GS_SELECTOR:
1089             return VMCS_HOST_GS_SELECTOR_STR;
1090         case VMCS_HOST_TR_SELECTOR:
1091             return VMCS_HOST_TR_SELECTOR_STR;
1092         case VMCS_IO_BITMAP_A_ADDR:
1093             return VMCS_IO_BITMAP_A_ADDR_STR;
1094         case VMCS_IO_BITMAP_A_ADDR_HIGH:
1095             return VMCS_IO_BITMAP_A_ADDR_HIGH_STR;
1096         case VMCS_IO_BITMAP_B_ADDR:
1097             return VMCS_IO_BITMAP_B_ADDR_STR;
1098         case VMCS_IO_BITMAP_B_ADDR_HIGH:
1099             return VMCS_IO_BITMAP_B_ADDR_HIGH_STR;
1100         case VMCS_MSR_BITMAP:
1101             return VMCS_MSR_BITMAP_STR;
1102         case VMCS_MSR_BITMAP_HIGH:
1103             return VMCS_MSR_BITMAP_HIGH_STR;
1104         case VMCS_EXIT_MSR_STORE_ADDR:
1105             return VMCS_EXIT_MSR_STORE_ADDR_STR;
1106         case VMCS_EXIT_MSR_STORE_ADDR_HIGH:
1107             return VMCS_EXIT_MSR_STORE_ADDR_HIGH_STR;
1108         case VMCS_EXIT_MSR_LOAD_ADDR:
1109             return VMCS_EXIT_MSR_LOAD_ADDR_STR;
1110         case VMCS_EXIT_MSR_LOAD_ADDR_HIGH:
1111             return VMCS_EXIT_MSR_LOAD_ADDR_HIGH_STR;
1112         case VMCS_ENTRY_MSR_LOAD_ADDR:
1113             return VMCS_ENTRY_MSR_LOAD_ADDR_STR;
1114         case VMCS_ENTRY_MSR_LOAD_ADDR_HIGH:
1115             return VMCS_ENTRY_MSR_LOAD_ADDR_HIGH_STR;
1116         case VMCS_EXEC_PTR:
1117             return VMCS_EXEC_PTR_STR;
1118         case VMCS_EXEC_PTR_HIGH:
1119             return VMCS_EXEC_PTR_HIGH_STR;
1120         case VMCS_TSC_OFFSET:
1121             return VMCS_TSC_OFFSET_STR;
1122         case VMCS_TSC_OFFSET_HIGH:
1123             return VMCS_TSC_OFFSET_HIGH_STR;
1124         case VMCS_VAPIC_ADDR:
1125             return VMCS_VAPIC_ADDR_STR;
1126         case VMCS_VAPIC_ADDR_HIGH:
1127             return VMCS_VAPIC_ADDR_HIGH_STR;
1128         case VMCS_APIC_ACCESS_ADDR:
1129             return VMCS_APIC_ACCESS_ADDR_STR;
1130         case VMCS_APIC_ACCESS_ADDR_HIGH:
1131             return VMCS_APIC_ACCESS_ADDR_HIGH_STR;
1132         case VMCS_EPT_PTR:
1133             return VMCS_EPT_PTR_STR;
1134         case VMCS_EPT_PTR_HIGH:
1135             return VMCS_EPT_PTR_HIGH_STR;
1136         case VMCS_GUEST_PHYS_ADDR:
1137             return VMCS_GUEST_PHYS_ADDR_STR;
1138         case VMCS_GUEST_PHYS_ADDR_HIGH:
1139             return VMCS_GUEST_PHYS_ADDR_HIGH_STR;
1140         case VMCS_LINK_PTR:
1141             return VMCS_LINK_PTR_STR;
1142         case VMCS_LINK_PTR_HIGH:
1143             return VMCS_LINK_PTR_HIGH_STR;
1144         case VMCS_GUEST_DBG_CTL:
1145             return VMCS_GUEST_DBG_CTL_STR;
1146         case VMCS_GUEST_DBG_CTL_HIGH:
1147             return VMCS_GUEST_DBG_CTL_HIGH_STR;
1148         case VMCS_GUEST_PAT:
1149             return VMCS_GUEST_PAT_STR;
1150         case VMCS_GUEST_PAT_HIGH:
1151             return VMCS_GUEST_PAT_HIGH_STR;
1152         case VMCS_GUEST_EFER:
1153             return VMCS_GUEST_EFER_STR;
1154         case VMCS_GUEST_EFER_HIGH:
1155             return VMCS_GUEST_EFER_HIGH_STR;
1156         case VMCS_GUEST_PERF_GLOBAL_CTRL:
1157             return VMCS_GUEST_PERF_GLOBAL_CTRL_STR;
1158         case VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH:
1159             return VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH_STR;
1160         case VMCS_GUEST_PDPTE0:
1161             return VMCS_GUEST_PDPTE0_STR;
1162         case VMCS_GUEST_PDPTE0_HIGH:
1163             return VMCS_GUEST_PDPTE0_HIGH_STR;
1164         case VMCS_GUEST_PDPTE1:
1165             return VMCS_GUEST_PDPTE1_STR;
1166         case VMCS_GUEST_PDPTE1_HIGH:
1167             return VMCS_GUEST_PDPTE1_HIGH_STR;
1168         case VMCS_GUEST_PDPTE2:
1169             return VMCS_GUEST_PDPTE2_STR;
1170         case VMCS_GUEST_PDPTE2_HIGH:
1171             return VMCS_GUEST_PDPTE2_HIGH_STR;
1172         case VMCS_GUEST_PDPTE3:
1173             return VMCS_GUEST_PDPTE3_STR;
1174         case VMCS_GUEST_PDPTE3_HIGH:
1175             return VMCS_GUEST_PDPTE3_HIGH_STR;
1176         case VMCS_HOST_PAT:
1177             return VMCS_HOST_PAT_STR;
1178         case VMCS_HOST_PAT_HIGH:
1179             return VMCS_HOST_PAT_HIGH_STR;
1180         case VMCS_HOST_EFER:
1181             return VMCS_HOST_EFER_STR;
1182         case VMCS_HOST_EFER_HIGH:
1183             return VMCS_HOST_EFER_HIGH_STR;
1184         case VMCS_HOST_PERF_GLOBAL_CTRL:
1185             return VMCS_HOST_PERF_GLOBAL_CTRL_STR;
1186         case VMCS_HOST_PERF_GLOBAL_CTRL_HIGH:
1187             return VMCS_HOST_PERF_GLOBAL_CTRL_HIGH_STR;
1188         case VMCS_PIN_CTRLS:
1189             return VMCS_PIN_CTRLS_STR;
1190         case VMCS_PROC_CTRLS:
1191             return VMCS_PROC_CTRLS_STR;
1192         case VMCS_EXCP_BITMAP:
1193             return VMCS_EXCP_BITMAP_STR;
1194         case VMCS_PG_FAULT_ERR_MASK:
1195             return VMCS_PG_FAULT_ERR_MASK_STR;
1196         case VMCS_PG_FAULT_ERR_MATCH:
1197             return VMCS_PG_FAULT_ERR_MATCH_STR;
1198         case VMCS_CR3_TGT_CNT:
1199             return VMCS_CR3_TGT_CNT_STR;
1200         case VMCS_EXIT_CTRLS:
1201             return VMCS_EXIT_CTRLS_STR;
1202         case VMCS_EXIT_MSR_STORE_CNT:
1203             return VMCS_EXIT_MSR_STORE_CNT_STR;
1204         case VMCS_EXIT_MSR_LOAD_CNT:
1205             return VMCS_EXIT_MSR_LOAD_CNT_STR;
1206         case VMCS_ENTRY_CTRLS:
1207             return VMCS_ENTRY_CTRLS_STR;
1208         case VMCS_ENTRY_MSR_LOAD_CNT:
1209             return VMCS_ENTRY_MSR_LOAD_CNT_STR;
1210         case VMCS_ENTRY_INT_INFO:
1211             return VMCS_ENTRY_INT_INFO_STR;
1212         case VMCS_ENTRY_EXCP_ERR:
1213             return VMCS_ENTRY_EXCP_ERR_STR;
1214         case VMCS_ENTRY_INSTR_LEN:
1215             return VMCS_ENTRY_INSTR_LEN_STR;
1216         case VMCS_TPR_THRESHOLD:
1217             return VMCS_TPR_THRESHOLD_STR;
1218         case VMCS_SEC_PROC_CTRLS:
1219             return VMCS_SEC_PROC_CTRLS_STR;
1220         case VMCS_PLE_GAP:
1221             return VMCS_PLE_GAP_STR;
1222         case VMCS_PLE_WINDOW:
1223             return VMCS_PLE_WINDOW_STR;
1224         case VMCS_INSTR_ERR:
1225             return VMCS_INSTR_ERR_STR;
1226         case VMCS_EXIT_REASON:
1227             return VMCS_EXIT_REASON_STR;
1228         case VMCS_EXIT_INT_INFO:
1229             return VMCS_EXIT_INT_INFO_STR;
1230         case VMCS_EXIT_INT_ERR:
1231             return VMCS_EXIT_INT_ERR_STR;
1232         case VMCS_IDT_VECTOR_INFO:
1233             return VMCS_IDT_VECTOR_INFO_STR;
1234         case VMCS_IDT_VECTOR_ERR:
1235             return VMCS_IDT_VECTOR_ERR_STR;
1236         case VMCS_EXIT_INSTR_LEN:
1237             return VMCS_EXIT_INSTR_LEN_STR;
1238         case VMCS_EXIT_INSTR_INFO:
1239             return VMCS_EXIT_INSTR_INFO_STR;
1240         case VMCS_GUEST_ES_LIMIT:
1241             return VMCS_GUEST_ES_LIMIT_STR;
1242         case VMCS_GUEST_CS_LIMIT:
1243             return VMCS_GUEST_CS_LIMIT_STR;
1244         case VMCS_GUEST_SS_LIMIT:
1245             return VMCS_GUEST_SS_LIMIT_STR;
1246         case VMCS_GUEST_DS_LIMIT:
1247             return VMCS_GUEST_DS_LIMIT_STR;
1248         case VMCS_GUEST_FS_LIMIT:
1249             return VMCS_GUEST_FS_LIMIT_STR;
1250         case VMCS_GUEST_GS_LIMIT:
1251             return VMCS_GUEST_GS_LIMIT_STR;
1252         case VMCS_GUEST_LDTR_LIMIT:
1253             return VMCS_GUEST_LDTR_LIMIT_STR;
1254         case VMCS_GUEST_TR_LIMIT:
1255             return VMCS_GUEST_TR_LIMIT_STR;
1256         case VMCS_GUEST_GDTR_LIMIT:
1257             return VMCS_GUEST_GDTR_LIMIT_STR;
1258         case VMCS_GUEST_IDTR_LIMIT:
1259             return VMCS_GUEST_IDTR_LIMIT_STR;
1260         case VMCS_GUEST_ES_ACCESS:
1261             return VMCS_GUEST_ES_ACCESS_STR;
1262         case VMCS_GUEST_CS_ACCESS:
1263             return VMCS_GUEST_CS_ACCESS_STR;
1264         case VMCS_GUEST_SS_ACCESS:
1265             return VMCS_GUEST_SS_ACCESS_STR;
1266         case VMCS_GUEST_DS_ACCESS:
1267             return VMCS_GUEST_DS_ACCESS_STR;
1268         case VMCS_GUEST_FS_ACCESS:
1269             return VMCS_GUEST_FS_ACCESS_STR;
1270         case VMCS_GUEST_GS_ACCESS:
1271             return VMCS_GUEST_GS_ACCESS_STR;
1272         case VMCS_GUEST_LDTR_ACCESS:
1273             return VMCS_GUEST_LDTR_ACCESS_STR;
1274         case VMCS_GUEST_TR_ACCESS:
1275             return VMCS_GUEST_TR_ACCESS_STR;
1276         case VMCS_GUEST_INT_STATE:
1277             return VMCS_GUEST_INT_STATE_STR;
1278         case VMCS_GUEST_ACTIVITY_STATE:
1279             return VMCS_GUEST_ACTIVITY_STATE_STR;
1280         case VMCS_GUEST_SMBASE:
1281             return VMCS_GUEST_SMBASE_STR;
1282         case VMCS_GUEST_SYSENTER_CS:
1283             return VMCS_GUEST_SYSENTER_CS_STR;
1284         case VMCS_PREEMPT_TIMER:
1285             return VMCS_PREEMPT_TIMER_STR;
1286         case VMCS_HOST_SYSENTER_CS:         
1287             return VMCS_HOST_SYSENTER_CS_STR;
1288         case VMCS_CR0_MASK:
1289             return VMCS_CR0_MASK_STR;
1290         case VMCS_CR4_MASK:
1291             return VMCS_CR4_MASK_STR;
1292         case VMCS_CR0_READ_SHDW:
1293             return VMCS_CR0_READ_SHDW_STR;
1294         case VMCS_CR4_READ_SHDW:
1295             return VMCS_CR4_READ_SHDW_STR;
1296         case VMCS_CR3_TGT_VAL_0:
1297             return VMCS_CR3_TGT_VAL_0_STR;
1298         case VMCS_CR3_TGT_VAL_1:
1299             return VMCS_CR3_TGT_VAL_1_STR;
1300         case VMCS_CR3_TGT_VAL_2:
1301             return VMCS_CR3_TGT_VAL_2_STR;
1302         case VMCS_CR3_TGT_VAL_3:
1303             return VMCS_CR3_TGT_VAL_3_STR;
1304         case VMCS_EXIT_QUAL:
1305             return VMCS_EXIT_QUAL_STR;
1306         case VMCS_IO_RCX:
1307             return VMCS_IO_RCX_STR;
1308         case VMCS_IO_RSI:
1309             return VMCS_IO_RSI_STR;
1310         case VMCS_IO_RDI:
1311             return VMCS_IO_RDI_STR;
1312         case VMCS_IO_RIP:
1313             return VMCS_IO_RIP_STR;
1314         case VMCS_GUEST_LINEAR_ADDR:
1315             return VMCS_GUEST_LINEAR_ADDR_STR;
1316         case VMCS_GUEST_CR0:
1317             return VMCS_GUEST_CR0_STR;
1318         case VMCS_GUEST_CR3:
1319             return VMCS_GUEST_CR3_STR;
1320         case VMCS_GUEST_CR4:
1321             return VMCS_GUEST_CR4_STR;
1322         case VMCS_GUEST_ES_BASE:
1323             return VMCS_GUEST_ES_BASE_STR;
1324         case VMCS_GUEST_CS_BASE:
1325             return VMCS_GUEST_CS_BASE_STR;
1326         case VMCS_GUEST_SS_BASE:
1327             return VMCS_GUEST_SS_BASE_STR;
1328         case VMCS_GUEST_DS_BASE:
1329             return VMCS_GUEST_DS_BASE_STR;
1330         case VMCS_GUEST_FS_BASE:
1331             return VMCS_GUEST_FS_BASE_STR;
1332         case VMCS_GUEST_GS_BASE:
1333             return VMCS_GUEST_GS_BASE_STR;
1334         case VMCS_GUEST_LDTR_BASE:
1335             return VMCS_GUEST_LDTR_BASE_STR;
1336         case VMCS_GUEST_TR_BASE:
1337             return VMCS_GUEST_TR_BASE_STR;
1338         case VMCS_GUEST_GDTR_BASE:
1339             return VMCS_GUEST_GDTR_BASE_STR;
1340         case VMCS_GUEST_IDTR_BASE:
1341             return VMCS_GUEST_IDTR_BASE_STR;
1342         case VMCS_GUEST_DR7:
1343             return VMCS_GUEST_DR7_STR;
1344         case VMCS_GUEST_RSP:
1345             return VMCS_GUEST_RSP_STR;
1346         case VMCS_GUEST_RIP:
1347             return VMCS_GUEST_RIP_STR;
1348         case VMCS_GUEST_RFLAGS:
1349             return VMCS_GUEST_RFLAGS_STR;
1350         case VMCS_GUEST_PENDING_DBG_EXCP:
1351             return VMCS_GUEST_PENDING_DBG_EXCP_STR;
1352         case VMCS_GUEST_SYSENTER_ESP:
1353             return VMCS_GUEST_SYSENTER_ESP_STR;
1354         case VMCS_GUEST_SYSENTER_EIP:
1355             return VMCS_GUEST_SYSENTER_EIP_STR;
1356         case VMCS_HOST_CR0:
1357             return VMCS_HOST_CR0_STR;
1358         case VMCS_HOST_CR3:
1359             return VMCS_HOST_CR3_STR;
1360         case VMCS_HOST_CR4:
1361             return VMCS_HOST_CR4_STR;
1362         case VMCS_HOST_FS_BASE:
1363             return VMCS_HOST_FS_BASE_STR;
1364         case VMCS_HOST_GS_BASE:
1365             return VMCS_HOST_GS_BASE_STR;
1366         case VMCS_HOST_TR_BASE:
1367             return VMCS_HOST_TR_BASE_STR;
1368         case VMCS_HOST_GDTR_BASE:
1369             return VMCS_HOST_GDTR_BASE_STR;
1370         case VMCS_HOST_IDTR_BASE:
1371             return VMCS_HOST_IDTR_BASE_STR;
1372         case VMCS_HOST_SYSENTER_ESP:
1373             return VMCS_HOST_SYSENTER_ESP_STR;
1374         case VMCS_HOST_SYSENTER_EIP:
1375             return VMCS_HOST_SYSENTER_EIP_STR;
1376         case VMCS_HOST_RSP:
1377             return VMCS_HOST_RSP_STR;
1378         case VMCS_HOST_RIP:
1379             return VMCS_HOST_RIP_STR;
1380         default:
1381             return NULL;
1382     }
1383 }
1384
1385
1386