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.


working instruction emulation
[palacios.git] / palacios / src / palacios / svm_handler.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
21 #include <palacios/svm_handler.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vm_guest_mem.h>
24 #include <palacios/vmm_decoder.h>
25 #include <palacios/vmm_ctrl_regs.h>
26 #include <palacios/svm_io.h>
27 #include <palacios/svm_halt.h>
28 #include <palacios/svm_pause.h>
29 #include <palacios/svm_wbinvd.h>
30 #include <palacios/vmm_intr.h>
31 #include <palacios/vmm_emulator.h>
32 #include <palacios/svm_msr.h>
33
34
35
36 static const uchar_t * vmexit_code_to_str(uint_t exit_code);
37
38
39 int v3_handle_svm_exit(struct guest_info * info) {
40   vmcb_ctrl_t * guest_ctrl = 0;
41   vmcb_saved_state_t * guest_state = 0;
42   ulong_t exit_code = 0;
43   
44   guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
45   guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
46   
47
48   // Update the high level state 
49   info->rip = guest_state->rip;
50   info->vm_regs.rsp = guest_state->rsp;
51   info->vm_regs.rax = guest_state->rax;
52
53   info->cpl = guest_state->cpl;
54
55
56   info->ctrl_regs.cr0 = guest_state->cr0;
57   info->ctrl_regs.cr2 = guest_state->cr2;
58   info->ctrl_regs.cr3 = guest_state->cr3;
59   info->ctrl_regs.cr4 = guest_state->cr4;
60   info->dbg_regs.dr6 = guest_state->dr6;
61   info->dbg_regs.dr7 = guest_state->dr7;
62   info->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
63   info->ctrl_regs.rflags = guest_state->rflags;
64   info->ctrl_regs.efer = guest_state->efer;
65
66   get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
67   info->cpu_mode = v3_get_cpu_mode(info);
68   info->mem_mode = v3_get_mem_mode(info);
69
70
71   exit_code = guest_ctrl->exit_code;
72  
73
74   // Disable printing io exits due to bochs debug messages
75   //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
76
77
78   //  PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc); 
79   
80   if ((0) && (exit_code < 0x4f)) {
81     uchar_t instr[32];
82     int ret;
83     // Dump out the instr stream
84
85     //PrintDebug("RIP: %x\n", guest_state->rip);
86     PrintDebug("RIP Linear: %p\n", (void *)get_addr_linear(info, info->rip, &(info->segments.cs)));
87
88     // OK, now we will read the instruction
89     // The only difference between PROTECTED and PROTECTED_PG is whether we read
90     // from guest_pa or guest_va
91     if (info->mem_mode == PHYSICAL_MEM) { 
92       // The real rip address is actually a combination of the rip + CS base 
93       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
94     } else { 
95       ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
96     }
97     
98     if (ret != 32) {
99       // I think we should inject a GPF into the guest
100       PrintDebug("Could not read instruction (ret=%d)\n", ret);
101     } else {
102
103       PrintDebug("Instr Stream:\n");
104       PrintTraceMemDump(instr, 32);
105     }
106   }
107
108
109     //  }
110   // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
111
112
113   // PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
114   //PrintDebug("RIP: %x\n", guest_state->rip);
115
116   
117   //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
118
119   switch (exit_code) {
120
121   case VMEXIT_IOIO: 
122     {
123       struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
124       
125       if (io_info->type == 0) {
126         if (io_info->str) {
127           if (v3_handle_svm_io_outs(info) == -1 ) {
128             return -1;
129           }
130         } else {
131           if (v3_handle_svm_io_out(info) == -1) {
132             return -1;
133           }
134         }
135       } else {
136         if (io_info->str) {
137           if (v3_handle_svm_io_ins(info) == -1) {
138             return -1;
139           }
140         } else {
141           if (v3_handle_svm_io_in(info) == -1) {
142             return -1;
143           }
144         }
145       }
146       break;
147     }
148   case VMEXIT_MSR:
149     {
150
151       if (guest_ctrl->exit_info1 == 0) {
152         if (v3_handle_msr_read(info) == -1) {
153           return -1;
154         }
155       } else if (guest_ctrl->exit_info1 == 1) {
156         if (v3_handle_msr_write(info) == -1) {
157           return -1;
158         }
159       } else {
160         PrintError("Invalid MSR Operation\n");
161         return -1;
162       }
163
164       break;
165     }
166   case VMEXIT_CR0_WRITE: 
167     {
168 #ifdef DEBUG_CTRL_REGS
169       PrintDebug("CR0 Write\n");
170 #endif
171       if (v3_handle_cr0_write(info) == -1) {
172         return -1;
173       }
174       break;
175     } 
176   case VMEXIT_CR0_READ: 
177     {
178 #ifdef DEBUG_CTRL_REGS
179       PrintDebug("CR0 Read\n");
180 #endif
181       if (v3_handle_cr0_read(info) == -1) {
182         return -1;
183       }
184       break;
185     } 
186   case VMEXIT_CR3_WRITE: 
187     {
188 #ifdef DEBUG_CTRL_REGS
189       PrintDebug("CR3 Write\n");
190 #endif
191       if (v3_handle_cr3_write(info) == -1) {
192         return -1;
193       }    
194       break;
195     }
196   case  VMEXIT_CR3_READ: 
197     {
198 #ifdef DEBUG_CTRL_REGS
199       PrintDebug("CR3 Read\n");
200 #endif
201       if (v3_handle_cr3_read(info) == -1) {
202         return -1;
203       }
204       break;
205     }
206   case VMEXIT_CR4_WRITE: 
207     {
208 #ifdef DEBUG_CTRL_REGS
209       PrintDebug("CR4 Write\n");
210 #endif
211       if (v3_handle_cr4_write(info) == -1) {
212         return -1;
213       }    
214       break;
215     }
216   case  VMEXIT_CR4_READ: 
217     {
218 #ifdef DEBUG_CTRL_REGS
219       PrintDebug("CR4 Read\n");
220 #endif
221       if (v3_handle_cr4_read(info) == -1) {
222         return -1;
223       }
224       break;
225     }
226
227   case VMEXIT_EXCP14: 
228     {
229       addr_t fault_addr = guest_ctrl->exit_info2;
230       pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
231 #ifdef DEBUG_SHADOW_PAGING
232       PrintDebug("PageFault at %p (error=%d)\n", 
233                  (void *)fault_addr, *(uint_t *)error_code);
234 #endif
235       if (info->shdw_pg_mode == SHADOW_PAGING) {
236         if (v3_handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
237           return -1;
238         }
239       } else {
240         PrintError("Page fault in un implemented paging mode\n");
241         return -1;
242       }
243       break;
244     } 
245   case VMEXIT_NPF: 
246     {
247       PrintError("Currently unhandled Nested Page Fault\n");
248       return -1;
249
250       break;
251     }
252   case VMEXIT_INVLPG: 
253     {
254       if (info->shdw_pg_mode == SHADOW_PAGING) {
255 #ifdef DEBUG_SHADOW_PAGING
256         PrintDebug("Invlpg\n");
257 #endif
258         if (v3_handle_shadow_invlpg(info) == -1) {
259           return -1;
260         }
261       }
262    
263       /*
264         (exit_code == VMEXIT_INVLPGA)   || 
265       */
266       break;
267     }
268   case VMEXIT_INTR: 
269     {
270       // handled by interrupt dispatch earlier
271       break;
272     }    
273   case VMEXIT_SMI: 
274     {      
275       //   handle_svm_smi(info); // ignored for now
276       break;
277     }
278   case VMEXIT_HLT: 
279     {
280 #ifdef DEBUG_HALT
281       PrintDebug("Guest halted\n");
282 #endif
283       if (v3_handle_svm_halt(info) == -1) {
284         return -1;
285       }
286       break;
287     }
288   case VMEXIT_PAUSE: {
289     //PrintDebug("Guest paused\n");
290     if (v3_handle_svm_pause(info) == -1) { 
291       return -1;
292     }
293   } 
294     break;
295
296
297 #if 0
298     // Emulation handlers currently not used
299   case VMEXIT_EXCP1: 
300     {
301 #ifdef DEBUG_EMULATOR
302       PrintDebug("DEBUG EXCEPTION\n");
303 #endif
304       if (info->run_state == VM_EMULATING) {
305         if (v3_emulation_exit_handler(info) == -1) {
306           return -1;
307         }
308       } else {
309         PrintError("VMMCALL with not emulator...\n");
310         return -1;
311       }
312       break;
313     } 
314     
315
316   case VMEXIT_VMMCALL: 
317     {
318 #ifdef DEBUG_EMULATOR
319       PrintDebug("VMMCALL\n");
320 #endif
321       if (info->run_state == VM_EMULATING) {
322         if (v3_emulation_exit_handler(info) == -1) {
323           return -1;
324         }
325       } else {
326         /*
327         ulong_t tsc_spread = 0;
328         ullong_t exit_tsc = 0;
329
330         ulong_t rax = (ulong_t)info->vm_regs.rbx;
331         ulong_t rdx = (ulong_t)info->vm_regs.rcx;
332
333         *(ulong_t *)(&exit_tsc) = rax;
334         *(((ulong_t *)(&exit_tsc)) + 1) = rdx; 
335
336         tsc_spread = info->exit_tsc - exit_tsc;
337
338         PrintError("VMMCALL tsc diff = %lu\n",tsc_spread); 
339         info->rip += 3;
340         */
341         PrintError("VMMCALL with not emulator...\n");
342         return -1;
343       }
344       break;
345     } 
346 #endif
347
348
349   case VMEXIT_WBINVD: 
350     {
351 #ifdef DEBUG_EMULATOR
352       PrintDebug("WBINVD\n");
353 #endif
354       if (!v3_handle_svm_wbinvd(info)) { 
355         return -1;
356       }
357       break;
358     }
359
360
361
362
363     /* Exits Following this line are NOT HANDLED */
364     /*=======================================================================*/
365
366   default: {
367
368     addr_t rip_addr;
369     uchar_t buf[15];
370     addr_t host_addr;
371
372     PrintDebug("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code));
373
374     rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
375
376
377     PrintError("SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data)); 
378     PrintError("RIP: %p\n", (void *)(addr_t)(guest_state->rip));
379     PrintError("RIP Linear: %p\n", (void *)(addr_t)(rip_addr));
380     
381     PrintError("SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code); 
382     
383     PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
384     PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
385     
386     PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
387     PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
388
389     
390
391     if (info->mem_mode == PHYSICAL_MEM) {
392       if (guest_pa_to_host_va(info, guest_state->rip, &host_addr) == -1) {
393         PrintError("Could not translate guest_state->rip to host address\n");
394         return -1;
395       }
396     } else if (info->mem_mode == VIRTUAL_MEM) {
397       if (guest_va_to_host_va(info, guest_state->rip, &host_addr) == -1) {
398         PrintError("Could not translate guest_state->rip to host address\n");
399         return -1;
400       }
401     } else {
402       PrintError("Invalid memory mode\n");
403       return -1;
404     }
405     
406     PrintError("Host Address of rip = 0x%p\n", (void *)host_addr);
407     
408     memset(buf, 0, 32);
409     
410     PrintError("Reading instruction stream in guest (addr=%p)\n", (void *)rip_addr);
411     
412     if (info->mem_mode == PHYSICAL_MEM) {
413       read_guest_pa_memory(info, rip_addr - 16, 32, buf);
414     } else {
415       read_guest_va_memory(info, rip_addr - 16, 32, buf);
416     }
417     
418     PrintDebug("16 bytes before Rip\n");
419     PrintTraceMemDump(buf, 16);
420     PrintDebug("Rip onward\n");
421     PrintTraceMemDump(buf+16, 16);
422     
423     return -1;
424
425   }
426     break;
427
428   }
429   // END OF SWITCH (EXIT_CODE)
430
431
432   // Update the low level state
433
434   if (v3_intr_pending(info)) {
435
436     switch (v3_get_intr_type(info)) {
437     case EXTERNAL_IRQ: 
438       {
439         uint_t irq = v3_get_intr_number(info);
440
441         // check to see if ==-1 (non exists)
442
443         /*      
444           guest_ctrl->EVENTINJ.vector = irq;
445           guest_ctrl->EVENTINJ.valid = 1;
446           guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
447         */
448         
449         guest_ctrl->guest_ctrl.V_IRQ = 1;
450         guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
451         guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
452         guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
453 #ifdef DEBUG_INTERRUPTS
454         PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
455                    guest_ctrl->guest_ctrl.V_INTR_VECTOR, 
456                    (void *)(addr_t)info->rip);
457 #endif
458         v3_injecting_intr(info, irq, EXTERNAL_IRQ);
459         
460         break;
461       }
462     case NMI:
463       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
464       break;
465     case EXCEPTION:
466       {
467         uint_t excp = v3_get_intr_number(info);
468
469         guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
470         
471         if (info->intr_state.excp_error_code_valid) {  //PAD
472           guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
473           guest_ctrl->EVENTINJ.ev = 1;
474 #ifdef DEBUG_INTERRUPTS
475           PrintDebug("Injecting error code %x\n", guest_ctrl->EVENTINJ.error_code);
476 #endif
477         }
478         
479         guest_ctrl->EVENTINJ.vector = excp;
480         
481         guest_ctrl->EVENTINJ.valid = 1;
482 #ifdef DEBUG_INTERRUPTS
483         PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
484                    guest_ctrl->EVENTINJ.vector, 
485                    (void *)(addr_t)info->rip);
486 #endif
487         v3_injecting_intr(info, excp, EXCEPTION);
488         break;
489       }
490     case SOFTWARE_INTR:
491       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
492       break;
493     case VIRTUAL_INTR:
494       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
495       break;
496
497     case INVALID_INTR: 
498     default:
499       PrintError("Attempted to issue an invalid interrupt\n");
500       return -1;
501     }
502
503   } else {
504 #ifdef DEBUG_INTERRUPTS
505     PrintDebug("No interrupts/exceptions pending\n");
506 #endif
507   }
508
509   guest_state->cr0 = info->ctrl_regs.cr0;
510   guest_state->cr2 = info->ctrl_regs.cr2;
511   guest_state->cr3 = info->ctrl_regs.cr3;
512   guest_state->cr4 = info->ctrl_regs.cr4;
513   guest_state->dr6 = info->dbg_regs.dr6;
514   guest_state->dr7 = info->dbg_regs.dr7;
515   guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
516   guest_state->rflags = info->ctrl_regs.rflags;
517   guest_state->efer = info->ctrl_regs.efer;
518
519   guest_state->cpl = info->cpl;
520
521   guest_state->rax = info->vm_regs.rax;
522   guest_state->rip = info->rip;
523   guest_state->rsp = info->vm_regs.rsp;
524
525
526   set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
527
528   if (exit_code == VMEXIT_INTR) {
529     //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
530   }
531
532   return 0;
533 }
534
535
536 static const uchar_t VMEXIT_CR0_READ_STR[] = "VMEXIT_CR0_READ";
537 static const uchar_t VMEXIT_CR1_READ_STR[] = "VMEXIT_CR1_READ";
538 static const uchar_t VMEXIT_CR2_READ_STR[] = "VMEXIT_CR2_READ";
539 static const uchar_t VMEXIT_CR3_READ_STR[] = "VMEXIT_CR3_READ";
540 static const uchar_t VMEXIT_CR4_READ_STR[] = "VMEXIT_CR4_READ";
541 static const uchar_t VMEXIT_CR5_READ_STR[] = "VMEXIT_CR5_READ";
542 static const uchar_t VMEXIT_CR6_READ_STR[] = "VMEXIT_CR6_READ";
543 static const uchar_t VMEXIT_CR7_READ_STR[] = "VMEXIT_CR7_READ";
544 static const uchar_t VMEXIT_CR8_READ_STR[] = "VMEXIT_CR8_READ";
545 static const uchar_t VMEXIT_CR9_READ_STR[] = "VMEXIT_CR9_READ";
546 static const uchar_t VMEXIT_CR10_READ_STR[] = "VMEXIT_CR10_READ";
547 static const uchar_t VMEXIT_CR11_READ_STR[] = "VMEXIT_CR11_READ";
548 static const uchar_t VMEXIT_CR12_READ_STR[] = "VMEXIT_CR12_READ";
549 static const uchar_t VMEXIT_CR13_READ_STR[] = "VMEXIT_CR13_READ";
550 static const uchar_t VMEXIT_CR14_READ_STR[] = "VMEXIT_CR14_READ";
551 static const uchar_t VMEXIT_CR15_READ_STR[] = "VMEXIT_CR15_READ";
552 static const uchar_t VMEXIT_CR0_WRITE_STR[] = "VMEXIT_CR0_WRITE";
553 static const uchar_t VMEXIT_CR1_WRITE_STR[] = "VMEXIT_CR1_WRITE";
554 static const uchar_t VMEXIT_CR2_WRITE_STR[] = "VMEXIT_CR2_WRITE";
555 static const uchar_t VMEXIT_CR3_WRITE_STR[] = "VMEXIT_CR3_WRITE";
556 static const uchar_t VMEXIT_CR4_WRITE_STR[] = "VMEXIT_CR4_WRITE";
557 static const uchar_t VMEXIT_CR5_WRITE_STR[] = "VMEXIT_CR5_WRITE";
558 static const uchar_t VMEXIT_CR6_WRITE_STR[] = "VMEXIT_CR6_WRITE";
559 static const uchar_t VMEXIT_CR7_WRITE_STR[] = "VMEXIT_CR7_WRITE";
560 static const uchar_t VMEXIT_CR8_WRITE_STR[] = "VMEXIT_CR8_WRITE";
561 static const uchar_t VMEXIT_CR9_WRITE_STR[] = "VMEXIT_CR9_WRITE";
562 static const uchar_t VMEXIT_CR10_WRITE_STR[] = "VMEXIT_CR10_WRITE";
563 static const uchar_t VMEXIT_CR11_WRITE_STR[] = "VMEXIT_CR11_WRITE";
564 static const uchar_t VMEXIT_CR12_WRITE_STR[] = "VMEXIT_CR12_WRITE";
565 static const uchar_t VMEXIT_CR13_WRITE_STR[] = "VMEXIT_CR13_WRITE";
566 static const uchar_t VMEXIT_CR14_WRITE_STR[] = "VMEXIT_CR14_WRITE";
567 static const uchar_t VMEXIT_CR15_WRITE_STR[] = "VMEXIT_CR15_WRITE";
568 static const uchar_t VMEXIT_DR0_READ_STR[] = "VMEXIT_DR0_READ";
569 static const uchar_t VMEXIT_DR1_READ_STR[] = "VMEXIT_DR1_READ";
570 static const uchar_t VMEXIT_DR2_READ_STR[] = "VMEXIT_DR2_READ";
571 static const uchar_t VMEXIT_DR3_READ_STR[] = "VMEXIT_DR3_READ";
572 static const uchar_t VMEXIT_DR4_READ_STR[] = "VMEXIT_DR4_READ";
573 static const uchar_t VMEXIT_DR5_READ_STR[] = "VMEXIT_DR5_READ";
574 static const uchar_t VMEXIT_DR6_READ_STR[] = "VMEXIT_DR6_READ";
575 static const uchar_t VMEXIT_DR7_READ_STR[] = "VMEXIT_DR7_READ";
576 static const uchar_t VMEXIT_DR8_READ_STR[] = "VMEXIT_DR8_READ";
577 static const uchar_t VMEXIT_DR9_READ_STR[] = "VMEXIT_DR9_READ";
578 static const uchar_t VMEXIT_DR10_READ_STR[] = "VMEXIT_DR10_READ";
579 static const uchar_t VMEXIT_DR11_READ_STR[] = "VMEXIT_DR11_READ";
580 static const uchar_t VMEXIT_DR12_READ_STR[] = "VMEXIT_DR12_READ";
581 static const uchar_t VMEXIT_DR13_READ_STR[] = "VMEXIT_DR13_READ";
582 static const uchar_t VMEXIT_DR14_READ_STR[] = "VMEXIT_DR14_READ";
583 static const uchar_t VMEXIT_DR15_READ_STR[] = "VMEXIT_DR15_READ";
584 static const uchar_t VMEXIT_DR0_WRITE_STR[] = "VMEXIT_DR0_WRITE";
585 static const uchar_t VMEXIT_DR1_WRITE_STR[] = "VMEXIT_DR1_WRITE";
586 static const uchar_t VMEXIT_DR2_WRITE_STR[] = "VMEXIT_DR2_WRITE";
587 static const uchar_t VMEXIT_DR3_WRITE_STR[] = "VMEXIT_DR3_WRITE";
588 static const uchar_t VMEXIT_DR4_WRITE_STR[] = "VMEXIT_DR4_WRITE";
589 static const uchar_t VMEXIT_DR5_WRITE_STR[] = "VMEXIT_DR5_WRITE";
590 static const uchar_t VMEXIT_DR6_WRITE_STR[] = "VMEXIT_DR6_WRITE";
591 static const uchar_t VMEXIT_DR7_WRITE_STR[] = "VMEXIT_DR7_WRITE";
592 static const uchar_t VMEXIT_DR8_WRITE_STR[] = "VMEXIT_DR8_WRITE";
593 static const uchar_t VMEXIT_DR9_WRITE_STR[] = "VMEXIT_DR9_WRITE";
594 static const uchar_t VMEXIT_DR10_WRITE_STR[] = "VMEXIT_DR10_WRITE";
595 static const uchar_t VMEXIT_DR11_WRITE_STR[] = "VMEXIT_DR11_WRITE";
596 static const uchar_t VMEXIT_DR12_WRITE_STR[] = "VMEXIT_DR12_WRITE";
597 static const uchar_t VMEXIT_DR13_WRITE_STR[] = "VMEXIT_DR13_WRITE";
598 static const uchar_t VMEXIT_DR14_WRITE_STR[] = "VMEXIT_DR14_WRITE";
599 static const uchar_t VMEXIT_DR15_WRITE_STR[] = "VMEXIT_DR15_WRITE";
600 static const uchar_t VMEXIT_EXCP0_STR[] = "VMEXIT_EXCP0";
601 static const uchar_t VMEXIT_EXCP1_STR[] = "VMEXIT_EXCP1";
602 static const uchar_t VMEXIT_EXCP2_STR[] = "VMEXIT_EXCP2";
603 static const uchar_t VMEXIT_EXCP3_STR[] = "VMEXIT_EXCP3";
604 static const uchar_t VMEXIT_EXCP4_STR[] = "VMEXIT_EXCP4";
605 static const uchar_t VMEXIT_EXCP5_STR[] = "VMEXIT_EXCP5";
606 static const uchar_t VMEXIT_EXCP6_STR[] = "VMEXIT_EXCP6";
607 static const uchar_t VMEXIT_EXCP7_STR[] = "VMEXIT_EXCP7";
608 static const uchar_t VMEXIT_EXCP8_STR[] = "VMEXIT_EXCP8";
609 static const uchar_t VMEXIT_EXCP9_STR[] = "VMEXIT_EXCP9";
610 static const uchar_t VMEXIT_EXCP10_STR[] = "VMEXIT_EXCP10";
611 static const uchar_t VMEXIT_EXCP11_STR[] = "VMEXIT_EXCP11";
612 static const uchar_t VMEXIT_EXCP12_STR[] = "VMEXIT_EXCP12";
613 static const uchar_t VMEXIT_EXCP13_STR[] = "VMEXIT_EXCP13";
614 static const uchar_t VMEXIT_EXCP14_STR[] = "VMEXIT_EXCP14";
615 static const uchar_t VMEXIT_EXCP15_STR[] = "VMEXIT_EXCP15";
616 static const uchar_t VMEXIT_EXCP16_STR[] = "VMEXIT_EXCP16";
617 static const uchar_t VMEXIT_EXCP17_STR[] = "VMEXIT_EXCP17";
618 static const uchar_t VMEXIT_EXCP18_STR[] = "VMEXIT_EXCP18";
619 static const uchar_t VMEXIT_EXCP19_STR[] = "VMEXIT_EXCP19";
620 static const uchar_t VMEXIT_EXCP20_STR[] = "VMEXIT_EXCP20";
621 static const uchar_t VMEXIT_EXCP21_STR[] = "VMEXIT_EXCP21";
622 static const uchar_t VMEXIT_EXCP22_STR[] = "VMEXIT_EXCP22";
623 static const uchar_t VMEXIT_EXCP23_STR[] = "VMEXIT_EXCP23";
624 static const uchar_t VMEXIT_EXCP24_STR[] = "VMEXIT_EXCP24";
625 static const uchar_t VMEXIT_EXCP25_STR[] = "VMEXIT_EXCP25";
626 static const uchar_t VMEXIT_EXCP26_STR[] = "VMEXIT_EXCP26";
627 static const uchar_t VMEXIT_EXCP27_STR[] = "VMEXIT_EXCP27";
628 static const uchar_t VMEXIT_EXCP28_STR[] = "VMEXIT_EXCP28";
629 static const uchar_t VMEXIT_EXCP29_STR[] = "VMEXIT_EXCP29";
630 static const uchar_t VMEXIT_EXCP30_STR[] = "VMEXIT_EXCP30";
631 static const uchar_t VMEXIT_EXCP31_STR[] = "VMEXIT_EXCP31";
632 static const uchar_t VMEXIT_INTR_STR[] = "VMEXIT_INTR";
633 static const uchar_t VMEXIT_NMI_STR[] = "VMEXIT_NMI";
634 static const uchar_t VMEXIT_SMI_STR[] = "VMEXIT_SMI";
635 static const uchar_t VMEXIT_INIT_STR[] = "VMEXIT_INIT";
636 static const uchar_t VMEXIT_VINITR_STR[] = "VMEXIT_VINITR";
637 static const uchar_t VMEXIT_CR0_SEL_WRITE_STR[] = "VMEXIT_CR0_SEL_WRITE";
638 static const uchar_t VMEXIT_IDTR_READ_STR[] = "VMEXIT_IDTR_READ";
639 static const uchar_t VMEXIT_GDTR_READ_STR[] = "VMEXIT_GDTR_READ";
640 static const uchar_t VMEXIT_LDTR_READ_STR[] = "VMEXIT_LDTR_READ";
641 static const uchar_t VMEXIT_TR_READ_STR[] = "VMEXIT_TR_READ";
642 static const uchar_t VMEXIT_IDTR_WRITE_STR[] = "VMEXIT_IDTR_WRITE";
643 static const uchar_t VMEXIT_GDTR_WRITE_STR[] = "VMEXIT_GDTR_WRITE";
644 static const uchar_t VMEXIT_LDTR_WRITE_STR[] = "VMEXIT_LDTR_WRITE";
645 static const uchar_t VMEXIT_TR_WRITE_STR[] = "VMEXIT_TR_WRITE";
646 static const uchar_t VMEXIT_RDTSC_STR[] = "VMEXIT_RDTSC";
647 static const uchar_t VMEXIT_RDPMC_STR[] = "VMEXIT_RDPMC";
648 static const uchar_t VMEXIT_PUSHF_STR[] = "VMEXIT_PUSHF";
649 static const uchar_t VMEXIT_POPF_STR[] = "VMEXIT_POPF";
650 static const uchar_t VMEXIT_CPUID_STR[] = "VMEXIT_CPUID";
651 static const uchar_t VMEXIT_RSM_STR[] = "VMEXIT_RSM";
652 static const uchar_t VMEXIT_IRET_STR[] = "VMEXIT_IRET";
653 static const uchar_t VMEXIT_SWINT_STR[] = "VMEXIT_SWINT";
654 static const uchar_t VMEXIT_INVD_STR[] = "VMEXIT_INVD";
655 static const uchar_t VMEXIT_PAUSE_STR[] = "VMEXIT_PAUSE";
656 static const uchar_t VMEXIT_HLT_STR[] = "VMEXIT_HLT";
657 static const uchar_t VMEXIT_INVLPG_STR[] = "VMEXIT_INVLPG";
658 static const uchar_t VMEXIT_INVLPGA_STR[] = "VMEXIT_INVLPGA";
659 static const uchar_t VMEXIT_IOIO_STR[] = "VMEXIT_IOIO";
660 static const uchar_t VMEXIT_MSR_STR[] = "VMEXIT_MSR";
661 static const uchar_t VMEXIT_TASK_SWITCH_STR[] = "VMEXIT_TASK_SWITCH";
662 static const uchar_t VMEXIT_FERR_FREEZE_STR[] = "VMEXIT_FERR_FREEZE";
663 static const uchar_t VMEXIT_SHUTDOWN_STR[] = "VMEXIT_SHUTDOWN";
664 static const uchar_t VMEXIT_VMRUN_STR[] = "VMEXIT_VMRUN";
665 static const uchar_t VMEXIT_VMMCALL_STR[] = "VMEXIT_VMMCALL";
666 static const uchar_t VMEXIT_VMLOAD_STR[] = "VMEXIT_VMLOAD";
667 static const uchar_t VMEXIT_VMSAVE_STR[] = "VMEXIT_VMSAVE";
668 static const uchar_t VMEXIT_STGI_STR[] = "VMEXIT_STGI";
669 static const uchar_t VMEXIT_CLGI_STR[] = "VMEXIT_CLGI";
670 static const uchar_t VMEXIT_SKINIT_STR[] = "VMEXIT_SKINIT";
671 static const uchar_t VMEXIT_RDTSCP_STR[] = "VMEXIT_RDTSCP";
672 static const uchar_t VMEXIT_ICEBP_STR[] = "VMEXIT_ICEBP";
673 static const uchar_t VMEXIT_WBINVD_STR[] = "VMEXIT_WBINVD";
674 static const uchar_t VMEXIT_MONITOR_STR[] = "VMEXIT_MONITOR";
675 static const uchar_t VMEXIT_MWAIT_STR[] = "VMEXIT_MWAIT";
676 static const uchar_t VMEXIT_MWAIT_CONDITIONAL_STR[] = "VMEXIT_MWAIT_CONDITIONAL";
677 static const uchar_t VMEXIT_NPF_STR[] = "VMEXIT_NPF";
678 static const uchar_t VMEXIT_INVALID_VMCB_STR[] = "VMEXIT_INVALID_VMCB";
679
680
681
682 const uchar_t * vmexit_code_to_str(uint_t exit_code) {
683   switch(exit_code) {
684   case VMEXIT_CR0_READ:
685     return VMEXIT_CR0_READ_STR;
686   case VMEXIT_CR1_READ:
687     return VMEXIT_CR1_READ_STR;
688   case VMEXIT_CR2_READ:
689     return VMEXIT_CR2_READ_STR;
690   case VMEXIT_CR3_READ:
691     return VMEXIT_CR3_READ_STR;
692   case VMEXIT_CR4_READ:
693     return VMEXIT_CR4_READ_STR;
694   case VMEXIT_CR5_READ:
695     return VMEXIT_CR5_READ_STR;
696   case VMEXIT_CR6_READ:
697     return VMEXIT_CR6_READ_STR;
698   case VMEXIT_CR7_READ:
699     return VMEXIT_CR7_READ_STR;
700   case VMEXIT_CR8_READ:
701     return VMEXIT_CR8_READ_STR;
702   case VMEXIT_CR9_READ:
703     return VMEXIT_CR9_READ_STR;
704   case VMEXIT_CR10_READ:
705     return VMEXIT_CR10_READ_STR;
706   case VMEXIT_CR11_READ:
707     return VMEXIT_CR11_READ_STR;
708   case VMEXIT_CR12_READ:
709     return VMEXIT_CR12_READ_STR;
710   case VMEXIT_CR13_READ:
711     return VMEXIT_CR13_READ_STR;
712   case VMEXIT_CR14_READ:
713     return VMEXIT_CR14_READ_STR;
714   case VMEXIT_CR15_READ:
715     return VMEXIT_CR15_READ_STR;
716   case VMEXIT_CR0_WRITE:
717     return VMEXIT_CR0_WRITE_STR;
718   case VMEXIT_CR1_WRITE:
719     return VMEXIT_CR1_WRITE_STR;
720   case VMEXIT_CR2_WRITE:
721     return VMEXIT_CR2_WRITE_STR;
722   case VMEXIT_CR3_WRITE:
723     return VMEXIT_CR3_WRITE_STR;
724   case VMEXIT_CR4_WRITE:
725     return VMEXIT_CR4_WRITE_STR;
726   case VMEXIT_CR5_WRITE:
727     return VMEXIT_CR5_WRITE_STR;
728   case VMEXIT_CR6_WRITE:
729     return VMEXIT_CR6_WRITE_STR;
730   case VMEXIT_CR7_WRITE:
731     return VMEXIT_CR7_WRITE_STR;
732   case VMEXIT_CR8_WRITE:
733     return VMEXIT_CR8_WRITE_STR;
734   case VMEXIT_CR9_WRITE:
735     return VMEXIT_CR9_WRITE_STR;
736   case VMEXIT_CR10_WRITE:
737     return VMEXIT_CR10_WRITE_STR;
738   case VMEXIT_CR11_WRITE:
739     return VMEXIT_CR11_WRITE_STR;
740   case VMEXIT_CR12_WRITE:
741     return VMEXIT_CR12_WRITE_STR;
742   case VMEXIT_CR13_WRITE:
743     return VMEXIT_CR13_WRITE_STR;
744   case VMEXIT_CR14_WRITE:
745     return VMEXIT_CR14_WRITE_STR;
746   case VMEXIT_CR15_WRITE:
747     return VMEXIT_CR15_WRITE_STR;
748   case VMEXIT_DR0_READ:
749     return VMEXIT_DR0_READ_STR;
750   case VMEXIT_DR1_READ:
751     return VMEXIT_DR1_READ_STR;
752   case VMEXIT_DR2_READ:
753     return VMEXIT_DR2_READ_STR;
754   case VMEXIT_DR3_READ:
755     return VMEXIT_DR3_READ_STR;
756   case VMEXIT_DR4_READ:
757     return VMEXIT_DR4_READ_STR;
758   case VMEXIT_DR5_READ:
759     return VMEXIT_DR5_READ_STR;
760   case VMEXIT_DR6_READ:
761     return VMEXIT_DR6_READ_STR;
762   case VMEXIT_DR7_READ:
763     return VMEXIT_DR7_READ_STR;
764   case VMEXIT_DR8_READ:
765     return VMEXIT_DR8_READ_STR;
766   case VMEXIT_DR9_READ:
767     return VMEXIT_DR9_READ_STR;
768   case VMEXIT_DR10_READ:
769     return VMEXIT_DR10_READ_STR;
770   case VMEXIT_DR11_READ:
771     return VMEXIT_DR11_READ_STR;
772   case VMEXIT_DR12_READ:
773     return VMEXIT_DR12_READ_STR;
774   case VMEXIT_DR13_READ:
775     return VMEXIT_DR13_READ_STR;
776   case VMEXIT_DR14_READ:
777     return VMEXIT_DR14_READ_STR;
778   case VMEXIT_DR15_READ:
779     return VMEXIT_DR15_READ_STR;
780   case VMEXIT_DR0_WRITE:
781     return VMEXIT_DR0_WRITE_STR;
782   case VMEXIT_DR1_WRITE:
783     return VMEXIT_DR1_WRITE_STR;
784   case VMEXIT_DR2_WRITE:
785     return VMEXIT_DR2_WRITE_STR;
786   case VMEXIT_DR3_WRITE:
787     return VMEXIT_DR3_WRITE_STR;
788   case VMEXIT_DR4_WRITE:
789     return VMEXIT_DR4_WRITE_STR;
790   case VMEXIT_DR5_WRITE:
791     return VMEXIT_DR5_WRITE_STR;
792   case VMEXIT_DR6_WRITE:
793     return VMEXIT_DR6_WRITE_STR;
794   case VMEXIT_DR7_WRITE:
795     return VMEXIT_DR7_WRITE_STR;
796   case VMEXIT_DR8_WRITE:
797     return VMEXIT_DR8_WRITE_STR;
798   case VMEXIT_DR9_WRITE:
799     return VMEXIT_DR9_WRITE_STR;
800   case VMEXIT_DR10_WRITE:
801     return VMEXIT_DR10_WRITE_STR;
802   case VMEXIT_DR11_WRITE:
803     return VMEXIT_DR11_WRITE_STR;
804   case VMEXIT_DR12_WRITE:
805     return VMEXIT_DR12_WRITE_STR;
806   case VMEXIT_DR13_WRITE:
807     return VMEXIT_DR13_WRITE_STR;
808   case VMEXIT_DR14_WRITE:
809     return VMEXIT_DR14_WRITE_STR;
810   case VMEXIT_DR15_WRITE:
811     return VMEXIT_DR15_WRITE_STR;
812   case VMEXIT_EXCP0:
813     return VMEXIT_EXCP0_STR;
814   case VMEXIT_EXCP1:
815     return VMEXIT_EXCP1_STR;
816   case VMEXIT_EXCP2:
817     return VMEXIT_EXCP2_STR;
818   case VMEXIT_EXCP3:
819     return VMEXIT_EXCP3_STR;
820   case VMEXIT_EXCP4:
821     return VMEXIT_EXCP4_STR;
822   case VMEXIT_EXCP5:
823     return VMEXIT_EXCP5_STR;
824   case VMEXIT_EXCP6:
825     return VMEXIT_EXCP6_STR;
826   case VMEXIT_EXCP7:
827     return VMEXIT_EXCP7_STR;
828   case VMEXIT_EXCP8:
829     return VMEXIT_EXCP8_STR;
830   case VMEXIT_EXCP9:
831     return VMEXIT_EXCP9_STR;
832   case VMEXIT_EXCP10:
833     return VMEXIT_EXCP10_STR;
834   case VMEXIT_EXCP11:
835     return VMEXIT_EXCP11_STR;
836   case VMEXIT_EXCP12:
837     return VMEXIT_EXCP12_STR;
838   case VMEXIT_EXCP13:
839     return VMEXIT_EXCP13_STR;
840   case VMEXIT_EXCP14:
841     return VMEXIT_EXCP14_STR;
842   case VMEXIT_EXCP15:
843     return VMEXIT_EXCP15_STR;
844   case VMEXIT_EXCP16:
845     return VMEXIT_EXCP16_STR;
846   case VMEXIT_EXCP17:
847     return VMEXIT_EXCP17_STR;
848   case VMEXIT_EXCP18:
849     return VMEXIT_EXCP18_STR;
850   case VMEXIT_EXCP19:
851     return VMEXIT_EXCP19_STR;
852   case VMEXIT_EXCP20:
853     return VMEXIT_EXCP20_STR;
854   case VMEXIT_EXCP21:
855     return VMEXIT_EXCP21_STR;
856   case VMEXIT_EXCP22:
857     return VMEXIT_EXCP22_STR;
858   case VMEXIT_EXCP23:
859     return VMEXIT_EXCP23_STR;
860   case VMEXIT_EXCP24:
861     return VMEXIT_EXCP24_STR;
862   case VMEXIT_EXCP25:
863     return VMEXIT_EXCP25_STR;
864   case VMEXIT_EXCP26:
865     return VMEXIT_EXCP26_STR;
866   case VMEXIT_EXCP27:
867     return VMEXIT_EXCP27_STR;
868   case VMEXIT_EXCP28:
869     return VMEXIT_EXCP28_STR;
870   case VMEXIT_EXCP29:
871     return VMEXIT_EXCP29_STR;
872   case VMEXIT_EXCP30:
873     return VMEXIT_EXCP30_STR;
874   case VMEXIT_EXCP31:
875     return VMEXIT_EXCP31_STR;
876   case VMEXIT_INTR:
877     return VMEXIT_INTR_STR;
878   case VMEXIT_NMI:
879     return VMEXIT_NMI_STR;
880   case VMEXIT_SMI:
881     return VMEXIT_SMI_STR;
882   case VMEXIT_INIT:
883     return VMEXIT_INIT_STR;
884   case VMEXIT_VINITR:
885     return VMEXIT_VINITR_STR;
886   case VMEXIT_CR0_SEL_WRITE:
887     return VMEXIT_CR0_SEL_WRITE_STR;
888   case VMEXIT_IDTR_READ:
889     return VMEXIT_IDTR_READ_STR;
890   case VMEXIT_GDTR_READ:
891     return VMEXIT_GDTR_READ_STR;
892   case VMEXIT_LDTR_READ:
893     return VMEXIT_LDTR_READ_STR;
894   case VMEXIT_TR_READ:
895     return VMEXIT_TR_READ_STR;
896   case VMEXIT_IDTR_WRITE:
897     return VMEXIT_IDTR_WRITE_STR;
898   case VMEXIT_GDTR_WRITE:
899     return VMEXIT_GDTR_WRITE_STR;
900   case VMEXIT_LDTR_WRITE:
901     return VMEXIT_LDTR_WRITE_STR;
902   case VMEXIT_TR_WRITE:
903     return VMEXIT_TR_WRITE_STR;
904   case VMEXIT_RDTSC:
905     return VMEXIT_RDTSC_STR;
906   case VMEXIT_RDPMC:
907     return VMEXIT_RDPMC_STR;
908   case VMEXIT_PUSHF:
909     return VMEXIT_PUSHF_STR;
910   case VMEXIT_POPF:
911     return VMEXIT_POPF_STR;
912   case VMEXIT_CPUID:
913     return VMEXIT_CPUID_STR;
914   case VMEXIT_RSM:
915     return VMEXIT_RSM_STR;
916   case VMEXIT_IRET:
917     return VMEXIT_IRET_STR;
918   case VMEXIT_SWINT:
919     return VMEXIT_SWINT_STR;
920   case VMEXIT_INVD:
921     return VMEXIT_INVD_STR;
922   case VMEXIT_PAUSE:
923     return VMEXIT_PAUSE_STR;
924   case VMEXIT_HLT:
925     return VMEXIT_HLT_STR;
926   case VMEXIT_INVLPG:
927     return VMEXIT_INVLPG_STR;
928   case VMEXIT_INVLPGA:
929     return VMEXIT_INVLPGA_STR;
930   case VMEXIT_IOIO:
931     return VMEXIT_IOIO_STR;
932   case VMEXIT_MSR:
933     return VMEXIT_MSR_STR;
934   case VMEXIT_TASK_SWITCH:
935     return VMEXIT_TASK_SWITCH_STR;
936   case VMEXIT_FERR_FREEZE:
937     return VMEXIT_FERR_FREEZE_STR;
938   case VMEXIT_SHUTDOWN:
939     return VMEXIT_SHUTDOWN_STR;
940   case VMEXIT_VMRUN:
941     return VMEXIT_VMRUN_STR;
942   case VMEXIT_VMMCALL:
943     return VMEXIT_VMMCALL_STR;
944   case VMEXIT_VMLOAD:
945     return VMEXIT_VMLOAD_STR;
946   case VMEXIT_VMSAVE:
947     return VMEXIT_VMSAVE_STR;
948   case VMEXIT_STGI:
949     return VMEXIT_STGI_STR;
950   case VMEXIT_CLGI:
951     return VMEXIT_CLGI_STR;
952   case VMEXIT_SKINIT:
953     return VMEXIT_SKINIT_STR;
954   case VMEXIT_RDTSCP:
955     return VMEXIT_RDTSCP_STR;
956   case VMEXIT_ICEBP:
957     return VMEXIT_ICEBP_STR;
958   case VMEXIT_WBINVD:
959     return VMEXIT_WBINVD_STR;
960   case VMEXIT_MONITOR:
961     return VMEXIT_MONITOR_STR;
962   case VMEXIT_MWAIT:
963     return VMEXIT_MWAIT_STR;
964   case VMEXIT_MWAIT_CONDITIONAL:
965     return VMEXIT_MWAIT_CONDITIONAL_STR;
966   case VMEXIT_NPF:
967     return VMEXIT_NPF_STR;
968   case VMEXIT_INVALID_VMCB:
969     return VMEXIT_INVALID_VMCB_STR;
970   }
971   return NULL;
972 }