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.


rename exit codes to avoid namespace collisions
[palacios.git] / palacios / src / palacios / svm_handler.c
index bd99a44..5849055 100644 (file)
+/* 
+ * 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>
 #include <palacios/vmm_decoder.h>
 #include <palacios/vmm_ctrl_regs.h>
 #include <palacios/svm_io.h>
-#include <palacios/svm_halt.h>
+#include <palacios/vmm_halt.h>
 #include <palacios/svm_pause.h>
 #include <palacios/svm_wbinvd.h>
 #include <palacios/vmm_intr.h>
 #include <palacios/vmm_emulator.h>
+#include <palacios/svm_msr.h>
+#include <palacios/vmm_hypercall.h>
+#include <palacios/vmm_cpuid.h>
+#include <palacios/vmm_direct_paging.h>
+
+#ifndef V3_CONFIG_DEBUG_SVM
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
 
-int 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;
-  
-  guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
-  guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
-  
-
-  // Update the high level state 
-  info->rip = guest_state->rip;
-  info->vm_regs.rsp = guest_state->rsp;
-  info->vm_regs.rax = guest_state->rax;
-
-  info->cpl = guest_state->cpl;
-
-
-  info->ctrl_regs.cr0 = guest_state->cr0;
-  info->ctrl_regs.cr2 = guest_state->cr2;
-  info->ctrl_regs.cr3 = guest_state->cr3;
-  info->ctrl_regs.cr4 = guest_state->cr4;
-  info->dbg_regs.dr6 = guest_state->dr6;
-  info->dbg_regs.dr7 = guest_state->dr7;
-  info->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
-  info->ctrl_regs.rflags = guest_state->rflags;
-  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);
-
-
-  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))) {
-
+#ifdef V3_CONFIG_TELEMETRY
+#include <palacios/vmm_telemetry.h>
+#endif
 
-  //  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];
-    int ret;
-    // Dump out the instr stream
+#ifdef V3_CONFIG_EXT_SW_INTERRUPTS
+#include <gears/sw_intr.h>
+#endif
 
-    //PrintDebug("RIP: %x\n", guest_state->rip);
-    PrintDebug("RIP Linear: %x\n", get_addr_linear(info, info->rip, &(info->segments.cs)));
+int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_info1, addr_t exit_info2) {
 
-    // OK, now we will read the instruction
-    // The only difference between PROTECTED and PROTECTED_PG is whether we read
-    // from guest_pa or guest_va
-    if (info->mem_mode == PHYSICAL_MEM) { 
-      // The real rip address is actually a combination of the rip + CS base 
-      ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
-    } else { 
-      ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
+#ifdef V3_CONFIG_TELEMETRY
+    if (info->vm_info->enable_telemetry) {
+       v3_telemetry_start_exit(info);
     }
-    
-    if (ret != 32) {
-      // I think we should inject a GPF into the guest
-      PrintDebug("Could not read instruction (ret=%d)\n", ret);
-    } else {
+#endif
 
-      PrintDebug("Instr Stream:\n");
-      PrintTraceMemDump(instr, 32);
-    }
-  }
 
 
-    //  }
-  // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
+    //    PrintDebug("SVM Returned: Exit Code: %p\n", (void *)exit_code); 
 
+    switch (exit_code) {
+       case SVM_EXIT_IOIO: {
+           struct svm_io_info * io_info = (struct svm_io_info *)&(exit_info1);
 
-  // PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
-  //PrintDebug("RIP: %x\n", guest_state->rip);
+           if (io_info->type == 0) {
+               if (io_info->str) {
 
-  
-  //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
+                   if (v3_handle_svm_io_outs(info, io_info) == -1 ) {
+                       return -1;
+                   }
+               } else {
+                   if (v3_handle_svm_io_out(info, io_info) == -1) {
+                       return -1;
+                   }
+               }
 
-  switch (exit_code) {
+           } else {
 
-  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;
-       }
-      } else {
-       if (handle_svm_io_out(info) == -1) {
-         return -1;
-       }
-      }
-    } else {
-      if (io_info->str) {
-       if (handle_svm_io_ins(info) == -1) {
-         return -1;
-       }
-      } else {
-       if (handle_svm_io_in(info) == -1) {
-         return -1;
-       }
-      }
-    }
-  }
-    break;
+               if (io_info->str) {
+                   if (v3_handle_svm_io_ins(info, io_info) == -1) {
+                       return -1;
+                   }
+               } else {
+                   if (v3_handle_svm_io_in(info, io_info) == -1) {
+                       return -1;
+                   }
+               }
+           }
 
+           info->rip = exit_info2;
 
-  case  VMEXIT_CR0_WRITE: {
-#ifdef DEBUG_CTRL_REGS
-    PrintDebug("CR0 Write\n");
+           break;
+       }
+       case SVM_EXIT_MSR:
+
+           if (exit_info1 == 0) {
+               if (v3_handle_msr_read(info) == -1) {
+                   return -1;
+               }
+           } else if (exit_info1 == 1) {
+               if (v3_handle_msr_write(info) == -1) {
+                   return -1;
+               }
+           } else {
+               PrintError("Invalid MSR Operation\n");
+               return -1;
+           }
+               
+           break;
+
+       case SVM_EXIT_CPUID:
+           if (v3_handle_cpuid(info) == -1) {
+               PrintError("Error handling CPUID\n");
+               return -1;
+           }
+
+           break;
+       case SVM_EXIT_CR0_WRITE: 
+#ifdef V3_CONFIG_DEBUG_CTRL_REGS
+           PrintDebug("CR0 Write\n");
 #endif
-    if (handle_cr0_write(info) == -1) {
-      return -1;
-    }
-  } 
-    break;
-
-  case VMEXIT_CR0_READ: {
-#ifdef DEBUG_CTRL_REGS
-    PrintDebug("CR0 Read\n");
+           if (v3_handle_cr0_write(info) == -1) {
+               return -1;
+           }
+           break;
+       case SVM_EXIT_CR0_READ: 
+#ifdef V3_CONFIG_DEBUG_CTRL_REGS
+           PrintDebug("CR0 Read\n");
 #endif
-    if (handle_cr0_read(info) == -1) {
-      return -1;
-    }
-  } 
-    break;
-
-  case VMEXIT_CR3_WRITE: {
-#ifdef DEBUG_CTRL_REGS
-    PrintDebug("CR3 Write\n");
+           if (v3_handle_cr0_read(info) == -1) {
+               return -1;
+           }
+           break;
+       case SVM_EXIT_CR3_WRITE: 
+#ifdef V3_CONFIG_DEBUG_CTRL_REGS
+           PrintDebug("CR3 Write\n");
 #endif
-    if (handle_cr3_write(info) == -1) {
-      return -1;
-    }    
-  } 
-    break;
-
-  case  VMEXIT_CR3_READ: {
-#ifdef DEBUG_CTRL_REGS
-    PrintDebug("CR3 Read\n");
+           if (v3_handle_cr3_write(info) == -1) {
+               return -1;
+           }    
+
+           break;
+       case  SVM_EXIT_CR3_READ: 
+#ifdef V3_CONFIG_DEBUG_CTRL_REGS
+           PrintDebug("CR3 Read\n");
 #endif
-    if (handle_cr3_read(info) == -1) {
-      return -1;
-    }
-  }
-    break;
-
-  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);
+           if (v3_handle_cr3_read(info) == -1) {
+               return -1;
+           }
+           break;
+       case SVM_EXIT_CR4_WRITE: 
+#ifdef V3_CONFIG_DEBUG_CTRL_REGS
+           PrintDebug("CR4 Write\n");
 #endif
-    if (info->shdw_pg_mode == SHADOW_PAGING) {
-      if (handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
-       return -1;
-      }
-    } else {
-      PrintError("Page fault in un implemented paging mode\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) {
-#ifdef DEBUG_SHADOW_PAGING
-      PrintDebug("Invlpg\n");
+           if (v3_handle_cr4_write(info) == -1) {
+               return -1;
+           }    
+           break;
+       case  SVM_EXIT_CR4_READ: 
+#ifdef V3_CONFIG_DEBUG_CTRL_REGS
+           PrintDebug("CR4 Read\n");
 #endif
-      if (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;
-    }
-  } 
-    break;
-
-  case VMEXIT_PAUSE: {
-    PrintDebug("Guest paused\n");
-    if (handle_svm_pause(info) == -1) { 
-      return -1;
-    }
-  } 
-    break;
-
-  case VMEXIT_EXCP1: {
-#ifdef DEBUG_EMULATOR
-    PrintDebug("DEBUG EXCEPTION\n");
+           if (v3_handle_cr4_read(info) == -1) {
+               return -1;
+           }
+           break;
+       case SVM_EXIT_EXCP14: {
+           addr_t fault_addr = exit_info2;
+           pf_error_t * error_code = (pf_error_t *)&(exit_info1);
+#ifdef V3_CONFIG_DEBUG_SHADOW_PAGING
+           PrintDebug("PageFault at %p (error=%d)\n", 
+                      (void *)fault_addr, *(uint_t *)error_code);
 #endif
-    if (info->run_state == VM_EMULATING) {
-      if (v3_emulation_exit_handler(info) == -1) {
-       return -1;
-      }
-    } else {
-      PrintError("VMMCALL with not emulator...\n");
-      return -1;
-    }
-  } 
-    break;
-
-  case VMEXIT_VMMCALL: {
-#ifdef DEBUG_EMULATOR
-    PrintDebug("VMMCALL\n");
+           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;
+           }
+           break;
+       } 
+       case SVM_EXIT_NPF: {
+           addr_t fault_addr = exit_info2;
+           pf_error_t * error_code = (pf_error_t *)&(exit_info1);
+
+           if (info->shdw_pg_mode == NESTED_PAGING) {
+               if (v3_handle_nested_pagefault(info, fault_addr, *error_code) == -1) {
+                   return -1;
+               }
+           } else {
+               PrintError("Currently unhandled Nested Page Fault\n");
+               return -1;
+                   }
+           break;
+           }
+       case SVM_EXIT_INVLPG: 
+           if (info->shdw_pg_mode == SHADOW_PAGING) {
+#ifdef V3_CONFIG_DEBUG_SHADOW_PAGING
+               PrintDebug("Invlpg\n");
 #endif
-    if (info->run_state == VM_EMULATING) {
-      if (v3_emulation_exit_handler(info) == -1) {
-       return -1;
-      }
-    } else {
-      PrintError("VMMCALL with not emulator...\n");
-      return -1;
-    }
-    
-  } 
-    break;
-
-
-  case VMEXIT_WBINVD: {
-#ifdef DEBUG_EMULATOR
-    PrintDebug("WBINVD\n");
+               if (v3_handle_shadow_invlpg(info) == -1) {
+                   return -1;
+               }
+           }
+           break;    
+       case SVM_EXIT_VMMCALL: 
+           /* 
+            * Hypercall 
+            */
+
+           // VMMCALL is a 3 byte op
+           // We do this early because some hypercalls can change the rip...
+           info->rip += 3;         
+
+           if (v3_handle_hypercall(info) == -1) {
+               PrintError("Error handling Hypercall\n");
+               return -1;
+           }
+
+           break;      
+       case SVM_EXIT_NMI:
+           // handled by interrupt dispatcher
+           break;
+       case SVM_EXIT_INTR:
+           // handled by interrupt dispatch earlier
+           break;
+       case SVM_EXIT_SMI:
+           //   handle_svm_smi(info); // ignored for now
+           break;
+       case SVM_EXIT_HLT:
+#ifdef V3_CONFIG_DEBUG_HALT
+           PrintDebug("Guest halted\n");
 #endif
-    if (!handle_svm_wbinvd(info)) { 
-      return -1;
-    }
-  }
-    break;
-
-
-
-    /* Exits Following this line are NOT HANDLED */
-    /*=======================================================================*/
-
-  case VMEXIT_CR_READ_MASK:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR_READ_MASK\n"); 
-    goto unhandled_exit;
-    break;
-    
-  case VMEXIT_CR_WRITE_MASK:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR_WRITE_MASK\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR1_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR1_READ\n");
-    goto unhandled_exit;
-    break;
-     
-  case VMEXIT_CR1_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR1_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR2_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR2_READ\n");
-    goto unhandled_exit;
-    break;
-     
-  case VMEXIT_CR2_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR2_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR4_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR4_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR4_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR4_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR5_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR5_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR5_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR5_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR6_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR6_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR6_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR6_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR7_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR7_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR7_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR7_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR8_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR8_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR8_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR8_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR9_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR9_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR9_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR9_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR10_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR10_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR10_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR10_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR11_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR11_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR11_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR11_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR12_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR12_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR12_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR12_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR13_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR13_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR13_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR13_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR14_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR14_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR14_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR14_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR15_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR15_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR15_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR15_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-
-  case VMEXIT_DR_READ_MASK:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR_READ_MASK\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR_WRITE_MASK:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR_WRITE_MASK\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR0_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR0_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR0_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR0_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR1_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR1_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR1_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR1_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR2_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR2_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR2_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR2_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR3_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR3_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR3_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR3_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR4_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR4_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR4_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR4_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR5_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR5_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR5_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR5_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR6_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR6_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR6_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR6_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR7_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR7_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR7_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR7_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR8_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR8_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR8_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR8_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR9_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR9_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR9_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR9_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR10_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR10_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR10_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR10_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR11_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR11_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR11_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR11_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR12_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR12_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR12_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR12_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR13_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR13_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR13_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR13_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR14_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR14_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR14_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR14_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR15_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR15_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_DR15_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_DR15_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-    
-  case VMEXIT_EXCP_MASK:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP_MASK\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP0:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP0\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP2:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP2\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP3:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP3\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP4:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP4\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP5:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP5\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP6:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP6\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP7:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP7\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP8:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP8\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP9:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP9\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP10:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP10\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP11:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP11\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP12:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP12\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP13:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP13\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP15:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP15\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP16:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP16\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP17:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP17\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP18:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP18\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP19:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP19\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP20:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP20\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP21:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP21\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP22:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP22\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP23:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP23\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP24:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP24\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP25:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP25\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP26:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP26\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP27:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP27\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP28:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP28\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP29:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP29\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP30:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP30\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_EXCP31:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP31\n");
-    goto unhandled_exit;
-    break;
-
-    
-  case VMEXIT_NMI:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_NMI\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_INIT:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_INIT\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_VINITR:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_VINITR\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CR0_SEL_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CR0_SEL_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_IDTR_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_IDTR_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_IDTR_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_IDTR_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_GDTR_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_GDTR_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_GDTR_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_GDTR_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_LDTR_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_LDTR_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_LDTR_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_LDTR_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_TR_READ:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_TR_READ\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_TR_WRITE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_TR_WRITE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_RDTSC:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_RDTSC\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_RDPMC:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_RDPMC\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_PUSHF:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_PUSHF\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_POPF:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_POPF\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CPUID:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CPUID\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_RSM:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_RSM\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_IRET:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_IRET\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_SWINT:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_SWINT\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_INVD:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_INVD\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_INVLPGA:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_INVLPGA\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_TASK_SWITCH:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_TASK_SWITCH\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_FERR_FREEZE:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_FERR_FREEZE\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_SHUTDOWN:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_SHUTDOWN\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_VMRUN:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_VMRUN\n");
-    goto unhandled_exit;
-    break;
-
-
-  case VMEXIT_STGI:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_STGI\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_CLGI:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_CLGI\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_SKINIT:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_SKINIT\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_RDTSCP:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_RDTSCP\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_ICEBP:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_ICEBP\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_MONITOR:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_MONITOR\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_MWAIT:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_MWAIT\n");
-    goto unhandled_exit;
-    break;
-
-  case VMEXIT_MWAIT_CONDITIONAL:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_MWAIT_CONDITIONAL\n");
-    goto unhandled_exit;
-    break;
-
-    
-  case VMEXIT_INVALID_VMCB:
-    PrintDebug("Unhandled SVM Exit: VMEXIT_INVALID_VMCB\n");
-    goto unhandled_exit;
-    break;
-
-
-  unhandled_exit:
-
-  default: {
-  
-    addr_t rip_addr;
-    char buf[15];
-    addr_t host_addr;
-
-
-    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: Exit Code: %x\n",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));
-    
-    PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
-    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;
-
-  }
-    break;
-
-  }
-  // END OF SWITCH (EXIT_CODE)
-
-
-  // Update the low level state
-
-  if (intr_pending(info)) {
-
-    switch (get_intr_type(info)) {
-    case EXTERNAL_IRQ: 
-      {
-       uint_t irq = get_intr_number(info);
-
-        // check to see if ==-1 (non exists)
-
-       /*      
-         guest_ctrl->EVENTINJ.vector = irq;
-         guest_ctrl->EVENTINJ.valid = 1;
-         guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
-       */
-       
-       guest_ctrl->guest_ctrl.V_IRQ = 1;
-       guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
-       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);
+           if (v3_handle_halt(info) == -1) {
+               return -1;
+           }
+           break;
+       case SVM_EXIT_PAUSE:
+           //      PrintDebug("Guest paused\n");
+           if (v3_handle_svm_pause(info) == -1) { 
+               return -1;
+           }
+           break;
+       case SVM_EXIT_WBINVD:   
+#ifdef V3_CONFIG_DEBUG_EMULATOR
+           PrintDebug("WBINVD\n");
 #endif
-       injecting_intr(info, irq, EXTERNAL_IRQ);
-       
-       break;
-      }
-    case NMI:
-      guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
-      break;
-    case EXCEPTION:
-      {
-       uint_t excp = get_intr_number(info);
-
-       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
-       
-       if (info->intr_state.excp_error_code_valid) {  //PAD
-         guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
-         guest_ctrl->EVENTINJ.ev = 1;
-#ifdef DEBUG_INTERRUPTS
-         PrintDebug("Injecting error code %x\n", guest_ctrl->EVENTINJ.error_code);
+           if (v3_handle_svm_wbinvd(info) == -1) { 
+               return -1;
+           }
+           break;
+        case SVM_EXIT_RDTSC:
+#ifdef V3_CONFIG_DEBUG_TIME
+           PrintDebug("RDTSC/RDTSCP\n");
+#endif 
+           if (v3_handle_rdtsc(info) == -1) {
+               PrintError("Error Handling RDTSC instruction\n");
+               return -1;
+           }
+           break;
+        case SVM_EXIT_RDTSCP:
+#ifdef V3_CONFIG_DEBUG_TIME
+           PrintDebug("RDTSCP\n");
+#endif 
+           if (v3_handle_rdtscp(info) == -1) {
+               PrintError("Error Handling RDTSCP instruction\n");
+               return -1;
+           }
+           break;
+       case SVM_EXIT_SHUTDOWN:
+           PrintDebug("Guest-initiated shutdown\n");
+
+           info->vm_info->run_state = VM_STOPPED;
+
+           // Force exit on other cores
+
+           break;
+#ifdef V3_CONFIG_EXT_SW_INTERRUPTS
+    case SVM_EXIT_SWINT:
+#ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS
+        PrintDebug("Intercepted a software interrupt\n");
 #endif
-       }
-       
-       guest_ctrl->EVENTINJ.vector = excp;
-       
-       guest_ctrl->EVENTINJ.valid = 1;
-#ifdef DEBUG_INTERRUPTS
-       PrintDebug("Injecting Interrupt %d (EIP=%x)\n", guest_ctrl->EVENTINJ.vector, info->rip);
+        if (v3_handle_swintr(info) == -1) {
+            PrintError("Error handling software interrupt\n");
+            return -1;
+        }
+        break;
 #endif
-       injecting_intr(info, excp, EXCEPTION);
-       break;
-      }
-    case SOFTWARE_INTR:
-      guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
-      break;
-    case VIRTUAL_INTR:
-      guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
-      break;
 
-    case INVALID_INTR: 
-    default:
-      PrintError("Attempted to issue an invalid interrupt\n");
-      return -1;
+
+           /* Exits Following this line are NOT HANDLED */
+           /*=======================================================================*/
+           
+       default: {
+
+           addr_t rip_addr;
+           
+           PrintError("Unhandled SVM Exit: %s\n", v3_svm_exit_code_to_str(exit_code));
+           
+           rip_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
+           
+           
+           PrintError("SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data)); 
+           PrintError("RIP: %p\n", (void *)(addr_t)(info->rip));
+           PrintError("RIP Linear: %p\n", (void *)(addr_t)(rip_addr));
+           
+           PrintError("SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code); 
+           
+           PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(exit_info1));
+           PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uint8_t *)&(exit_info1)) + 4));
+           
+           PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(exit_info2));
+           PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uint8_t *)&(exit_info2)) + 4));
+           
+           
+           if (info->shdw_pg_mode == SHADOW_PAGING) {
+               //      PrintHostPageTables(info, info->ctrl_regs.cr3);
+               //PrintGuestPageTables(info, info->shdw_pg_state.guest_cr3);
+           }
+           
+           return -1;              
+       }
     }
+    // END OF SWITCH (EXIT_CODE)
 
-  } else {
-#ifdef DEBUG_INTERRUPTS
-    PrintDebug("No interrupts/exceptions pending\n");
+#ifdef V3_CONFIG_TELEMETRY
+    if (info->vm_info->enable_telemetry) {
+       v3_telemetry_end_exit(info, exit_code);
+    }
 #endif
-  }
-
-  guest_state->cr0 = info->ctrl_regs.cr0;
-  guest_state->cr2 = info->ctrl_regs.cr2;
-  guest_state->cr3 = info->ctrl_regs.cr3;
-  guest_state->cr4 = info->ctrl_regs.cr4;
-  guest_state->dr6 = info->dbg_regs.dr6;
-  guest_state->dr7 = info->dbg_regs.dr7;
-  guest_ctrl->guest_ctrl.V_TPR = info->ctrl_regs.cr8 & 0xff;
-  guest_state->rflags = info->ctrl_regs.rflags;
-  guest_state->efer = info->ctrl_regs.efer;
 
-  guest_state->cpl = info->cpl;
 
-  guest_state->rax = info->vm_regs.rax;
-  guest_state->rip = info->rip;
-  guest_state->rsp = info->vm_regs.rsp;
-
-
-  set_vmcb_segments((vmcb_t*)(info->vmm_data), &(info->segments));
+    if (exit_code == SVM_EXIT_INTR) {
+       //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
+    }
+    
+    return 0;
+}
 
-  if (exit_code == VMEXIT_INTR) {
-    //PrintDebug("INTR ret IP = %x\n", guest_state->rip);
-  }
 
-  return 0;
+static const char SVM_EXIT_CR0_READ_STR[] = "SVM_EXIT_CR0_READ";
+static const char SVM_EXIT_CR1_READ_STR[] = "SVM_EXIT_CR1_READ";
+static const char SVM_EXIT_CR2_READ_STR[] = "SVM_EXIT_CR2_READ";
+static const char SVM_EXIT_CR3_READ_STR[] = "SVM_EXIT_CR3_READ";
+static const char SVM_EXIT_CR4_READ_STR[] = "SVM_EXIT_CR4_READ";
+static const char SVM_EXIT_CR5_READ_STR[] = "SVM_EXIT_CR5_READ";
+static const char SVM_EXIT_CR6_READ_STR[] = "SVM_EXIT_CR6_READ";
+static const char SVM_EXIT_CR7_READ_STR[] = "SVM_EXIT_CR7_READ";
+static const char SVM_EXIT_CR8_READ_STR[] = "SVM_EXIT_CR8_READ";
+static const char SVM_EXIT_CR9_READ_STR[] = "SVM_EXIT_CR9_READ";
+static const char SVM_EXIT_CR10_READ_STR[] = "SVM_EXIT_CR10_READ";
+static const char SVM_EXIT_CR11_READ_STR[] = "SVM_EXIT_CR11_READ";
+static const char SVM_EXIT_CR12_READ_STR[] = "SVM_EXIT_CR12_READ";
+static const char SVM_EXIT_CR13_READ_STR[] = "SVM_EXIT_CR13_READ";
+static const char SVM_EXIT_CR14_READ_STR[] = "SVM_EXIT_CR14_READ";
+static const char SVM_EXIT_CR15_READ_STR[] = "SVM_EXIT_CR15_READ";
+static const char SVM_EXIT_CR0_WRITE_STR[] = "SVM_EXIT_CR0_WRITE";
+static const char SVM_EXIT_CR1_WRITE_STR[] = "SVM_EXIT_CR1_WRITE";
+static const char SVM_EXIT_CR2_WRITE_STR[] = "SVM_EXIT_CR2_WRITE";
+static const char SVM_EXIT_CR3_WRITE_STR[] = "SVM_EXIT_CR3_WRITE";
+static const char SVM_EXIT_CR4_WRITE_STR[] = "SVM_EXIT_CR4_WRITE";
+static const char SVM_EXIT_CR5_WRITE_STR[] = "SVM_EXIT_CR5_WRITE";
+static const char SVM_EXIT_CR6_WRITE_STR[] = "SVM_EXIT_CR6_WRITE";
+static const char SVM_EXIT_CR7_WRITE_STR[] = "SVM_EXIT_CR7_WRITE";
+static const char SVM_EXIT_CR8_WRITE_STR[] = "SVM_EXIT_CR8_WRITE";
+static const char SVM_EXIT_CR9_WRITE_STR[] = "SVM_EXIT_CR9_WRITE";
+static const char SVM_EXIT_CR10_WRITE_STR[] = "SVM_EXIT_CR10_WRITE";
+static const char SVM_EXIT_CR11_WRITE_STR[] = "SVM_EXIT_CR11_WRITE";
+static const char SVM_EXIT_CR12_WRITE_STR[] = "SVM_EXIT_CR12_WRITE";
+static const char SVM_EXIT_CR13_WRITE_STR[] = "SVM_EXIT_CR13_WRITE";
+static const char SVM_EXIT_CR14_WRITE_STR[] = "SVM_EXIT_CR14_WRITE";
+static const char SVM_EXIT_CR15_WRITE_STR[] = "SVM_EXIT_CR15_WRITE";
+static const char SVM_EXIT_DR0_READ_STR[] = "SVM_EXIT_DR0_READ";
+static const char SVM_EXIT_DR1_READ_STR[] = "SVM_EXIT_DR1_READ";
+static const char SVM_EXIT_DR2_READ_STR[] = "SVM_EXIT_DR2_READ";
+static const char SVM_EXIT_DR3_READ_STR[] = "SVM_EXIT_DR3_READ";
+static const char SVM_EXIT_DR4_READ_STR[] = "SVM_EXIT_DR4_READ";
+static const char SVM_EXIT_DR5_READ_STR[] = "SVM_EXIT_DR5_READ";
+static const char SVM_EXIT_DR6_READ_STR[] = "SVM_EXIT_DR6_READ";
+static const char SVM_EXIT_DR7_READ_STR[] = "SVM_EXIT_DR7_READ";
+static const char SVM_EXIT_DR8_READ_STR[] = "SVM_EXIT_DR8_READ";
+static const char SVM_EXIT_DR9_READ_STR[] = "SVM_EXIT_DR9_READ";
+static const char SVM_EXIT_DR10_READ_STR[] = "SVM_EXIT_DR10_READ";
+static const char SVM_EXIT_DR11_READ_STR[] = "SVM_EXIT_DR11_READ";
+static const char SVM_EXIT_DR12_READ_STR[] = "SVM_EXIT_DR12_READ";
+static const char SVM_EXIT_DR13_READ_STR[] = "SVM_EXIT_DR13_READ";
+static const char SVM_EXIT_DR14_READ_STR[] = "SVM_EXIT_DR14_READ";
+static const char SVM_EXIT_DR15_READ_STR[] = "SVM_EXIT_DR15_READ";
+static const char SVM_EXIT_DR0_WRITE_STR[] = "SVM_EXIT_DR0_WRITE";
+static const char SVM_EXIT_DR1_WRITE_STR[] = "SVM_EXIT_DR1_WRITE";
+static const char SVM_EXIT_DR2_WRITE_STR[] = "SVM_EXIT_DR2_WRITE";
+static const char SVM_EXIT_DR3_WRITE_STR[] = "SVM_EXIT_DR3_WRITE";
+static const char SVM_EXIT_DR4_WRITE_STR[] = "SVM_EXIT_DR4_WRITE";
+static const char SVM_EXIT_DR5_WRITE_STR[] = "SVM_EXIT_DR5_WRITE";
+static const char SVM_EXIT_DR6_WRITE_STR[] = "SVM_EXIT_DR6_WRITE";
+static const char SVM_EXIT_DR7_WRITE_STR[] = "SVM_EXIT_DR7_WRITE";
+static const char SVM_EXIT_DR8_WRITE_STR[] = "SVM_EXIT_DR8_WRITE";
+static const char SVM_EXIT_DR9_WRITE_STR[] = "SVM_EXIT_DR9_WRITE";
+static const char SVM_EXIT_DR10_WRITE_STR[] = "SVM_EXIT_DR10_WRITE";
+static const char SVM_EXIT_DR11_WRITE_STR[] = "SVM_EXIT_DR11_WRITE";
+static const char SVM_EXIT_DR12_WRITE_STR[] = "SVM_EXIT_DR12_WRITE";
+static const char SVM_EXIT_DR13_WRITE_STR[] = "SVM_EXIT_DR13_WRITE";
+static const char SVM_EXIT_DR14_WRITE_STR[] = "SVM_EXIT_DR14_WRITE";
+static const char SVM_EXIT_DR15_WRITE_STR[] = "SVM_EXIT_DR15_WRITE";
+static const char SVM_EXIT_EXCP0_STR[] = "SVM_EXIT_EXCP0";
+static const char SVM_EXIT_EXCP1_STR[] = "SVM_EXIT_EXCP1";
+static const char SVM_EXIT_EXCP2_STR[] = "SVM_EXIT_EXCP2";
+static const char SVM_EXIT_EXCP3_STR[] = "SVM_EXIT_EXCP3";
+static const char SVM_EXIT_EXCP4_STR[] = "SVM_EXIT_EXCP4";
+static const char SVM_EXIT_EXCP5_STR[] = "SVM_EXIT_EXCP5";
+static const char SVM_EXIT_EXCP6_STR[] = "SVM_EXIT_EXCP6";
+static const char SVM_EXIT_EXCP7_STR[] = "SVM_EXIT_EXCP7";
+static const char SVM_EXIT_EXCP8_STR[] = "SVM_EXIT_EXCP8";
+static const char SVM_EXIT_EXCP9_STR[] = "SVM_EXIT_EXCP9";
+static const char SVM_EXIT_EXCP10_STR[] = "SVM_EXIT_EXCP10";
+static const char SVM_EXIT_EXCP11_STR[] = "SVM_EXIT_EXCP11";
+static const char SVM_EXIT_EXCP12_STR[] = "SVM_EXIT_EXCP12";
+static const char SVM_EXIT_EXCP13_STR[] = "SVM_EXIT_EXCP13";
+static const char SVM_EXIT_EXCP14_STR[] = "SVM_EXIT_EXCP14";
+static const char SVM_EXIT_EXCP15_STR[] = "SVM_EXIT_EXCP15";
+static const char SVM_EXIT_EXCP16_STR[] = "SVM_EXIT_EXCP16";
+static const char SVM_EXIT_EXCP17_STR[] = "SVM_EXIT_EXCP17";
+static const char SVM_EXIT_EXCP18_STR[] = "SVM_EXIT_EXCP18";
+static const char SVM_EXIT_EXCP19_STR[] = "SVM_EXIT_EXCP19";
+static const char SVM_EXIT_EXCP20_STR[] = "SVM_EXIT_EXCP20";
+static const char SVM_EXIT_EXCP21_STR[] = "SVM_EXIT_EXCP21";
+static const char SVM_EXIT_EXCP22_STR[] = "SVM_EXIT_EXCP22";
+static const char SVM_EXIT_EXCP23_STR[] = "SVM_EXIT_EXCP23";
+static const char SVM_EXIT_EXCP24_STR[] = "SVM_EXIT_EXCP24";
+static const char SVM_EXIT_EXCP25_STR[] = "SVM_EXIT_EXCP25";
+static const char SVM_EXIT_EXCP26_STR[] = "SVM_EXIT_EXCP26";
+static const char SVM_EXIT_EXCP27_STR[] = "SVM_EXIT_EXCP27";
+static const char SVM_EXIT_EXCP28_STR[] = "SVM_EXIT_EXCP28";
+static const char SVM_EXIT_EXCP29_STR[] = "SVM_EXIT_EXCP29";
+static const char SVM_EXIT_EXCP30_STR[] = "SVM_EXIT_EXCP30";
+static const char SVM_EXIT_EXCP31_STR[] = "SVM_EXIT_EXCP31";
+static const char SVM_EXIT_INTR_STR[] = "SVM_EXIT_INTR";
+static const char SVM_EXIT_NMI_STR[] = "SVM_EXIT_NMI";
+static const char SVM_EXIT_SMI_STR[] = "SVM_EXIT_SMI";
+static const char SVM_EXIT_INIT_STR[] = "SVM_EXIT_INIT";
+static const char SVM_EXIT_VINITR_STR[] = "SVM_EXIT_VINITR";
+static const char SVM_EXIT_CR0_SEL_WRITE_STR[] = "SVM_EXIT_CR0_SEL_WRITE";
+static const char SVM_EXIT_IDTR_READ_STR[] = "SVM_EXIT_IDTR_READ";
+static const char SVM_EXIT_GDTR_READ_STR[] = "SVM_EXIT_GDTR_READ";
+static const char SVM_EXIT_LDTR_READ_STR[] = "SVM_EXIT_LDTR_READ";
+static const char SVM_EXIT_TR_READ_STR[] = "SVM_EXIT_TR_READ";
+static const char SVM_EXIT_IDTR_WRITE_STR[] = "SVM_EXIT_IDTR_WRITE";
+static const char SVM_EXIT_GDTR_WRITE_STR[] = "SVM_EXIT_GDTR_WRITE";
+static const char SVM_EXIT_LDTR_WRITE_STR[] = "SVM_EXIT_LDTR_WRITE";
+static const char SVM_EXIT_TR_WRITE_STR[] = "SVM_EXIT_TR_WRITE";
+static const char SVM_EXIT_RDTSC_STR[] = "SVM_EXIT_RDTSC";
+static const char SVM_EXIT_RDPMC_STR[] = "SVM_EXIT_RDPMC";
+static const char SVM_EXIT_PUSHF_STR[] = "SVM_EXIT_PUSHF";
+static const char SVM_EXIT_POPF_STR[] = "SVM_EXIT_POPF";
+static const char SVM_EXIT_CPUID_STR[] = "SVM_EXIT_CPUID";
+static const char SVM_EXIT_RSM_STR[] = "SVM_EXIT_RSM";
+static const char SVM_EXIT_IRET_STR[] = "SVM_EXIT_IRET";
+static const char SVM_EXIT_SWINT_STR[] = "SVM_EXIT_SWINT";
+static const char SVM_EXIT_INVD_STR[] = "SVM_EXIT_INVD";
+static const char SVM_EXIT_PAUSE_STR[] = "SVM_EXIT_PAUSE";
+static const char SVM_EXIT_HLT_STR[] = "SVM_EXIT_HLT";
+static const char SVM_EXIT_INVLPG_STR[] = "SVM_EXIT_INVLPG";
+static const char SVM_EXIT_INVLPGA_STR[] = "SVM_EXIT_INVLPGA";
+static const char SVM_EXIT_IOIO_STR[] = "SVM_EXIT_IOIO";
+static const char SVM_EXIT_MSR_STR[] = "SVM_EXIT_MSR";
+static const char SVM_EXIT_TASK_SWITCH_STR[] = "SVM_EXIT_TASK_SWITCH";
+static const char SVM_EXIT_FERR_FREEZE_STR[] = "SVM_EXIT_FERR_FREEZE";
+static const char SVM_EXIT_SHUTDOWN_STR[] = "SVM_EXIT_SHUTDOWN";
+static const char SVM_EXIT_VMRUN_STR[] = "SVM_EXIT_VMRUN";
+static const char SVM_EXIT_VMMCALL_STR[] = "SVM_EXIT_VMMCALL";
+static const char SVM_EXIT_VMLOAD_STR[] = "SVM_EXIT_VMLOAD";
+static const char SVM_EXIT_VMSAVE_STR[] = "SVM_EXIT_VMSAVE";
+static const char SVM_EXIT_STGI_STR[] = "SVM_EXIT_STGI";
+static const char SVM_EXIT_CLGI_STR[] = "SVM_EXIT_CLGI";
+static const char SVM_EXIT_SKINIT_STR[] = "SVM_EXIT_SKINIT";
+static const char SVM_EXIT_RDTSCP_STR[] = "SVM_EXIT_RDTSCP";
+static const char SVM_EXIT_ICEBP_STR[] = "SVM_EXIT_ICEBP";
+static const char SVM_EXIT_WBINVD_STR[] = "SVM_EXIT_WBINVD";
+static const char SVM_EXIT_MONITOR_STR[] = "SVM_EXIT_MONITOR";
+static const char SVM_EXIT_MWAIT_STR[] = "SVM_EXIT_MWAIT";
+static const char SVM_EXIT_MWAIT_CONDITIONAL_STR[] = "SVM_EXIT_MWAIT_CONDITIONAL";
+static const char SVM_EXIT_NPF_STR[] = "SVM_EXIT_NPF";
+static const char SVM_EXIT_INVALID_VMCB_STR[] = "SVM_EXIT_INVALID_VMCB";
+
+
+
+const char * v3_svm_exit_code_to_str(uint_t exit_code) {
+    switch(exit_code) {
+       case SVM_EXIT_CR0_READ:
+           return SVM_EXIT_CR0_READ_STR;
+       case SVM_EXIT_CR1_READ:
+           return SVM_EXIT_CR1_READ_STR;
+       case SVM_EXIT_CR2_READ:
+           return SVM_EXIT_CR2_READ_STR;
+       case SVM_EXIT_CR3_READ:
+           return SVM_EXIT_CR3_READ_STR;
+       case SVM_EXIT_CR4_READ:
+           return SVM_EXIT_CR4_READ_STR;
+       case SVM_EXIT_CR5_READ:
+           return SVM_EXIT_CR5_READ_STR;
+       case SVM_EXIT_CR6_READ:
+           return SVM_EXIT_CR6_READ_STR;
+       case SVM_EXIT_CR7_READ:
+           return SVM_EXIT_CR7_READ_STR;
+       case SVM_EXIT_CR8_READ:
+           return SVM_EXIT_CR8_READ_STR;
+       case SVM_EXIT_CR9_READ:
+           return SVM_EXIT_CR9_READ_STR;
+       case SVM_EXIT_CR10_READ:
+           return SVM_EXIT_CR10_READ_STR;
+       case SVM_EXIT_CR11_READ:
+           return SVM_EXIT_CR11_READ_STR;
+       case SVM_EXIT_CR12_READ:
+           return SVM_EXIT_CR12_READ_STR;
+       case SVM_EXIT_CR13_READ:
+           return SVM_EXIT_CR13_READ_STR;
+       case SVM_EXIT_CR14_READ:
+           return SVM_EXIT_CR14_READ_STR;
+       case SVM_EXIT_CR15_READ:
+           return SVM_EXIT_CR15_READ_STR;
+       case SVM_EXIT_CR0_WRITE:
+           return SVM_EXIT_CR0_WRITE_STR;
+       case SVM_EXIT_CR1_WRITE:
+           return SVM_EXIT_CR1_WRITE_STR;
+       case SVM_EXIT_CR2_WRITE:
+           return SVM_EXIT_CR2_WRITE_STR;
+       case SVM_EXIT_CR3_WRITE:
+           return SVM_EXIT_CR3_WRITE_STR;
+       case SVM_EXIT_CR4_WRITE:
+           return SVM_EXIT_CR4_WRITE_STR;
+       case SVM_EXIT_CR5_WRITE:
+           return SVM_EXIT_CR5_WRITE_STR;
+       case SVM_EXIT_CR6_WRITE:
+           return SVM_EXIT_CR6_WRITE_STR;
+       case SVM_EXIT_CR7_WRITE:
+           return SVM_EXIT_CR7_WRITE_STR;
+       case SVM_EXIT_CR8_WRITE:
+           return SVM_EXIT_CR8_WRITE_STR;
+       case SVM_EXIT_CR9_WRITE:
+           return SVM_EXIT_CR9_WRITE_STR;
+       case SVM_EXIT_CR10_WRITE:
+           return SVM_EXIT_CR10_WRITE_STR;
+       case SVM_EXIT_CR11_WRITE:
+           return SVM_EXIT_CR11_WRITE_STR;
+       case SVM_EXIT_CR12_WRITE:
+           return SVM_EXIT_CR12_WRITE_STR;
+       case SVM_EXIT_CR13_WRITE:
+           return SVM_EXIT_CR13_WRITE_STR;
+       case SVM_EXIT_CR14_WRITE:
+           return SVM_EXIT_CR14_WRITE_STR;
+       case SVM_EXIT_CR15_WRITE:
+           return SVM_EXIT_CR15_WRITE_STR;
+       case SVM_EXIT_DR0_READ:
+           return SVM_EXIT_DR0_READ_STR;
+       case SVM_EXIT_DR1_READ:
+           return SVM_EXIT_DR1_READ_STR;
+       case SVM_EXIT_DR2_READ:
+           return SVM_EXIT_DR2_READ_STR;
+       case SVM_EXIT_DR3_READ:
+           return SVM_EXIT_DR3_READ_STR;
+       case SVM_EXIT_DR4_READ:
+           return SVM_EXIT_DR4_READ_STR;
+       case SVM_EXIT_DR5_READ:
+           return SVM_EXIT_DR5_READ_STR;
+       case SVM_EXIT_DR6_READ:
+           return SVM_EXIT_DR6_READ_STR;
+       case SVM_EXIT_DR7_READ:
+           return SVM_EXIT_DR7_READ_STR;
+       case SVM_EXIT_DR8_READ:
+           return SVM_EXIT_DR8_READ_STR;
+       case SVM_EXIT_DR9_READ:
+           return SVM_EXIT_DR9_READ_STR;
+       case SVM_EXIT_DR10_READ:
+           return SVM_EXIT_DR10_READ_STR;
+       case SVM_EXIT_DR11_READ:
+           return SVM_EXIT_DR11_READ_STR;
+       case SVM_EXIT_DR12_READ:
+           return SVM_EXIT_DR12_READ_STR;
+       case SVM_EXIT_DR13_READ:
+           return SVM_EXIT_DR13_READ_STR;
+       case SVM_EXIT_DR14_READ:
+           return SVM_EXIT_DR14_READ_STR;
+       case SVM_EXIT_DR15_READ:
+           return SVM_EXIT_DR15_READ_STR;
+       case SVM_EXIT_DR0_WRITE:
+           return SVM_EXIT_DR0_WRITE_STR;
+       case SVM_EXIT_DR1_WRITE:
+           return SVM_EXIT_DR1_WRITE_STR;
+       case SVM_EXIT_DR2_WRITE:
+           return SVM_EXIT_DR2_WRITE_STR;
+       case SVM_EXIT_DR3_WRITE:
+           return SVM_EXIT_DR3_WRITE_STR;
+       case SVM_EXIT_DR4_WRITE:
+           return SVM_EXIT_DR4_WRITE_STR;
+       case SVM_EXIT_DR5_WRITE:
+           return SVM_EXIT_DR5_WRITE_STR;
+       case SVM_EXIT_DR6_WRITE:
+           return SVM_EXIT_DR6_WRITE_STR;
+       case SVM_EXIT_DR7_WRITE:
+           return SVM_EXIT_DR7_WRITE_STR;
+       case SVM_EXIT_DR8_WRITE:
+           return SVM_EXIT_DR8_WRITE_STR;
+       case SVM_EXIT_DR9_WRITE:
+           return SVM_EXIT_DR9_WRITE_STR;
+       case SVM_EXIT_DR10_WRITE:
+           return SVM_EXIT_DR10_WRITE_STR;
+       case SVM_EXIT_DR11_WRITE:
+           return SVM_EXIT_DR11_WRITE_STR;
+       case SVM_EXIT_DR12_WRITE:
+           return SVM_EXIT_DR12_WRITE_STR;
+       case SVM_EXIT_DR13_WRITE:
+           return SVM_EXIT_DR13_WRITE_STR;
+       case SVM_EXIT_DR14_WRITE:
+           return SVM_EXIT_DR14_WRITE_STR;
+       case SVM_EXIT_DR15_WRITE:
+           return SVM_EXIT_DR15_WRITE_STR;
+       case SVM_EXIT_EXCP0:
+           return SVM_EXIT_EXCP0_STR;
+       case SVM_EXIT_EXCP1:
+           return SVM_EXIT_EXCP1_STR;
+       case SVM_EXIT_EXCP2:
+           return SVM_EXIT_EXCP2_STR;
+       case SVM_EXIT_EXCP3:
+           return SVM_EXIT_EXCP3_STR;
+       case SVM_EXIT_EXCP4:
+           return SVM_EXIT_EXCP4_STR;
+       case SVM_EXIT_EXCP5:
+           return SVM_EXIT_EXCP5_STR;
+       case SVM_EXIT_EXCP6:
+           return SVM_EXIT_EXCP6_STR;
+       case SVM_EXIT_EXCP7:
+           return SVM_EXIT_EXCP7_STR;
+       case SVM_EXIT_EXCP8:
+           return SVM_EXIT_EXCP8_STR;
+       case SVM_EXIT_EXCP9:
+           return SVM_EXIT_EXCP9_STR;
+       case SVM_EXIT_EXCP10:
+           return SVM_EXIT_EXCP10_STR;
+       case SVM_EXIT_EXCP11:
+           return SVM_EXIT_EXCP11_STR;
+       case SVM_EXIT_EXCP12:
+           return SVM_EXIT_EXCP12_STR;
+       case SVM_EXIT_EXCP13:
+           return SVM_EXIT_EXCP13_STR;
+       case SVM_EXIT_EXCP14:
+           return SVM_EXIT_EXCP14_STR;
+       case SVM_EXIT_EXCP15:
+           return SVM_EXIT_EXCP15_STR;
+       case SVM_EXIT_EXCP16:
+           return SVM_EXIT_EXCP16_STR;
+       case SVM_EXIT_EXCP17:
+           return SVM_EXIT_EXCP17_STR;
+       case SVM_EXIT_EXCP18:
+           return SVM_EXIT_EXCP18_STR;
+       case SVM_EXIT_EXCP19:
+           return SVM_EXIT_EXCP19_STR;
+       case SVM_EXIT_EXCP20:
+           return SVM_EXIT_EXCP20_STR;
+       case SVM_EXIT_EXCP21:
+           return SVM_EXIT_EXCP21_STR;
+       case SVM_EXIT_EXCP22:
+           return SVM_EXIT_EXCP22_STR;
+       case SVM_EXIT_EXCP23:
+           return SVM_EXIT_EXCP23_STR;
+       case SVM_EXIT_EXCP24:
+           return SVM_EXIT_EXCP24_STR;
+       case SVM_EXIT_EXCP25:
+           return SVM_EXIT_EXCP25_STR;
+       case SVM_EXIT_EXCP26:
+           return SVM_EXIT_EXCP26_STR;
+       case SVM_EXIT_EXCP27:
+           return SVM_EXIT_EXCP27_STR;
+       case SVM_EXIT_EXCP28:
+           return SVM_EXIT_EXCP28_STR;
+       case SVM_EXIT_EXCP29:
+           return SVM_EXIT_EXCP29_STR;
+       case SVM_EXIT_EXCP30:
+           return SVM_EXIT_EXCP30_STR;
+       case SVM_EXIT_EXCP31:
+           return SVM_EXIT_EXCP31_STR;
+       case SVM_EXIT_INTR:
+           return SVM_EXIT_INTR_STR;
+       case SVM_EXIT_NMI:
+           return SVM_EXIT_NMI_STR;
+       case SVM_EXIT_SMI:
+           return SVM_EXIT_SMI_STR;
+       case SVM_EXIT_INIT:
+           return SVM_EXIT_INIT_STR;
+       case SVM_EXIT_VINITR:
+           return SVM_EXIT_VINITR_STR;
+       case SVM_EXIT_CR0_SEL_WRITE:
+           return SVM_EXIT_CR0_SEL_WRITE_STR;
+       case SVM_EXIT_IDTR_READ:
+           return SVM_EXIT_IDTR_READ_STR;
+       case SVM_EXIT_GDTR_READ:
+           return SVM_EXIT_GDTR_READ_STR;
+       case SVM_EXIT_LDTR_READ:
+           return SVM_EXIT_LDTR_READ_STR;
+       case SVM_EXIT_TR_READ:
+           return SVM_EXIT_TR_READ_STR;
+       case SVM_EXIT_IDTR_WRITE:
+           return SVM_EXIT_IDTR_WRITE_STR;
+       case SVM_EXIT_GDTR_WRITE:
+           return SVM_EXIT_GDTR_WRITE_STR;
+       case SVM_EXIT_LDTR_WRITE:
+           return SVM_EXIT_LDTR_WRITE_STR;
+       case SVM_EXIT_TR_WRITE:
+           return SVM_EXIT_TR_WRITE_STR;
+       case SVM_EXIT_RDTSC:
+           return SVM_EXIT_RDTSC_STR;
+       case SVM_EXIT_RDPMC:
+           return SVM_EXIT_RDPMC_STR;
+       case SVM_EXIT_PUSHF:
+           return SVM_EXIT_PUSHF_STR;
+       case SVM_EXIT_POPF:
+           return SVM_EXIT_POPF_STR;
+       case SVM_EXIT_CPUID:
+           return SVM_EXIT_CPUID_STR;
+       case SVM_EXIT_RSM:
+           return SVM_EXIT_RSM_STR;
+       case SVM_EXIT_IRET:
+           return SVM_EXIT_IRET_STR;
+       case SVM_EXIT_SWINT:
+           return SVM_EXIT_SWINT_STR;
+       case SVM_EXIT_INVD:
+           return SVM_EXIT_INVD_STR;
+       case SVM_EXIT_PAUSE:
+           return SVM_EXIT_PAUSE_STR;
+       case SVM_EXIT_HLT:
+           return SVM_EXIT_HLT_STR;
+       case SVM_EXIT_INVLPG:
+           return SVM_EXIT_INVLPG_STR;
+       case SVM_EXIT_INVLPGA:
+           return SVM_EXIT_INVLPGA_STR;
+       case SVM_EXIT_IOIO:
+           return SVM_EXIT_IOIO_STR;
+       case SVM_EXIT_MSR:
+           return SVM_EXIT_MSR_STR;
+       case SVM_EXIT_TASK_SWITCH:
+           return SVM_EXIT_TASK_SWITCH_STR;
+       case SVM_EXIT_FERR_FREEZE:
+           return SVM_EXIT_FERR_FREEZE_STR;
+       case SVM_EXIT_SHUTDOWN:
+           return SVM_EXIT_SHUTDOWN_STR;
+       case SVM_EXIT_VMRUN:
+           return SVM_EXIT_VMRUN_STR;
+       case SVM_EXIT_VMMCALL:
+           return SVM_EXIT_VMMCALL_STR;
+       case SVM_EXIT_VMLOAD:
+           return SVM_EXIT_VMLOAD_STR;
+       case SVM_EXIT_VMSAVE:
+           return SVM_EXIT_VMSAVE_STR;
+       case SVM_EXIT_STGI:
+           return SVM_EXIT_STGI_STR;
+       case SVM_EXIT_CLGI:
+           return SVM_EXIT_CLGI_STR;
+       case SVM_EXIT_SKINIT:
+           return SVM_EXIT_SKINIT_STR;
+       case SVM_EXIT_RDTSCP:
+           return SVM_EXIT_RDTSCP_STR;
+       case SVM_EXIT_ICEBP:
+           return SVM_EXIT_ICEBP_STR;
+       case SVM_EXIT_WBINVD:
+           return SVM_EXIT_WBINVD_STR;
+       case SVM_EXIT_MONITOR:
+           return SVM_EXIT_MONITOR_STR;
+       case SVM_EXIT_MWAIT:
+           return SVM_EXIT_MWAIT_STR;
+       case SVM_EXIT_MWAIT_CONDITIONAL:
+           return SVM_EXIT_MWAIT_CONDITIONAL_STR;
+       case SVM_EXIT_NPF:
+           return SVM_EXIT_NPF_STR;
+       case SVM_EXIT_INVALID_VMCB:
+           return SVM_EXIT_INVALID_VMCB_STR;
+    }
+    return NULL;
 }
-