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.


changed to error output
[palacios.git] / palacios / src / palacios / svm_handler.c
index ad4fe4c..68bb240 100644 (file)
@@ -1,3 +1,23 @@
+/* 
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
 #include <palacios/svm_handler.h>
 #include <palacios/vmm.h>
 #include <palacios/vm_guest_mem.h>
@@ -9,8 +29,13 @@
 #include <palacios/svm_wbinvd.h>
 #include <palacios/vmm_intr.h>
 #include <palacios/vmm_emulator.h>
+#include <palacios/svm_msr.h>
+#include <palacios/vmm_profiler.h>
+
+
+
 
-int handle_svm_exit(struct guest_info * info) {
+int v3_handle_svm_exit(struct guest_info * info) {
   vmcb_ctrl_t * guest_ctrl = 0;
   vmcb_saved_state_t * guest_state = 0;
   ulong_t exit_code = 0;
@@ -38,12 +63,15 @@ int handle_svm_exit(struct guest_info * info) {
   info->ctrl_regs.efer = guest_state->efer;
 
   get_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
-  info->cpu_mode = get_cpu_mode(info);
-  info->mem_mode = get_mem_mode(info);
+  info->cpu_mode = v3_get_cpu_mode(info);
+  info->mem_mode = v3_get_mem_mode(info);
 
 
   exit_code = guest_ctrl->exit_code;
+
+
+
+  
 
   // Disable printing io exits due to bochs debug messages
   //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
@@ -52,12 +80,12 @@ int handle_svm_exit(struct guest_info * info) {
   //  PrintDebug("SVM Returned: Exit Code: 0x%x \t\t(tsc=%ul)\n",exit_code, (uint_t)info->time_state.guest_tsc); 
   
   if ((0) && (exit_code < 0x4f)) {
-    char instr[32];
+    uchar_t instr[32];
     int ret;
     // Dump out the instr stream
 
     //PrintDebug("RIP: %x\n", guest_state->rip);
-    PrintDebug("RIP Linear: %x\n", get_addr_linear(info, info->rip, &(info->segments.cs)));
+    PrintDebug("RIP Linear: %p\n", (void *)get_addr_linear(info, info->rip, &(info->segments.cs)));
 
     // OK, now we will read the instruction
     // The only difference between PROTECTED and PROTECTED_PG is whether we read
@@ -80,157 +108,194 @@ int handle_svm_exit(struct guest_info * info) {
   }
 
 
-    //  }
-  // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
-
 
-  // PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
-  //PrintDebug("RIP: %x\n", guest_state->rip);
+  if (info->enable_profiler) {
+    rdtscll(info->profiler.start_time);
+  }
 
   
   //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
 
   switch (exit_code) {
 
-  case VMEXIT_IOIO: {
-    struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
-    
-    if (io_info->type == 0) {
-      if (io_info->str) {
-       if (handle_svm_io_outs(info) == -1 ) {
-         return -1;
+  case VMEXIT_IOIO: 
+    {
+      struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
+      
+      if (io_info->type == 0) {
+       if (io_info->str) {
+         if (v3_handle_svm_io_outs(info) == -1 ) {
+           return -1;
+         }
+       } else {
+         if (v3_handle_svm_io_out(info) == -1) {
+           return -1;
+         }
        }
       } else {
-       if (handle_svm_io_out(info) == -1) {
-         return -1;
+       if (io_info->str) {
+         if (v3_handle_svm_io_ins(info) == -1) {
+           return -1;
+         }
+       } else {
+         if (v3_handle_svm_io_in(info) == -1) {
+           return -1;
+         }
        }
       }
-    } else {
-      if (io_info->str) {
-       if (handle_svm_io_ins(info) == -1) {
+      break;
+    }
+  case VMEXIT_MSR:
+    {
+
+      if (guest_ctrl->exit_info1 == 0) {
+       if (v3_handle_msr_read(info) == -1) {
          return -1;
        }
-      } else {
-       if (handle_svm_io_in(info) == -1) {
+      } else if (guest_ctrl->exit_info1 == 1) {
+       if (v3_handle_msr_write(info) == -1) {
          return -1;
        }
+      } else {
+       PrintError("Invalid MSR Operation\n");
+       return -1;
       }
-    }
-  }
-    break;
-
 
-  case  VMEXIT_CR0_WRITE: {
+      break;
+    }
+  case VMEXIT_CR0_WRITE: 
+    {
 #ifdef DEBUG_CTRL_REGS
-    PrintDebug("CR0 Write\n");
+      PrintDebug("CR0 Write\n");
 #endif
-    if (handle_cr0_write(info) == -1) {
-      return -1;
+      if (v3_handle_cr0_write(info) == -1) {
+       return -1;
+      }
+      break;
+    } 
+  case VMEXIT_CR0_READ: 
+    {
+#ifdef DEBUG_CTRL_REGS
+      PrintDebug("CR0 Read\n");
+#endif
+      if (v3_handle_cr0_read(info) == -1) {
+       return -1;
+      }
+      break;
+    } 
+  case VMEXIT_CR3_WRITE: 
+    {
+#ifdef DEBUG_CTRL_REGS
+      PrintDebug("CR3 Write\n");
+#endif
+      if (v3_handle_cr3_write(info) == -1) {
+       return -1;
+      }    
+      break;
     }
-  } 
-    break;
-
-  case VMEXIT_CR0_READ: {
+  case  VMEXIT_CR3_READ: 
+    {
 #ifdef DEBUG_CTRL_REGS
-    PrintDebug("CR0 Read\n");
+      PrintDebug("CR3 Read\n");
 #endif
-    if (handle_cr0_read(info) == -1) {
-      return -1;
+      if (v3_handle_cr3_read(info) == -1) {
+       return -1;
+      }
+      break;
     }
-  } 
-    break;
-
-  case VMEXIT_CR3_WRITE: {
+  case VMEXIT_CR4_WRITE: 
+    {
 #ifdef DEBUG_CTRL_REGS
-    PrintDebug("CR3 Write\n");
+      PrintDebug("CR4 Write\n");
 #endif
-    if (handle_cr3_write(info) == -1) {
-      return -1;
-    }    
-  } 
-    break;
-
-  case  VMEXIT_CR3_READ: {
+      if (v3_handle_cr4_write(info) == -1) {
+       return -1;
+      }    
+      break;
+    }
+  case  VMEXIT_CR4_READ: 
+    {
 #ifdef DEBUG_CTRL_REGS
-    PrintDebug("CR3 Read\n");
+      PrintDebug("CR4 Read\n");
 #endif
-    if (handle_cr3_read(info) == -1) {
-      return -1;
+      if (v3_handle_cr4_read(info) == -1) {
+       return -1;
+      }
+      break;
     }
-  }
-    break;
 
-  case VMEXIT_EXCP14: {
-    addr_t fault_addr = guest_ctrl->exit_info2;
-    pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
+  case VMEXIT_EXCP14: 
+    {
+      addr_t fault_addr = guest_ctrl->exit_info2;
+      pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1);
 #ifdef DEBUG_SHADOW_PAGING
-    PrintDebug("PageFault at %x (error=%d)\n", fault_addr, *error_code);
+      PrintDebug("PageFault at %p (error=%d)\n", 
+                (void *)fault_addr, *(uint_t *)error_code);
 #endif
-    if (info->shdw_pg_mode == SHADOW_PAGING) {
-      if (handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
+      if (info->shdw_pg_mode == SHADOW_PAGING) {
+       if (v3_handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
+         return -1;
+       }
+      } else {
+       PrintError("Page fault in un implemented paging mode\n");
        return -1;
       }
-    } else {
-      PrintError("Page fault in un implemented paging mode\n");
+      break;
+    } 
+  case VMEXIT_NPF: 
+    {
+      PrintError("Currently unhandled Nested Page Fault\n");
       return -1;
-    }
-  } 
-    break;
-
-  case VMEXIT_NPF: {
-    PrintError("Currently unhandled Nested Page Fault\n");
-    return -1;
-    
-  } 
-    break;
 
-  case VMEXIT_INVLPG: {
-    if (info->shdw_pg_mode == SHADOW_PAGING) {
+      break;
+    }
+  case VMEXIT_INVLPG: 
+    {
+      if (info->shdw_pg_mode == SHADOW_PAGING) {
 #ifdef DEBUG_SHADOW_PAGING
-      PrintDebug("Invlpg\n");
+       PrintDebug("Invlpg\n");
 #endif
-      if (handle_shadow_invlpg(info) == -1) {
-       return -1;
+       if (v3_handle_shadow_invlpg(info) == -1) {
+         return -1;
+       }
       }
-    }
    
-    /*
-      (exit_code == VMEXIT_INVLPGA)   || 
-    */
-    
-  } 
-    break;
-
-  case VMEXIT_INTR: { 
-    
-    //    handle_svm_intr(info); // handled by interrupt dispatch earlier
-
-  } 
-    break;
-    
-  case VMEXIT_SMI: {
-    
-    //   handle_svm_smi(info); // ignored for now
-
-  } 
-    break;
-
-  case VMEXIT_HLT: {
-    PrintDebug("Guest halted\n");
-    if (handle_svm_halt(info) == -1) {
-      return -1;
+      /*
+       (exit_code == VMEXIT_INVLPGA)   || 
+      */
+      break;
+    }
+  case VMEXIT_INTR: 
+    {
+      // handled by interrupt dispatch earlier
+      break;
+    }    
+  case VMEXIT_SMI: 
+    {      
+      //   handle_svm_smi(info); // ignored for now
+      break;
+    }
+  case VMEXIT_HLT: 
+    {
+#ifdef DEBUG_HALT
+      PrintDebug("Guest halted\n");
+#endif
+      if (v3_handle_svm_halt(info) == -1) {
+       return -1;
+      }
+      break;
     }
-  } 
-    break;
-
   case VMEXIT_PAUSE: {
-    PrintDebug("Guest paused\n");
-    if (handle_svm_pause(info) == -1) { 
+    //PrintDebug("Guest paused\n");
+    if (v3_handle_svm_pause(info) == -1) { 
       return -1;
     }
   } 
     break;
 
+
+#if 0
+    // Emulation handlers currently not used
   case VMEXIT_EXCP1: 
     {
 #ifdef DEBUG_EMULATOR
@@ -246,7 +311,7 @@ int handle_svm_exit(struct guest_info * info) {
       }
       break;
     } 
-
+    
 
   case VMEXIT_VMMCALL: 
     {
@@ -258,12 +323,27 @@ int handle_svm_exit(struct guest_info * info) {
          return -1;
        }
       } else {
+       /*
+       ulong_t tsc_spread = 0;
+       ullong_t exit_tsc = 0;
+
+       ulong_t rax = (ulong_t)info->vm_regs.rbx;
+       ulong_t rdx = (ulong_t)info->vm_regs.rcx;
+
+       *(ulong_t *)(&exit_tsc) = rax;
+       *(((ulong_t *)(&exit_tsc)) + 1) = rdx; 
+
+       tsc_spread = info->exit_tsc - exit_tsc;
+
+       PrintError("VMMCALL tsc diff = %lu\n",tsc_spread); 
+       info->rip += 3;
+       */
        PrintError("VMMCALL with not emulator...\n");
        return -1;
       }
       break;
     } 
-    
+#endif
 
 
   case VMEXIT_WBINVD: 
@@ -271,7 +351,7 @@ int handle_svm_exit(struct guest_info * info) {
 #ifdef DEBUG_EMULATOR
       PrintDebug("WBINVD\n");
 #endif
-      if (!handle_svm_wbinvd(info)) { 
+      if (!v3_handle_svm_wbinvd(info)) { 
        return -1;
       }
       break;
@@ -286,7 +366,7 @@ int handle_svm_exit(struct guest_info * info) {
   default: {
 
     addr_t rip_addr;
-    char buf[15];
+    uchar_t buf[15];
     addr_t host_addr;
 
     PrintDebug("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code));
@@ -294,11 +374,11 @@ int handle_svm_exit(struct guest_info * info) {
     rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
 
 
-    PrintError("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
-    PrintError("RIP: %x\n", guest_state->rip);
-    PrintError("RIP Linear: %x\n", rip_addr);
+    PrintError("SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data)); 
+    PrintError("RIP: %p\n", (void *)(addr_t)(guest_state->rip));
+    PrintError("RIP Linear: %p\n", (void *)(addr_t)(rip_addr));
     
-    PrintError("SVM Returned: Exit Code: %x\n", exit_code); 
+    PrintError("SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code); 
     
     PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
     PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
@@ -307,39 +387,6 @@ int handle_svm_exit(struct guest_info * info) {
     PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
 
     
-
-    if (info->mem_mode == PHYSICAL_MEM) {
-      if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
-       PrintError("Could not translate guest_state->rip to host address\n");
-       return -1;
-      }
-    } else if (info->mem_mode == VIRTUAL_MEM) {
-      if (guest_va_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
-       PrintError("Could not translate guest_state->rip to host address\n");
-       return -1;
-      }
-    } else {
-      PrintError("Invalid memory mode\n");
-      return -1;
-    }
-    
-    PrintError("Host Address of rip = 0x%x\n", host_addr);
-    
-    memset(buf, 0, 32);
-    
-    PrintError("Reading instruction stream in guest\n", rip_addr);
-    
-    if (info->mem_mode == PHYSICAL_MEM) {
-      read_guest_pa_memory(info, rip_addr-16, 32, buf);
-    } else {
-      read_guest_va_memory(info, rip_addr-16, 32, buf);
-    }
-    
-    PrintDebug("16 bytes before Rip\n");
-    PrintTraceMemDump(buf, 16);
-    PrintDebug("Rip onward\n");
-    PrintTraceMemDump(buf+16, 16);
-    
     return -1;
 
   }
@@ -349,14 +396,21 @@ int handle_svm_exit(struct guest_info * info) {
   // END OF SWITCH (EXIT_CODE)
 
 
+  if (info->enable_profiler) {
+    rdtscll(info->profiler.end_time);
+    v3_profile_exit(info, exit_code);
+  }
+      
+
+
   // Update the low level state
 
-  if (intr_pending(info)) {
+  if (v3_intr_pending(info)) {
 
-    switch (get_intr_type(info)) {
+    switch (v3_get_intr_type(info)) {
     case EXTERNAL_IRQ: 
       {
-       uint_t irq = get_intr_number(info);
+       uint_t irq = v3_get_intr_number(info);
 
         // check to see if ==-1 (non exists)
 
@@ -371,9 +425,11 @@ int handle_svm_exit(struct guest_info * info) {
        guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
        guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
 #ifdef DEBUG_INTERRUPTS
-       PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->guest_ctrl.V_INTR_VECTOR, info->rip);
+       PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
+                  guest_ctrl->guest_ctrl.V_INTR_VECTOR, 
+                  (void *)(addr_t)info->rip);
 #endif
-       injecting_intr(info, irq, EXTERNAL_IRQ);
+       v3_injecting_intr(info, irq, EXTERNAL_IRQ);
        
        break;
       }
@@ -382,7 +438,7 @@ int handle_svm_exit(struct guest_info * info) {
       break;
     case EXCEPTION:
       {
-       uint_t excp = get_intr_number(info);
+       uint_t excp = v3_get_intr_number(info);
 
        guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
        
@@ -398,9 +454,11 @@ int handle_svm_exit(struct guest_info * info) {
        
        guest_ctrl->EVENTINJ.valid = 1;
 #ifdef DEBUG_INTERRUPTS
-       PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->EVENTINJ.vector, info->rip);
+       PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
+                  guest_ctrl->EVENTINJ.vector, 
+                  (void *)(addr_t)info->rip);
 #endif
-       injecting_intr(info, excp, EXCEPTION);
+       v3_injecting_intr(info, excp, EXCEPTION);
        break;
       }
     case SOFTWARE_INTR:
@@ -449,9 +507,153 @@ int handle_svm_exit(struct guest_info * info) {
 }
 
 
-
-
-const uchar_t * vmexit_code_to_str(uint_t exit_code) {
+static const char VMEXIT_CR0_READ_STR[] = "VMEXIT_CR0_READ";
+static const char VMEXIT_CR1_READ_STR[] = "VMEXIT_CR1_READ";
+static const char VMEXIT_CR2_READ_STR[] = "VMEXIT_CR2_READ";
+static const char VMEXIT_CR3_READ_STR[] = "VMEXIT_CR3_READ";
+static const char VMEXIT_CR4_READ_STR[] = "VMEXIT_CR4_READ";
+static const char VMEXIT_CR5_READ_STR[] = "VMEXIT_CR5_READ";
+static const char VMEXIT_CR6_READ_STR[] = "VMEXIT_CR6_READ";
+static const char VMEXIT_CR7_READ_STR[] = "VMEXIT_CR7_READ";
+static const char VMEXIT_CR8_READ_STR[] = "VMEXIT_CR8_READ";
+static const char VMEXIT_CR9_READ_STR[] = "VMEXIT_CR9_READ";
+static const char VMEXIT_CR10_READ_STR[] = "VMEXIT_CR10_READ";
+static const char VMEXIT_CR11_READ_STR[] = "VMEXIT_CR11_READ";
+static const char VMEXIT_CR12_READ_STR[] = "VMEXIT_CR12_READ";
+static const char VMEXIT_CR13_READ_STR[] = "VMEXIT_CR13_READ";
+static const char VMEXIT_CR14_READ_STR[] = "VMEXIT_CR14_READ";
+static const char VMEXIT_CR15_READ_STR[] = "VMEXIT_CR15_READ";
+static const char VMEXIT_CR0_WRITE_STR[] = "VMEXIT_CR0_WRITE";
+static const char VMEXIT_CR1_WRITE_STR[] = "VMEXIT_CR1_WRITE";
+static const char VMEXIT_CR2_WRITE_STR[] = "VMEXIT_CR2_WRITE";
+static const char VMEXIT_CR3_WRITE_STR[] = "VMEXIT_CR3_WRITE";
+static const char VMEXIT_CR4_WRITE_STR[] = "VMEXIT_CR4_WRITE";
+static const char VMEXIT_CR5_WRITE_STR[] = "VMEXIT_CR5_WRITE";
+static const char VMEXIT_CR6_WRITE_STR[] = "VMEXIT_CR6_WRITE";
+static const char VMEXIT_CR7_WRITE_STR[] = "VMEXIT_CR7_WRITE";
+static const char VMEXIT_CR8_WRITE_STR[] = "VMEXIT_CR8_WRITE";
+static const char VMEXIT_CR9_WRITE_STR[] = "VMEXIT_CR9_WRITE";
+static const char VMEXIT_CR10_WRITE_STR[] = "VMEXIT_CR10_WRITE";
+static const char VMEXIT_CR11_WRITE_STR[] = "VMEXIT_CR11_WRITE";
+static const char VMEXIT_CR12_WRITE_STR[] = "VMEXIT_CR12_WRITE";
+static const char VMEXIT_CR13_WRITE_STR[] = "VMEXIT_CR13_WRITE";
+static const char VMEXIT_CR14_WRITE_STR[] = "VMEXIT_CR14_WRITE";
+static const char VMEXIT_CR15_WRITE_STR[] = "VMEXIT_CR15_WRITE";
+static const char VMEXIT_DR0_READ_STR[] = "VMEXIT_DR0_READ";
+static const char VMEXIT_DR1_READ_STR[] = "VMEXIT_DR1_READ";
+static const char VMEXIT_DR2_READ_STR[] = "VMEXIT_DR2_READ";
+static const char VMEXIT_DR3_READ_STR[] = "VMEXIT_DR3_READ";
+static const char VMEXIT_DR4_READ_STR[] = "VMEXIT_DR4_READ";
+static const char VMEXIT_DR5_READ_STR[] = "VMEXIT_DR5_READ";
+static const char VMEXIT_DR6_READ_STR[] = "VMEXIT_DR6_READ";
+static const char VMEXIT_DR7_READ_STR[] = "VMEXIT_DR7_READ";
+static const char VMEXIT_DR8_READ_STR[] = "VMEXIT_DR8_READ";
+static const char VMEXIT_DR9_READ_STR[] = "VMEXIT_DR9_READ";
+static const char VMEXIT_DR10_READ_STR[] = "VMEXIT_DR10_READ";
+static const char VMEXIT_DR11_READ_STR[] = "VMEXIT_DR11_READ";
+static const char VMEXIT_DR12_READ_STR[] = "VMEXIT_DR12_READ";
+static const char VMEXIT_DR13_READ_STR[] = "VMEXIT_DR13_READ";
+static const char VMEXIT_DR14_READ_STR[] = "VMEXIT_DR14_READ";
+static const char VMEXIT_DR15_READ_STR[] = "VMEXIT_DR15_READ";
+static const char VMEXIT_DR0_WRITE_STR[] = "VMEXIT_DR0_WRITE";
+static const char VMEXIT_DR1_WRITE_STR[] = "VMEXIT_DR1_WRITE";
+static const char VMEXIT_DR2_WRITE_STR[] = "VMEXIT_DR2_WRITE";
+static const char VMEXIT_DR3_WRITE_STR[] = "VMEXIT_DR3_WRITE";
+static const char VMEXIT_DR4_WRITE_STR[] = "VMEXIT_DR4_WRITE";
+static const char VMEXIT_DR5_WRITE_STR[] = "VMEXIT_DR5_WRITE";
+static const char VMEXIT_DR6_WRITE_STR[] = "VMEXIT_DR6_WRITE";
+static const char VMEXIT_DR7_WRITE_STR[] = "VMEXIT_DR7_WRITE";
+static const char VMEXIT_DR8_WRITE_STR[] = "VMEXIT_DR8_WRITE";
+static const char VMEXIT_DR9_WRITE_STR[] = "VMEXIT_DR9_WRITE";
+static const char VMEXIT_DR10_WRITE_STR[] = "VMEXIT_DR10_WRITE";
+static const char VMEXIT_DR11_WRITE_STR[] = "VMEXIT_DR11_WRITE";
+static const char VMEXIT_DR12_WRITE_STR[] = "VMEXIT_DR12_WRITE";
+static const char VMEXIT_DR13_WRITE_STR[] = "VMEXIT_DR13_WRITE";
+static const char VMEXIT_DR14_WRITE_STR[] = "VMEXIT_DR14_WRITE";
+static const char VMEXIT_DR15_WRITE_STR[] = "VMEXIT_DR15_WRITE";
+static const char VMEXIT_EXCP0_STR[] = "VMEXIT_EXCP0";
+static const char VMEXIT_EXCP1_STR[] = "VMEXIT_EXCP1";
+static const char VMEXIT_EXCP2_STR[] = "VMEXIT_EXCP2";
+static const char VMEXIT_EXCP3_STR[] = "VMEXIT_EXCP3";
+static const char VMEXIT_EXCP4_STR[] = "VMEXIT_EXCP4";
+static const char VMEXIT_EXCP5_STR[] = "VMEXIT_EXCP5";
+static const char VMEXIT_EXCP6_STR[] = "VMEXIT_EXCP6";
+static const char VMEXIT_EXCP7_STR[] = "VMEXIT_EXCP7";
+static const char VMEXIT_EXCP8_STR[] = "VMEXIT_EXCP8";
+static const char VMEXIT_EXCP9_STR[] = "VMEXIT_EXCP9";
+static const char VMEXIT_EXCP10_STR[] = "VMEXIT_EXCP10";
+static const char VMEXIT_EXCP11_STR[] = "VMEXIT_EXCP11";
+static const char VMEXIT_EXCP12_STR[] = "VMEXIT_EXCP12";
+static const char VMEXIT_EXCP13_STR[] = "VMEXIT_EXCP13";
+static const char VMEXIT_EXCP14_STR[] = "VMEXIT_EXCP14";
+static const char VMEXIT_EXCP15_STR[] = "VMEXIT_EXCP15";
+static const char VMEXIT_EXCP16_STR[] = "VMEXIT_EXCP16";
+static const char VMEXIT_EXCP17_STR[] = "VMEXIT_EXCP17";
+static const char VMEXIT_EXCP18_STR[] = "VMEXIT_EXCP18";
+static const char VMEXIT_EXCP19_STR[] = "VMEXIT_EXCP19";
+static const char VMEXIT_EXCP20_STR[] = "VMEXIT_EXCP20";
+static const char VMEXIT_EXCP21_STR[] = "VMEXIT_EXCP21";
+static const char VMEXIT_EXCP22_STR[] = "VMEXIT_EXCP22";
+static const char VMEXIT_EXCP23_STR[] = "VMEXIT_EXCP23";
+static const char VMEXIT_EXCP24_STR[] = "VMEXIT_EXCP24";
+static const char VMEXIT_EXCP25_STR[] = "VMEXIT_EXCP25";
+static const char VMEXIT_EXCP26_STR[] = "VMEXIT_EXCP26";
+static const char VMEXIT_EXCP27_STR[] = "VMEXIT_EXCP27";
+static const char VMEXIT_EXCP28_STR[] = "VMEXIT_EXCP28";
+static const char VMEXIT_EXCP29_STR[] = "VMEXIT_EXCP29";
+static const char VMEXIT_EXCP30_STR[] = "VMEXIT_EXCP30";
+static const char VMEXIT_EXCP31_STR[] = "VMEXIT_EXCP31";
+static const char VMEXIT_INTR_STR[] = "VMEXIT_INTR";
+static const char VMEXIT_NMI_STR[] = "VMEXIT_NMI";
+static const char VMEXIT_SMI_STR[] = "VMEXIT_SMI";
+static const char VMEXIT_INIT_STR[] = "VMEXIT_INIT";
+static const char VMEXIT_VINITR_STR[] = "VMEXIT_VINITR";
+static const char VMEXIT_CR0_SEL_WRITE_STR[] = "VMEXIT_CR0_SEL_WRITE";
+static const char VMEXIT_IDTR_READ_STR[] = "VMEXIT_IDTR_READ";
+static const char VMEXIT_GDTR_READ_STR[] = "VMEXIT_GDTR_READ";
+static const char VMEXIT_LDTR_READ_STR[] = "VMEXIT_LDTR_READ";
+static const char VMEXIT_TR_READ_STR[] = "VMEXIT_TR_READ";
+static const char VMEXIT_IDTR_WRITE_STR[] = "VMEXIT_IDTR_WRITE";
+static const char VMEXIT_GDTR_WRITE_STR[] = "VMEXIT_GDTR_WRITE";
+static const char VMEXIT_LDTR_WRITE_STR[] = "VMEXIT_LDTR_WRITE";
+static const char VMEXIT_TR_WRITE_STR[] = "VMEXIT_TR_WRITE";
+static const char VMEXIT_RDTSC_STR[] = "VMEXIT_RDTSC";
+static const char VMEXIT_RDPMC_STR[] = "VMEXIT_RDPMC";
+static const char VMEXIT_PUSHF_STR[] = "VMEXIT_PUSHF";
+static const char VMEXIT_POPF_STR[] = "VMEXIT_POPF";
+static const char VMEXIT_CPUID_STR[] = "VMEXIT_CPUID";
+static const char VMEXIT_RSM_STR[] = "VMEXIT_RSM";
+static const char VMEXIT_IRET_STR[] = "VMEXIT_IRET";
+static const char VMEXIT_SWINT_STR[] = "VMEXIT_SWINT";
+static const char VMEXIT_INVD_STR[] = "VMEXIT_INVD";
+static const char VMEXIT_PAUSE_STR[] = "VMEXIT_PAUSE";
+static const char VMEXIT_HLT_STR[] = "VMEXIT_HLT";
+static const char VMEXIT_INVLPG_STR[] = "VMEXIT_INVLPG";
+static const char VMEXIT_INVLPGA_STR[] = "VMEXIT_INVLPGA";
+static const char VMEXIT_IOIO_STR[] = "VMEXIT_IOIO";
+static const char VMEXIT_MSR_STR[] = "VMEXIT_MSR";
+static const char VMEXIT_TASK_SWITCH_STR[] = "VMEXIT_TASK_SWITCH";
+static const char VMEXIT_FERR_FREEZE_STR[] = "VMEXIT_FERR_FREEZE";
+static const char VMEXIT_SHUTDOWN_STR[] = "VMEXIT_SHUTDOWN";
+static const char VMEXIT_VMRUN_STR[] = "VMEXIT_VMRUN";
+static const char VMEXIT_VMMCALL_STR[] = "VMEXIT_VMMCALL";
+static const char VMEXIT_VMLOAD_STR[] = "VMEXIT_VMLOAD";
+static const char VMEXIT_VMSAVE_STR[] = "VMEXIT_VMSAVE";
+static const char VMEXIT_STGI_STR[] = "VMEXIT_STGI";
+static const char VMEXIT_CLGI_STR[] = "VMEXIT_CLGI";
+static const char VMEXIT_SKINIT_STR[] = "VMEXIT_SKINIT";
+static const char VMEXIT_RDTSCP_STR[] = "VMEXIT_RDTSCP";
+static const char VMEXIT_ICEBP_STR[] = "VMEXIT_ICEBP";
+static const char VMEXIT_WBINVD_STR[] = "VMEXIT_WBINVD";
+static const char VMEXIT_MONITOR_STR[] = "VMEXIT_MONITOR";
+static const char VMEXIT_MWAIT_STR[] = "VMEXIT_MWAIT";
+static const char VMEXIT_MWAIT_CONDITIONAL_STR[] = "VMEXIT_MWAIT_CONDITIONAL";
+static const char VMEXIT_NPF_STR[] = "VMEXIT_NPF";
+static const char VMEXIT_INVALID_VMCB_STR[] = "VMEXIT_INVALID_VMCB";
+
+
+
+const char * vmexit_code_to_str(uint_t exit_code) {
   switch(exit_code) {
   case VMEXIT_CR0_READ:
     return VMEXIT_CR0_READ_STR;