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.


minor changes to organization
Kyle Hale [Fri, 17 Jun 2011 19:51:21 +0000 (14:51 -0500)]
17 files changed:
1  2 
Kconfig
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm_ctrl_regs.h
palacios/include/palacios/vmm_decoder.h
palacios/include/palacios/vmm_instr_decoder.h
palacios/src/extensions/Kconfig
palacios/src/extensions/Makefile
palacios/src/palacios/Makefile
palacios/src/palacios/svm.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/vm_guest.c
palacios/src/palacios/vm_guest_mem.c
palacios/src/palacios/vmm_ctrl_regs.c
palacios/src/palacios/vmm_decoder.c
palacios/src/palacios/vmm_intr.c
palacios/src/palacios/vmm_v3dec.c
palacios/src/palacios/vmm_xed.c

diff --combined Kconfig
+++ b/Kconfig
@@@ -163,66 -163,6 +163,15 @@@ config EXPERIMENTA
          The purpose of this option is to allow features under development to be committed to the mainline
          to more easily track changes and provide access to multiple developers
  
- config VNET
-         depends on EXPERIMENTAL
-         bool "Enable Vnet in Palacios"
-         default n
-         help
-           Enable the Vnet in Palacios
 +
 +config INSPECTOR
 +      bool "Enable VM inspection"
 +      depends on EXPERIMENTAL
 +      default n
 +      help 
 +        Enable inspection framework for vm internal state
 +
- config SW_INTERRUPTS
-     bool "Enable interception and hooking of software interrupts"
-     depends on EXPERIMENTAL
-     default n
-     help
-       This feature will cause the VMM to intercept the execution
-       of software interrupts (i.e. the INTn instruction) and enable
-       any INT vector to be hooked
- config SWINTR_PASSTHROUGH
-     bool "Hook all unhandled sofware interrupts for passthrough"
-     depends on SW_INTERRUPTS
-     default n
-     help
-       If enabled, this will cause all software interrupts 
-       (INT instruction vectors) to be hooked for passthrough.
-       May reduce performance but useful for debugging.
- config SYSCALL_HIJACK
-     bool "Enable System Call Hijacking"
-     depends on SW_INTERRUPTS
-     default n
-     help
-       Enable the VMM to hijack system calls executed by the guest.
-       If enabled, the VMM will hook execution of INT 80
-       (support for Fast-System Calls coming soon)
- config SYSCALL_PASSTHROUGH
-     bool "Hook all unhandled system calls for passthrough"
-     depends on SYSCALL_HIJACK
-     default n
-     help
-       If enabled, this option will cause all system calls
-       that are not explicitly hooked to be hooked for 
-       passthrough. This is useful for debugging.
- config HIJACK_SYSCALL_MSR
-     bool "Intercept Syscall-related MSR reads & writes"
-     depends on SYSCALL_HIJACK 
-     default n
-     help
-       Allow the VMM to intercept reads and writes to MSRs
-       related to SYSCALL and SYSENTER instructions. Specifically,
-       it will intercept R/W to STAR, CSTAR, and LSTAR.
 +
  endmenu
  
  
@@@ -336,7 -276,23 +285,23 @@@ menuconfig SYMMO
  
  endmenu
  
+ menu "VNET"
  
+ config VNET
+         bool "Enable Vnet in Palacios"
+         default n
+         help
+           Enable the Vnet in Palacios
+ config DEBUG_VNET
+         depends on VNET
+         bool "Enable Vnet Debug in Palacios"
+         default n
+         help
+           Enable the Vnet debug in Palacios
+ endmenu
  
  menu "Debug configuration"
  
@@@ -446,22 -402,6 +411,16 @@@ config DEBUG_DEV_MG
        help 
          This turns on debugging for the device manager
  
- config DEBUG_VNET
-         depends on EXPERIMENTAL && VNET
-         bool "Enable Vnet Debug in Palacios"
-         default n
-         help
-           Enable the Vnet debug in Palacios
 +
 +config DEBUG_SYSCALL_HIJACK
 +        bool "Enable Syscall Hijack Debug in Palacios"
 +        default n
 +        depends on DEBUG_ON && SYSCALL_HIJACK
 +        help
 +          Enable Debugging printouts for syscall hijacking
 +          code in Palacios
 +
 +
  endmenu
  
  
  
  
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
  #include <palacios/vmm_telemetry.h>
  #endif
  
  
- #ifdef CONFIG_SYMBIOTIC
+ #ifdef V3_CONFIG_SYMBIOTIC
  #include <palacios/vmm_symbiotic.h>
  struct v3_sym_core_state;
  #endif
  
- #ifdef CONFIG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_SYSCALL_HIJACK
 +#include <palacios/vmm_syscall_hijack.h>
 +#include <palacios/vmm_execve_hook.h>
 +#endif
 +
  
  
  #include <palacios/vmm_config.h>
@@@ -95,12 -90,6 +95,12 @@@ struct guest_info 
      /* This structure is how we get exceptions for the guest */
      struct v3_excp_state excp_state;
  
- #ifdef CONFIG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_SYSCALL_HIJACK
 +    struct v3_syscall_hook_map sc_hook_map;
 +    struct v3_execve_varchunk var_dump;
 +    struct v3_exec_hooks exec_hooks;
 +#endif
 +
  
      v3_cpu_mode_t cpu_mode;
      v3_mem_mode_t mem_mode;
      
      uint64_t num_exits;
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
      struct v3_core_telemetry core_telem;
  #endif
  
  
      void * decoder_state;
  
- #ifdef CONFIG_SYMBIOTIC
+ #ifdef V3_CONFIG_SYMBIOTIC
      /* Symbiotic state */
      struct v3_sym_core_state sym_core_state;
  #endif
      v3_core_operating_mode_t core_run_state;
  
      /* the logical cpu on which this core runs */
-     uint32_t cpu_id;
+     uint32_t pcpu_id;
+     
+     /* The virtual core # of this cpu (what the guest sees this core as) */
+     uint32_t vcpu_id;
       
  };
  
@@@ -156,8 -148,6 +159,6 @@@ struct v3_vm_info 
      uint32_t mem_align;
      struct v3_mem_map mem_map;
  
-     v3_paging_size_t paging_size; // for nested paging
      struct v3_mem_hooks mem_hooks;
  
      struct v3_shdw_impl_state shdw_impl;
  
      struct v3_extensions extensions;
  
- #ifdef CONFIG_SYMBIOTIC
+ #ifdef V3_CONFIG_SYMBIOTIC
      /* Symbiotic state */
      struct v3_sym_vm_state sym_vm_state;
  #endif
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
      uint_t enable_telemetry;
      struct v3_telemetry_state telemetry;
  #endif
  
  #define EFER_MSR                 0xc0000080
  
 +// KCH: for system-call interposition
- #define STAR_MSR                 0xc0000081
- #define LSTAR_MSR                0xc0000082
- #define CSTAR_MSR                0xc0000083
- #define SF_MASK_MSR              0xc0000084
- #define FS_BASE_MSR              0xc0000100
- #define GS_BASE_MSR              0xc0000101
- #define KERN_GS_BASE_MSR         0xc0000102
++#define STAR_MSR                 0xc0000081 /* Legacy mode SYSCALL target */
++#define LSTAR_MSR                0xc0000082 /* Long mode SYSCALL target */
++#define CSTAR_MSR                0xc0000083 /* compat mode SYSCALL target */
++#define SF_MASK_MSR              0xc0000084 /* EFLAGS mask for syscall */
++#define FS_BASE_MSR              0xc0000100 /* 64-bit FS base */
++#define GS_BASE_MSR              0xc0000101 /* 64-bit GS base */
++#define KERN_GS_BASE_MSR         0xc0000102 /* swapGS GS shadow */
++
++/* Intel specific */
++#define IA32_SYSENTER_CS_MSR     0x00000174
++#define IA32_SYSENTER_ESP_MSR    0x00000175
++#define IA32_SYSENTER_EIP_MSR    0x00000176
 +
  struct cr0_real {
      uint_t pe    : 1;
      uint_t mp    : 1;
@@@ -224,13 -215,6 +229,16 @@@ int v3_handle_cr4_read(struct guest_inf
  int v3_handle_efer_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data);
  int v3_handle_efer_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data);
  
 +int v3_handle_star_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data);
 +int v3_handle_star_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data);
 +int v3_handle_lstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data);
 +int v3_handle_lstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data);
 +int v3_handle_cstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data);
 +int v3_handle_cstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data);
 +
++int v3_handle_seeip_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data);
++int v3_handle_seeip_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data);
++
  int v3_handle_vm_cr_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data);
  int v3_handle_vm_cr_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data);
  
@@@ -34,7 -34,7 +34,7 @@@ typedef enum { V3_INVALID_OP
               V3_OP_SETB, V3_OP_SETBE, V3_OP_SETL, V3_OP_SETLE, V3_OP_SETNB, 
               V3_OP_SETNBE, V3_OP_SETNL, V3_OP_SETNLE, V3_OP_SETNO, V3_OP_SETNP,
               V3_OP_SETNS, V3_OP_SETNZ, V3_OP_SETO, V3_OP_SETP, V3_OP_SETS, 
 -             V3_OP_SETZ, V3_OP_MOVS, V3_OP_STOS, V3_OP_MOVZX, V3_OP_MOVSX } v3_op_type_t;
 +             V3_OP_SETZ, V3_OP_MOVS, V3_OP_STOS, V3_OP_MOVZX, V3_OP_MOVSX, V3_OP_INT } v3_op_type_t;
  
  
  typedef enum {INVALID_OPERAND, REG_OPERAND, MEM_OPERAND, IMM_OPERAND} v3_operand_type_t;
@@@ -48,30 -48,35 +48,35 @@@ struct x86_operand 
  } __attribute__((packed));
  
  struct x86_prefixes {
-     uint_t lock   : 1;  // 0xF0
-     uint_t repne  : 1;  // 0xF2
-     uint_t repnz  : 1;  // 0xF2
-     uint_t rep    : 1;  // 0xF3
-     uint_t repe   : 1;  // 0xF3
-     uint_t repz   : 1;  // 0xF3
-     uint_t cs_override : 1;  // 0x2E
-     uint_t ss_override : 1;  // 0x36
-     uint_t ds_override : 1;  // 0x3E
-     uint_t es_override : 1;  // 0x26
-     uint_t fs_override : 1;  // 0x64
-     uint_t gs_override : 1;  // 0x65
-     uint_t br_not_taken : 1;  // 0x2E
-     uint_t br_taken   : 1;  // 0x3E
-     uint_t op_size     : 1;  // 0x66
-     uint_t addr_size   : 1;  // 0x67
-     uint_t rex   : 1;
+     union {
+       uint32_t val;
+       
+       struct {
+           uint_t lock   : 1;  // 0xF0
+           uint_t repne  : 1;  // 0xF2
+           uint_t repnz  : 1;  // 0xF2
+           uint_t rep    : 1;  // 0xF3
+           uint_t repe   : 1;  // 0xF3
+           uint_t repz   : 1;  // 0xF3
+           uint_t cs_override : 1;  // 0x2E
+           uint_t ss_override : 1;  // 0x36
+           uint_t ds_override : 1;  // 0x3E
+           uint_t es_override : 1;  // 0x26
+           uint_t fs_override : 1;  // 0x64
+           uint_t gs_override : 1;  // 0x65
+           uint_t br_not_taken : 1;  // 0x2E
+           uint_t br_taken   : 1;  // 0x3E
+           uint_t op_size     : 1;  // 0x66
+           uint_t addr_size   : 1;  // 0x67
+           uint_t rex   : 1;
      
-     uint_t rex_rm        : 1;  // REX.B
-     uint_t rex_sib_idx   : 1;  // REX.X
-     uint_t rex_reg       : 1;  // REX.R
-     uint_t rex_op_size   : 1;  // REX.W
+           uint_t rex_rm        : 1;  // REX.B
+           uint_t rex_sib_idx   : 1;  // REX.X
+           uint_t rex_reg       : 1;  // REX.R
+           uint_t rex_op_size   : 1;  // REX.W
+       } __attribute__((packed));
+     } __attribute__((packed));
  } __attribute__((packed));
  
  
@@@ -19,7 -19,6 +19,6 @@@
  
  #include <palacios/vmm_types.h>
  
  /* .... Giant fucking switch tables */
  
  
@@@ -29,7 -28,6 +28,7 @@@ typedef enum 
      SMSW,
      CLTS,
      INVLPG,
 +    INT, // KCH: adding software interrupts
  
      MOV_CR2,
      MOV_2CR,
@@@ -263,6 -261,8 +262,8 @@@ static int get_operand_width(struct gue
                case LONG:
                    if (instr->prefixes.rex_op_size) {
                        return 8;
+                   } else {
+                       return 4;
                    }
                case PROTECTED:
                case PROTECTED_PAE:
                    return -1;
            }
  
 +    case INT: // KCH
        case MOV_DR2:
        case MOV_2DR:
        case MOV_CR2:
            return -1;
        
      }
      return 0;
  }
  
@@@ -452,7 -452,7 +454,7 @@@ static inline int decode_cr(struct gues
  
      struct v3_ctrl_regs * crs = &(core->ctrl_regs);
  
-     PrintDebug("\t Ctrl regs %d\n", reg_code);
+ //    PrintDebug("\t Ctrl regs %d\n", reg_code);
  
      switch (reg_code) {
        case 0:
@@@ -1336,10 -1336,7 +1338,10 @@@ static op_form_t op_code_to_form(uint8_
  
        case 0xf4:
            return HLT;
 -
 +    
 +    // KCH
 +    case 0xcd:
 +        return INT;
  
        case 0xf6: {
            struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
@@@ -1502,7 -1499,6 +1504,7 @@@ static char * op_form_to_str(op_form_t 
        case SETO: return "SETO";
        case STOS_8: return "STOS_8";
        case STOS: return "STOS";
 +    case INT: return "INT"; // KCH
  
        case INVALID_INSTR:
        default:
@@@ -38,4 -38,4 +38,48 @@@ config EXT_INSPECTO
        help
          Provides the inspection extension
  
++config SW_INTERRUPTS
++    bool "Enable interception and hooking of software interrupts"
++    default n
++    help
++      This feature will cause the VMM to intercept the execution
++      of software interrupts (i.e. the INTn instruction) and enable
++      any INT vector to be hooked
++
++config SWINTR_PASSTHROUGH
++    bool "Hook all unhandled sofware interrupts for passthrough"
++    depends on SW_INTERRUPTS
++    default n
++    help
++      If enabled, this will cause all software interrupts 
++      (INT instruction vectors) to be hooked for passthrough.
++      May reduce performance but useful for debugging.
++
++config SYSCALL_HIJACK
++    bool "Enable System Call Hijacking"
++    depends on SW_INTERRUPTS
++    default n
++    help
++      Enable the VMM to hijack system calls executed by the guest.
++      If enabled, the VMM will hook execution of INT 80
++      (support for Fast-System Calls coming soon)
++
++config SYSCALL_PASSTHROUGH
++    bool "Hook all unhandled system calls for passthrough"
++    depends on SYSCALL_HIJACK
++    default n
++    help
++      If enabled, this option will cause all system calls
++      that are not explicitly hooked to be hooked for 
++      passthrough. This is useful for debugging.
++
++config HIJACK_SYSCALL_MSR
++    bool "Intercept Syscall-related MSR reads & writes"
++    depends on SYSCALL_HIJACK 
++    default n
++    help
++      Allow the VMM to intercept reads and writes to MSRs
++      related to SYSCALL and SYSENTER instructions. Specifically,
++      it will intercept R/W to STAR, CSTAR, and LSTAR.
++
  endmenu
@@@ -1,5 -1,5 +1,11 @@@
  obj-y += null.o
- obj-$(CONFIG_EXT_MTRRS) += ext_mtrr.o
- obj-$(CONFIG_EXT_VTSC) += ext_vtsc.o
- obj-$(CONFIG_EXT_VTIME) += ext_vtime.o
- obj-$(CONFIG_EXT_INSPECTOR) += ext_inspector.o
+ obj-$(V3_CONFIG_EXT_MTRRS) += ext_mtrr.o
+ obj-$(V3_CONFIG_EXT_VTSC) += ext_vtsc.o
+ obj-$(V3_CONFIG_EXT_VTIME) += ext_vtime.o
+ obj-$(V3_CONFIG_EXT_INSPECTOR) += ext_inspector.o
++
++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_syscall_hijack.o 
++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_linux_syscall_map.o
++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_mpi_accel.o
++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_process_environment.o
++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_execve_hook.o
@@@ -32,7 -32,6 +32,6 @@@ obj-y := 
        vmm_cpuid.o \
        vmm_xml.o \
        vmm_mem_hook.o \
-       vmm_mptable.o \
        vmm_extensions.o \
        vmm_mtrr.o \
        vmm_multitree.o \
  
  
  
- obj-$(CONFIG_XED) +=  vmm_xed.o
- obj-$(CONFIG_V3_DECODER) += vmm_v3dec.o
+ obj-$(V3_CONFIG_XED) +=       vmm_xed.o
+ obj-$(V3_CONFIG_V3_DECODER) += vmm_v3dec.o
  
- obj-$(CONFIG_SVM) +=    svm.o \
-                       svm_io.o \
-                       svm_lowlevel.o \
-                       svm_msr.o \
-                       svm_pause.o \
-                       svm_wbinvd.o \
-                       svm_handler.o \
-                       vmcb.o
+ obj-$(V3_CONFIG_SVM) +=    svm.o \
+                          svm_io.o \
+                          svm_lowlevel.o \
+                          svm_msr.o \
+                          svm_pause.o \
+                          svm_wbinvd.o \
+                          svm_handler.o \
+                          vmcb.o
  
- obj-$(CONFIG_VMX) +=          vmx.o \
-                       vmx_handler.o \
-                       vmx_io.o \
-                       vmx_lowlevel.o \
-                       vmx_msr.o \
-                       vmx_hw_info.o \
-                       vmcs.o \
-                       vmx_ctrl_regs.o \
-                       vmx_assist.o
+ obj-$(V3_CONFIG_VMX) +=       vmx.o \
+                               vmx_handler.o \
+                               vmx_io.o \
+                               vmx_lowlevel.o \
+                               vmx_msr.o \
+                               vmx_hw_info.o \
+                               vmcs.o \
+                               vmx_ctrl_regs.o \
+                               vmx_assist.o \
+                               vmx_ept.o 
  
  
  
  
- obj-$(CONFIG_INSTRUMENT_VMM) += vmm_instrument.o
- obj-$(CONFIG_TELEMETRY) += vmm_telemetry.o 
+ obj-$(V3_CONFIG_TELEMETRY) += vmm_telemetry.o 
  
- obj-$(CONFIG_VNET) += vmm_vnet_core.o
- obj-$(CONFIG_SYMBIOTIC) += vmm_symbiotic.o vmm_symspy.o
- obj-$(CONFIG_SYMCALL) += vmm_symcall.o
- obj-$(CONFIG_SYMMOD) += vmm_symmod.o
- obj-$(CONFIG_SYSCALL_HIJACK) += vmm_syscall_hijack.o 
- obj-$(CONFIG_SYSCALL_HIJACK) += vmm_linux_syscall_map.o
- obj-$(CONFIG_SYSCALL_HIJACK) += vmm_mpi_accel.o
- obj-$(CONFIG_SYSCALL_HIJACK) += vmm_process_environment.o
- obj-$(CONFIG_SYSCALL_HIJACK) += vmm_execve_hook.o
+ obj-$(V3_CONFIG_SYMBIOTIC) += vmm_symbiotic.o vmm_symspy.o
+ obj-$(V3_CONFIG_SYMCALL) += vmm_symcall.o
+ obj-$(V3_CONFIG_SYMMOD) += vmm_symmod.o
  
 -
  obj-y += mmu/
@@@ -1,3 -1,4 +1,4 @@@
  /* 
   * This file is part of the Palacios Virtual Machine Monitor developed
   * by the V3VEE Project with funding from the United States National 
@@@ -44,7 -45,7 +45,7 @@@
  #include <palacios/vmm_sprintf.h>
  
  
- #ifndef CONFIG_DEBUG_SVM
+ #ifndef V3_CONFIG_DEBUG_SVM
  #undef PrintDebug
  #define PrintDebug(fmt, args...)
  #endif
@@@ -53,7 -54,7 +54,7 @@@
  uint32_t v3_last_exit;
  
  // This is a global pointer to the host's VMCB
- static addr_t host_vmcbs[CONFIG_MAX_CPUS] = { [0 ... CONFIG_MAX_CPUS - 1] = 0};
+ static addr_t host_vmcbs[V3_CONFIG_MAX_CPUS] = { [0 ... V3_CONFIG_MAX_CPUS - 1] = 0};
  
  
  
@@@ -105,7 -106,7 +106,7 @@@ static void Init_VMCB_BIOS(vmcb_t * vmc
  
      ctrl_area->instrs.HLT = 1;
  
- #ifdef CONFIG_TIME_VIRTUALIZE_TSC
+ #ifdef V3_CONFIG_TIME_VIRTUALIZE_TSC
      ctrl_area->instrs.RDTSC = 1;
      ctrl_area->svm_instrs.RDTSCP = 1;
  #endif
      ctrl_area->instrs.PAUSE = 1;
      ctrl_area->instrs.shutdown_evts = 1;
  
 +    /* KCH: intercept SW Interrupts (INT instr) */
- #ifdef CONFIG_SW_INTERRUPTS
++#ifdef V3_CONFIG_SW_INTERRUPTS
 +    ctrl_area->instrs.INTn = 1;
 +#endif
 +
  
      /* DEBUG FOR RETURN CODE */
      ctrl_area->exit_code = 1;
                &v3_handle_efer_write, 
                core);
  
- #ifdef CONFIG_HIJACK_MSR
-     /* KCH: for SYSCALL and SYSENTER interception */
++#ifdef V3_CONFIG_HIJACK_SYSCALL_MSR
++    /* KCH: we're not hooking these to TRAP them,
++            instead, we're going to catch the target EIP.
++            Hopefully this EIP is the entry point in the ELF located in the 
++            vsyscall page. We can inject checks into the code segment such that
++            we don't have to exit on uninteresting system calls. This should
++            give us much better performance than INT 80, and should even obviate
++            the need to deal with software interrupts at all */
 +    v3_hook_msr(core->vm_info, STAR_MSR,
 +        &v3_handle_star_read,
 +        &v3_handle_star_write,
 +        core);
 +    v3_hook_msr(core->vm_info, LSTAR_MSR,
 +        &v3_handle_lstar_read,
 +        &v3_handle_lstar_write,
 +        core);
 +    v3_hook_msr(core->vm_info, CSTAR_MSR,
 +        &v3_handle_cstar_read,
 +        &v3_handle_cstar_write,
 +        core);
++    
++    /* KCH: this probably isn't necessary, as
++        SYSENTER is only used in legacy mode. In fact,
++        in long mode it results in an illegal instruction
++        exception */
++    v3_hook_msr(core->vm_info, IA32_SYSENTER_EIP_MSR,
++        &v3_handle_seeip_read,
++        &v3_handle_seeip_write,
++        core);
 +#endif
 +
      if (core->shdw_pg_mode == SHADOW_PAGING) {
        PrintDebug("Creating initial shadow page table\n");
        
@@@ -347,7 -327,7 +363,7 @@@ static int update_irq_exit_state(struc
  
      if ((info->intr_core_state.irq_pending == 1) && (guest_ctrl->guest_ctrl.V_IRQ == 0)) {
        
- #ifdef CONFIG_DEBUG_INTERRUPTS
+ #ifdef V3_CONFIG_DEBUG_INTERRUPTS
        PrintDebug("INTAK cycle completed for irq %d\n", info->intr_core_state.irq_vector);
  #endif
  
      }
  
      if ((info->intr_core_state.irq_started == 1) && (guest_ctrl->exit_int_info.valid == 0)) {
- #ifdef CONFIG_DEBUG_INTERRUPTS
+ #ifdef V3_CONFIG_DEBUG_INTERRUPTS
        PrintDebug("Interrupt %d taken by guest\n", info->intr_core_state.irq_vector);
  #endif
  
        info->intr_core_state.irq_started = 0;
  
      } else if ((info->intr_core_state.irq_started == 1) && (guest_ctrl->exit_int_info.valid == 1)) {
- #ifdef CONFIG_DEBUG_INTERRUPTS
+ #ifdef V3_CONFIG_DEBUG_INTERRUPTS
        PrintDebug("EXIT INT INFO is set (vec=%d)\n", guest_ctrl->exit_int_info.vector);
  #endif
      }
@@@ -392,7 -372,7 +408,7 @@@ static int update_irq_entry_state(struc
        if (info->excp_state.excp_error_code_valid) {
            guest_ctrl->EVENTINJ.error_code = info->excp_state.excp_error_code;
            guest_ctrl->EVENTINJ.ev = 1;
- #ifdef CONFIG_DEBUG_INTERRUPTS
+ #ifdef V3_CONFIG_DEBUG_INTERRUPTS
            PrintDebug("Injecting exception %d with error code %x\n", excp, guest_ctrl->EVENTINJ.error_code);
  #endif
        }
        
        guest_ctrl->EVENTINJ.valid = 1;
  
- #ifdef CONFIG_DEBUG_INTERRUPTS
+ #ifdef V3_CONFIG_DEBUG_INTERRUPTS
        PrintDebug("<%d> Injecting Exception %d (CR2=%p) (EIP=%p)\n", 
                   (int)info->num_exits, 
                   guest_ctrl->EVENTINJ.vector, 
  
        v3_injecting_excp(info, excp);
      } else if (info->intr_core_state.irq_started == 1) {
- #ifdef CONFIG_DEBUG_INTERRUPTS
+ #ifdef V3_CONFIG_DEBUG_INTERRUPTS
        PrintDebug("IRQ pending from previous injection\n");
  #endif
        guest_ctrl->guest_ctrl.V_IRQ = 1;
                guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
                guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
  
- #ifdef CONFIG_DEBUG_INTERRUPTS
+ #ifdef V3_CONFIG_DEBUG_INTERRUPTS
                PrintDebug("Injecting Interrupt %d (EIP=%p)\n", 
                           guest_ctrl->guest_ctrl.V_INTR_VECTOR, 
                           (void *)(addr_t)info->rip);
            case V3_NMI:
                guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
                break;
 -          case V3_SOFTWARE_INTR:
 -              guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
 -              break;
 +          case V3_SOFTWARE_INTR: {
 +#ifdef CONFIG_DEBUG_INTERRUPTS
 +            PrintDebug("Caught an injected software interrupt\n");
 +            PrintDebug("\ttype: %d, vector: %d\n", SVM_INJECTION_SOFT_INTR, info->intr_core_state.swintr_vector);
 +#endif
 +            guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
 +            guest_ctrl->EVENTINJ.vector = info->intr_core_state.swintr_vector;
 +            guest_ctrl->EVENTINJ.valid = 1;
 +            
 +            /* reset the software interrupt state. 
 +                we can do this because we know only one
 +                sw int can be posted at a time on a given 
 +                core, unlike irqs */
 +            info->intr_core_state.swintr_posted = 0;
 +            info->intr_core_state.swintr_vector = 0;
 +            break;
 +        }
            case V3_VIRTUAL_IRQ:
                guest_ctrl->EVENTINJ.type = SVM_INJECTION_IRQ;
                break;
@@@ -519,7 -485,7 +535,7 @@@ int v3_svm_enter(struct guest_info * in
      guest_state->rip = info->rip;
      guest_state->rsp = info->vm_regs.rsp;
  
- #ifdef CONFIG_SYMCALL
+ #ifdef V3_CONFIG_SYMCALL
      if (info->sym_core_state.symcall_state.sym_call_active == 0) {
        update_irq_entry_state(info);
      }
        (void *)(addr_t)info->rip);
      */
  
- #ifdef CONFIG_SYMCALL
+ #ifdef V3_CONFIG_SYMCALL
      if (info->sym_core_state.symcall_state.sym_call_active == 1) {
        if (guest_ctrl->guest_ctrl.V_IRQ == 1) {
            V3_Print("!!! Injecting Interrupt during Sym call !!!\n");
      exit_info2 = guest_ctrl->exit_info2;
  
  
- #ifdef CONFIG_SYMCALL
+ #ifdef V3_CONFIG_SYMCALL
      if (info->sym_core_state.symcall_state.sym_call_active == 0) {
        update_irq_exit_state(info);
      }
@@@ -622,29 -588,31 +638,31 @@@ int v3_start_svm_guest(struct guest_inf
      //    vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
      //  vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
  
-     PrintDebug("Starting SVM core %u\n", info->cpu_id);
+     PrintDebug("Starting SVM core %u (on logical core %u)\n", info->vcpu_id, info->pcpu_id);
  
-     if (info->cpu_id == 0) {
+     if (info->vcpu_id == 0) {
        info->core_run_state = CORE_RUNNING;
        info->vm_info->run_state = VM_RUNNING;
      } else  { 
-       PrintDebug("SVM core %u: Waiting for core initialization\n", info->cpu_id);
+       PrintDebug("SVM core %u (on %u): Waiting for core initialization\n", info->vcpu_id, info->pcpu_id);
  
        while (info->core_run_state == CORE_STOPPED) {
            v3_yield(info);
-           //PrintDebug("SVM core %u: still waiting for INIT\n",info->cpu_id);
+           //PrintDebug("SVM core %u: still waiting for INIT\n", info->vcpu_id);
        }
  
-       PrintDebug("SVM core %u initialized\n", info->cpu_id);
+       PrintDebug("SVM core %u(on %u) initialized\n", info->vcpu_id, info->pcpu_id);
      } 
  
-     PrintDebug("SVM core %u: I am starting at CS=0x%x (base=0x%p, limit=0x%x),  RIP=0x%p\n", 
-              info->cpu_id, info->segments.cs.selector, (void *)(info->segments.cs.base), 
+     PrintDebug("SVM core %u(on %u): I am starting at CS=0x%x (base=0x%p, limit=0x%x),  RIP=0x%p\n", 
+              info->vcpu_id, info->pcpu_id, 
+              info->segments.cs.selector, (void *)(info->segments.cs.base), 
               info->segments.cs.limit, (void *)(info->rip));
  
  
  
-     PrintDebug("SVM core %u: Launching SVM VM (vmcb=%p)\n", info->cpu_id, (void *)info->vmm_data);
+     PrintDebug("SVM core %u: Launching SVM VM (vmcb=%p) (on cpu %u)\n", 
+              info->vcpu_id, (void *)info->vmm_data, info->pcpu_id);
      //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
      
      v3_start_time(info);
            
            info->vm_info->run_state = VM_ERROR;
            
-           V3_Print("SVM core %u: SVM ERROR!!\n", info->cpu_id); 
+           V3_Print("SVM core %u: SVM ERROR!!\n", info->vcpu_id); 
            
            v3_print_guest_state(info);
            
-           V3_Print("SVM core %u: SVM Exit Code: %p\n", info->cpu_id, (void *)(addr_t)guest_ctrl->exit_code); 
+           V3_Print("SVM core %u: SVM Exit Code: %p\n", info->vcpu_id, (void *)(addr_t)guest_ctrl->exit_code); 
            
-           V3_Print("SVM core %u: exit_info1 low = 0x%.8x\n", info->cpu_id, *(uint_t*)&(guest_ctrl->exit_info1));
-           V3_Print("SVM core %u: exit_info1 high = 0x%.8x\n", info->cpu_id, *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
+           V3_Print("SVM core %u: exit_info1 low = 0x%.8x\n", info->vcpu_id, *(uint_t*)&(guest_ctrl->exit_info1));
+           V3_Print("SVM core %u: exit_info1 high = 0x%.8x\n", info->vcpu_id, *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
            
-           V3_Print("SVM core %u: exit_info2 low = 0x%.8x\n", info->cpu_id, *(uint_t*)&(guest_ctrl->exit_info2));
-           V3_Print("SVM core %u: exit_info2 high = 0x%.8x\n", info->cpu_id, *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
+           V3_Print("SVM core %u: exit_info2 low = 0x%.8x\n", info->vcpu_id, *(uint_t*)&(guest_ctrl->exit_info2));
+           V3_Print("SVM core %u: exit_info2 high = 0x%.8x\n", info->vcpu_id, *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
            
            linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
            
                v3_gva_to_hva(info, linear_addr, &host_addr);
            }
            
-           V3_Print("SVM core %u: Host Address of rip = 0x%p\n", info->cpu_id, (void *)host_addr);
+           V3_Print("SVM core %u: Host Address of rip = 0x%p\n", info->vcpu_id, (void *)host_addr);
            
-           V3_Print("SVM core %u: Instr (15 bytes) at %p:\n", info->cpu_id, (void *)host_addr);
+           V3_Print("SVM core %u: Instr (15 bytes) at %p:\n", info->vcpu_id, (void *)host_addr);
            v3_dump_mem((uint8_t *)host_addr, 15);
            
            v3_print_stack(info);
        }
  
        
  /*
-       if ((info->num_exits % 5000) == 0) {
+       if ((info->num_exits % 50000) == 0) {
            V3_Print("SVM Exit number %d\n", (uint32_t)info->num_exits);
+           v3_print_guest_state(info);
        }
  */
        
  
  
  
+ int v3_reset_svm_vm_core(struct guest_info * core, addr_t rip) {
+     // init vmcb_bios
+     // Write the RIP, CS, and descriptor
+     // assume the rest is already good to go
+     //
+     // vector VV -> rip at 0
+     //              CS = VV00
+     //  This means we start executing at linear address VV000
+     //
+     // So the selector needs to be VV00
+     // and the base needs to be VV000
+     //
+     core->rip = 0;
+     core->segments.cs.selector = rip << 8;
+     core->segments.cs.limit = 0xffff;
+     core->segments.cs.base = rip << 12;
+     return 0;
+ }
  
  /* Checks machine SVM capability */
  /* Implemented from: AMD Arch Manual 3, sect 15.4 */ 
@@@ -780,6 -775,7 +825,7 @@@ static int has_svm_nested_paging() 
  }
  
  
  void v3_init_svm_cpu(int cpu_id) {
      reg_ex_t msr;
      extern v3_cpu_arch_t v3_cpu_types[];
  #include <palacios/vmm_hypercall.h>
  #include <palacios/vmm_cpuid.h>
  #include <palacios/vmm_direct_paging.h>
 +#include <palacios/vmm_syscall_hijack.h>
  
- #ifndef CONFIG_DEBUG_SVM
+ #ifndef V3_CONFIG_DEBUG_SVM
  #undef PrintDebug
  #define PrintDebug(fmt, args...)
  #endif
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
  #include <palacios/vmm_telemetry.h>
  #endif
  
@@@ -48,7 -47,7 +48,7 @@@
  
  int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_info1, addr_t exit_info2) {
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
      if (info->vm_info->enable_telemetry) {
        v3_telemetry_start_exit(info);
      }
  
            break;
        case VMEXIT_CR0_WRITE: 
- #ifdef CONFIG_DEBUG_CTRL_REGS
+ #ifdef V3_CONFIG_DEBUG_CTRL_REGS
            PrintDebug("CR0 Write\n");
  #endif
            if (v3_handle_cr0_write(info) == -1) {
            }
            break;
        case VMEXIT_CR0_READ: 
- #ifdef CONFIG_DEBUG_CTRL_REGS
+ #ifdef V3_CONFIG_DEBUG_CTRL_REGS
            PrintDebug("CR0 Read\n");
  #endif
            if (v3_handle_cr0_read(info) == -1) {
            }
            break;
        case VMEXIT_CR3_WRITE: 
- #ifdef CONFIG_DEBUG_CTRL_REGS
+ #ifdef V3_CONFIG_DEBUG_CTRL_REGS
            PrintDebug("CR3 Write\n");
  #endif
            if (v3_handle_cr3_write(info) == -1) {
  
            break;
        case  VMEXIT_CR3_READ: 
- #ifdef CONFIG_DEBUG_CTRL_REGS
+ #ifdef V3_CONFIG_DEBUG_CTRL_REGS
            PrintDebug("CR3 Read\n");
  #endif
            if (v3_handle_cr3_read(info) == -1) {
            }
            break;
        case VMEXIT_CR4_WRITE: 
- #ifdef CONFIG_DEBUG_CTRL_REGS
+ #ifdef V3_CONFIG_DEBUG_CTRL_REGS
            PrintDebug("CR4 Write\n");
  #endif
            if (v3_handle_cr4_write(info) == -1) {
            }    
            break;
        case  VMEXIT_CR4_READ: 
- #ifdef CONFIG_DEBUG_CTRL_REGS
+ #ifdef V3_CONFIG_DEBUG_CTRL_REGS
            PrintDebug("CR4 Read\n");
  #endif
            if (v3_handle_cr4_read(info) == -1) {
        case VMEXIT_EXCP14: {
            addr_t fault_addr = exit_info2;
            pf_error_t * error_code = (pf_error_t *)&(exit_info1);
- #ifdef CONFIG_DEBUG_SHADOW_PAGING
+ #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING
            PrintDebug("PageFault at %p (error=%d)\n", 
                       (void *)fault_addr, *(uint_t *)error_code);
  #endif
                    }
            break;
            }
 +    case VMEXIT_SWINT:
 +#ifdef CONFIG_DEBUG_INTERRUPTS
 +        PrintDebug("Intercepted SW Interrupt\n");
 +#endif
 +        if (v3_handle_swintr(info) == -1) {
 +            PrintError("Error handling software interrupt\n");
 +            return -1;
 +        }
 +        break;
        case VMEXIT_INVLPG: 
            if (info->shdw_pg_mode == SHADOW_PAGING) {
- #ifdef CONFIG_DEBUG_SHADOW_PAGING
+ #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING
                PrintDebug("Invlpg\n");
  #endif
                if (v3_handle_shadow_invlpg(info) == -1) {
                return -1;
            }
  
-           break;          
+           break;      
+       case VMEXIT_NMI:
+           // handled by interrupt dispatcher
+           break;
        case VMEXIT_INTR:
            // handled by interrupt dispatch earlier
            break;
            //   handle_svm_smi(info); // ignored for now
            break;
        case VMEXIT_HLT:
- #ifdef CONFIG_DEBUG_HALT
+ #ifdef V3_CONFIG_DEBUG_HALT
            PrintDebug("Guest halted\n");
  #endif
            if (v3_handle_halt(info) == -1) {
            }
            break;
        case VMEXIT_WBINVD:   
- #ifdef CONFIG_DEBUG_EMULATOR
+ #ifdef V3_CONFIG_DEBUG_EMULATOR
            PrintDebug("WBINVD\n");
  #endif
            if (v3_handle_svm_wbinvd(info) == -1) { 
            }
            break;
          case VMEXIT_RDTSC:
- #ifdef CONFIG_DEBUG_TIME
+ #ifdef V3_CONFIG_DEBUG_TIME
            PrintDebug("RDTSC/RDTSCP\n");
  #endif 
            if (v3_handle_rdtsc(info) == -1) {
            }
            break;
          case VMEXIT_RDTSCP:
- #ifdef CONFIG_DEBUG_TIME
+ #ifdef V3_CONFIG_DEBUG_TIME
            PrintDebug("RDTSCP\n");
  #endif 
            if (v3_handle_rdtscp(info) == -1) {
      }
      // END OF SWITCH (EXIT_CODE)
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
      if (info->vm_info->enable_telemetry) {
        v3_telemetry_end_exit(info, exit_code);
      }
  #include <palacios/vmm_xed.h>
  #include <palacios/vmm_direct_paging.h>
  
- #ifdef CONFIG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_SYSCALL_HIJACK
 +#include <palacios/vmm_syscall_hijack.h>
 +#include <palacios/vmm_mpi_accel.h>
 +#endif
 +
  
  
  v3_cpu_mode_t v3_get_vm_cpu_mode(struct guest_info * info) {
@@@ -492,14 -487,14 +492,14 @@@ static int info_hcall(struct guest_inf
      v3_print_guest_state(core);
      
      // init SVM/VMX
- #ifdef CONFIG_SVM
+ #ifdef V3_CONFIG_SVM
      if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) {
        cpu_valid = 1;
        PrintDebugVMCB((vmcb_t *)(core->vmm_data));
      }
  #endif
- #ifdef CONFIG_VMX
-     if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) {
+ #ifdef V3_CONFIG_VMX
+     if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU) || (cpu_type == V3_VMX_EPT_UG_CPU)) {
        cpu_valid = 1;
        v3_print_vmcs();
      }
  }
  
  
- #ifdef CONFIG_SVM
+ #ifdef V3_CONFIG_SVM
  #include <palacios/svm.h>
  #include <palacios/svm_io.h>
  #include <palacios/svm_msr.h>
  #endif
  
- #ifdef CONFIG_VMX
+ #ifdef V3_CONFIG_VMX
  #include <palacios/vmx.h>
  #include <palacios/vmx_io.h>
  #include <palacios/vmx_msr.h>
@@@ -532,7 -527,7 +532,7 @@@ int v3_init_vm(struct v3_vm_info * vm) 
  
  
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
      v3_init_telemetry(vm);
  #endif
  
      v3_init_time_vm(vm);
  
  
- #ifdef CONFIG_SYMBIOTIC
+ #ifdef V3_CONFIG_SYMBIOTIC
      v3_init_symbiotic_vm(vm);
  #endif
  
  
      // init SVM/VMX
      switch (cpu_type) {
- #ifdef CONFIG_SVM
+ #ifdef V3_CONFIG_SVM
        case V3_SVM_CPU:
        case V3_SVM_REV3_CPU:
            v3_init_svm_io_map(vm);
            v3_init_svm_msr_map(vm);
            break;
  #endif
- #ifdef CONFIG_VMX
+ #ifdef V3_CONFIG_VMX
        case V3_VMX_CPU:
        case V3_VMX_EPT_CPU:
+       case V3_VMX_EPT_UG_CPU:
            v3_init_vmx_io_map(vm);
            v3_init_vmx_msr_map(vm);
            break;
@@@ -604,22 -600,23 +605,23 @@@ int v3_free_vm_internal(struct v3_vm_in
  
  
  
- #ifdef CONFIG_SYMBIOTIC
+ #ifdef V3_CONFIG_SYMBIOTIC
      v3_deinit_symbiotic_vm(vm);
  #endif
  
      // init SVM/VMX
      switch (cpu_type) {
- #ifdef CONFIG_SVM
+ #ifdef V3_CONFIG_SVM
        case V3_SVM_CPU:
        case V3_SVM_REV3_CPU:
            v3_deinit_svm_io_map(vm);
            v3_deinit_svm_msr_map(vm);
            break;
  #endif
- #ifdef CONFIG_VMX
+ #ifdef V3_CONFIG_VMX
        case V3_VMX_CPU:
        case V3_VMX_EPT_CPU:
+       case V3_VMX_EPT_UG_CPU:
            v3_deinit_vmx_io_map(vm);
            v3_deinit_vmx_msr_map(vm);
            break;
      v3_deinit_io_map(vm);
      v3_deinit_hypercall_map(vm);
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
      v3_deinit_telemetry(vm);
  #endif
  
@@@ -664,7 -661,7 +666,7 @@@ int v3_init_core(struct guest_info * co
      /*
       * Initialize the subsystem data strutures
       */
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
      v3_init_core_telemetry(core);
  #endif
  
      v3_init_decoder(core);
  
  
- #ifdef CONFIG_SYMBIOTIC
+ #ifdef V3_CONFIG_SYMBIOTIC
      v3_init_symbiotic_core(core);
  #endif
  
 +// KCH
- #ifdef CONFIG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_SYSCALL_HIJACK
 +    v3_init_exec_hooks(core);
 +    v3_init_mpi_accel(core);
-     //v3_hook_swintr(core, 0x80, v3_syscall_handler, NULL);
-     /* hook a poll syscall */
-     //v3_hook_syscall(core, 5, v3_sysopen_handler, NULL);
-     //v3_hook_syscall(core, 21, v3_sysmount_handler, NULL);
-     //char * args[2];
-     //args[0] = "./envtest";
-     //args[1] = "LD_PRELOAD=./libcwrap.so";
-     //v3_hook_syscall(core, 11, v3_sysexecve_handler, (void*)args);
 +#endif  
 +
      // init SVM/VMX
  
  
      switch (cpu_type) {
- #ifdef CONFIG_SVM
+ #ifdef V3_CONFIG_SVM
        case V3_SVM_CPU:
        case V3_SVM_REV3_CPU:
            if (v3_init_svm_vmcb(core, vm->vm_class) == -1) {
            }
            break;
  #endif
- #ifdef CONFIG_VMX
+ #ifdef V3_CONFIG_VMX
        case V3_VMX_CPU:
        case V3_VMX_EPT_CPU:
+       case V3_VMX_EPT_UG_CPU:
            if (v3_init_vmx_vmcs(core, vm->vm_class) == -1) {
                PrintError("Error in VMX initialization\n");
                return -1;
@@@ -733,7 -717,7 +728,7 @@@ int v3_free_core(struct guest_info * co
      v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU());
  
      
- #ifdef CONFIG_SYMBIOTIC
+ #ifdef V3_CONFIG_SYMBIOTIC
      v3_deinit_symbiotic_core(core);
  #endif
  
  
      v3_free_passthrough_pts(core);
  
- #ifdef CONFIG_TELEMETRY
+ #ifdef V3_CONFIG_TELEMETRY
      v3_deinit_core_telemetry(core);
  #endif
  
      switch (cpu_type) {
- #ifdef CONFIG_SVM
+ #ifdef V3_CONFIG_SVM
        case V3_SVM_CPU:
        case V3_SVM_REV3_CPU:
            if (v3_deinit_svm_vmcb(core) == -1) {
            }
            break;
  #endif
- #ifdef CONFIG_VMX
+ #ifdef V3_CONFIG_VMX
        case V3_VMX_CPU:
        case V3_VMX_EPT_CPU:
+       case V3_VMX_EPT_UG_CPU:
            if (v3_deinit_vmx_vmcs(core) == -1) {
                PrintError("Error in VMX initialization\n");
                return -1;
@@@ -64,7 -64,7 +64,7 @@@ int v3_hpa_to_hva(addr_t hpa, addr_t * 
  }
  
  int v3_gpa_to_hpa(struct guest_info * info, addr_t gpa, addr_t * hpa) {
-     struct v3_mem_region * reg = v3_get_mem_region(info->vm_info, info->cpu_id, gpa);
+     struct v3_mem_region * reg = v3_get_mem_region(info->vm_info, info->vcpu_id, gpa);
  
      if (reg == NULL) {
        PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (NULL REGION)\n", 
@@@ -168,15 -168,15 +168,15 @@@ int v3_gva_to_gpa(struct guest_info * g
      switch (guest_info->cpu_mode) {
        case PROTECTED:
            if (v3_translate_guest_pt_32(guest_info, guest_cr3, gva, gpa) == -1) {
 -              PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n", 
 -                         (void *)gva, (void *)(addr_t)guest_cr3);
 +              /*PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n", 
 +                         (void *)gva, (void *)(addr_t)guest_cr3);*/
                return -1;
            }
            break;
        case PROTECTED_PAE:
            if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, gva, gpa) == -1) {
 -              PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n", 
 -                         (void *)gva, (void *)(addr_t)guest_cr3);
 +              /*PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n", 
 +                         (void *)gva, (void *)(addr_t)guest_cr3);*/
                return -1;
            }
            break;
        case LONG_32_COMPAT:
        case LONG_16_COMPAT:
            if (v3_translate_guest_pt_64(guest_info, guest_cr3, gva, gpa) == -1) {
 -              PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n", 
 -                         (void *)gva, (void *)(addr_t)guest_cr3);
 +              /*PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n", 
 +                         (void *)gva, (void *)(addr_t)guest_cr3);*/
                return -1;
            }
            break;
@@@ -266,8 -266,8 +266,8 @@@ int v3_gva_to_hva(struct guest_info * g
      *hva = 0;
  
      if (v3_gva_to_gpa(guest_info, gva, &gpa) != 0) {
 -      PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n", 
 -                 (void *)gva);
 +      /*PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n", 
 +                 (void *)gva);*/
        return -1;
      }
  
@@@ -317,56 -317,6 +317,56 @@@ int v3_hva_to_gva(struct guest_info * g
  
  
  
 +/* KCH: currently only checks if we can perform a user-mode write
 +   return 1 on success */
 +int v3_gva_can_access(struct guest_info * core, addr_t gva) {
 +
 +    v3_reg_t guest_cr3 = 0;
 +    pf_error_t access_type;
 +    pt_access_status_t access_status;
 +
 +    access_type.write = 1;
 +    access_type.user = 1;
 +    
 +    if (core->mem_mode == PHYSICAL_MEM) {
 +        return -1;
 +    }
 +    
 +    if (core->shdw_pg_mode == SHADOW_PAGING) {
 +        guest_cr3 = core->shdw_pg_state.guest_cr3;
 +    } else {
 +        guest_cr3 = core->ctrl_regs.cr3;
 +    }
 +    
 +    // guest is in paged mode
 +    switch (core->cpu_mode) {
 +    case PROTECTED:
 +        if (v3_check_guest_pt_32(core, guest_cr3, gva, access_type, &access_status) == -1) {
 +            return -1;
 +        }
 +        break;
 +    case PROTECTED_PAE:
 +        if (v3_check_guest_pt_32pae(core, guest_cr3, gva, access_type, &access_status) == -1) {
 +            return -1;
 +        }
 +        break;
 +    case LONG:
 +    case LONG_32_COMPAT:
 +    case LONG_16_COMPAT:
 +        if (v3_check_guest_pt_64(core, guest_cr3, gva, access_type, &access_status) == -1) {
 +            return -1;
 +        }
 +        break;
 +    default:
 +        return -1;
 +    }
 +
 +    if (access_status != PT_ACCESS_OK) {
 +        return 0;
 +    } else {
 +        return 1;
 +    }
 +}
  
  
  
@@@ -26,7 -26,7 +26,7 @@@
  #include <palacios/vmm_direct_paging.h>
  #include <palacios/svm.h>
  
- #ifndef CONFIG_DEBUG_CTRL_REGS
+ #ifndef V3_CONFIG_DEBUG_CTRL_REGS
  #undef PrintDebug
  #define PrintDebug(fmt, args...)
  #endif
@@@ -582,63 -582,6 +582,78 @@@ int v3_handle_efer_write(struct guest_i
      return 0;
  }
  
 +
 +/* KCH: all of the star handlers are for syscall interposition */
 +int v3_handle_star_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) {
 +
 +#ifdef CONFIG_DEBUG_SYSCALL_HIJACK
 +    PrintDebug("STAR Read\n");
 +#endif
 +
 +    return 0;
 +}
 +
 +
 +int v3_handle_star_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) {
 +    
- #ifdef CONFIG_DEBUG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK
 +    PrintDebug("STAR Write\n");
 +#endif
 +    return 0;
 +}
 +
 +
 +int v3_handle_lstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) {
 +
- #ifdef CONFIG_DEBUG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK
 +    PrintDebug("LSTAR Read\n");
 +#endif
 +    return 0;
 +}
 +
 +
 +int v3_handle_lstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) {
 +    
- #ifdef CONFIG_DEBUG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK
++    ulong_t entry = ((ulong_t)src.hi << 32) | (ulong_t)src.lo;
 +    PrintDebug("LSTAR Write\n");
++    PrintDebug("\tKernel syscall entry point: 0x%lx\n", entry);
 +#endif
++    
 +    return 0;
 +}
 +
 +
 +int v3_handle_cstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) {
 +
- #ifdef CONFIG_DEBUG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK
 +    PrintDebug("CSTAR Read\n");
 +#endif
 +    return 0;
 +}
 +
 +
 +int v3_handle_cstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) {
 +    
- #ifdef CONFIG_DEBUG_SYSCALL_HIJACK
++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK
 +    PrintDebug("CSTAR Write\n");
 +#endif
++    return 0;
++}
++
++int v3_handle_seeip_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) {
++    /* we don't care about reads */
++    return 0;
++}
++
++int v3_handle_seeip_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) {
++#ifdef V3_CONFIG_DEBUG_SYSALL_HIJACK
++    PrintDebug("SYSENTER_EIP Write\n");
++#endif
 +    return 0;
 +}
 +
 +
  int v3_handle_vm_cr_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) {
      /* tell the guest that the BIOS disabled SVM, that way it doesn't get 
       * confused by the fact that CPUID reports SVM as available but it still
@@@ -146,7 -146,6 +146,7 @@@ static char * op_type_to_str(v3_op_type
        case V3_OP_STOS: return "V3_OP_STOS"; 
        case V3_OP_MOVZX: return "V3_OP_MOVZX"; 
        case V3_OP_MOVSX: return "V3_OP_MOVSX";
 +    case V3_OP_INT: return "V3_OP_INT"; // KCH
        case V3_INVALID_OP: 
        default:
            return "V3_INVALID_OP";
@@@ -193,7 -192,7 +193,7 @@@ static const ullong_t mask_8 = 0xffffff
  void v3_print_instr(struct x86_instr * instr) {
      V3_Print("Instr: %s (Len: %d)\n", op_type_to_str(instr->op_type), instr->instr_length);
  
-     V3_Print("Prefixes= %x\n", *(uint32_t *)&(instr->prefixes));
+     V3_Print("Prefixes= %x\n", instr->prefixes.val);
  
      if (instr->is_str_op) {
        V3_Print("String OP (len=%d)\n", (uint32_t)instr->str_op_length);
  #include <palacios/vmm_ctrl_regs.h>
  
  #include <palacios/vmm_lock.h>
 +#include <palacios/vm_guest_mem.h>
 +#include <palacios/vmm_decoder.h>
  
- #ifndef CONFIG_DEBUG_INTERRUPTS
+ #ifndef V3_CONFIG_DEBUG_INTERRUPTS
  #undef PrintDebug
  #define PrintDebug(fmt, args...)
  #endif
  
  
  
 -
  struct intr_controller {
      struct intr_ctrl_ops * ctrl_ops;
      
@@@ -51,8 -50,6 +51,8 @@@ struct intr_router 
  
  };
  
 +
 +
  void v3_init_intr_controllers(struct guest_info * info) {
      struct v3_intr_core_state * intr_state = &(info->intr_core_state);
  
@@@ -98,7 -95,6 +98,7 @@@ void v3_deinit_intr_routers(struct v3_v
      }  
  }
  
 +
  void * v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * priv_data) {
      struct intr_controller * ctrlr = (struct intr_controller *)V3_Malloc(sizeof(struct intr_controller));
  
      return (void *)ctrlr;
  }
  
 +
  void v3_remove_intr_controller(struct guest_info * core, void * handle) {
      struct v3_intr_core_state * intr_state = &(core->intr_core_state);
      struct intr_controller * ctrlr = handle;
      V3_Free(ctrlr);
  }
  
 +
  void * v3_register_intr_router(struct v3_vm_info * vm, struct intr_router_ops * ops, void * priv_data) {
      struct intr_router * router = (struct intr_router *)V3_Malloc(sizeof(struct intr_router));
  
      return (void *)router;
  }
  
 +
  void v3_remove_intr_router(struct v3_vm_info * vm, void * handle) {
      struct intr_router * router = handle;
      struct intr_router * tmp = NULL;
  }
  
  
 -
 -static inline struct v3_irq_hook * get_irq_hook(struct v3_vm_info * vm, uint_t irq) {
 -    V3_ASSERT(irq <= 256);
 +static inline struct v3_irq_hook * get_irq_hook(struct v3_vm_info * vm, uint8_t irq) {
      return vm->intr_routers.hooks[irq];
  }
  
@@@ -204,6 -199,7 +204,6 @@@ int v3_hook_irq(struct v3_vm_info * vm
  }
  
  
 -
  static int passthrough_irq_handler(struct v3_vm_info * vm, struct v3_interrupt * intr, void * priv_data) {
      PrintDebug("[passthrough_irq_handler] raise_irq=%d (guest=0x%p)\n", 
               intr->irq, (void *)vm);
      return v3_raise_irq(vm, intr->irq);
  }
  
 +
  int v3_hook_passthrough_irq(struct v3_vm_info * vm, uint_t irq) {
      int rc = v3_hook_irq(vm, irq, passthrough_irq_handler, NULL);
  
  }
  
  
 -
 -
 -
  int v3_deliver_irq(struct v3_vm_info * vm, struct v3_interrupt * intr) {
      PrintDebug("v3_deliver_irq: irq=%d state=0x%p, \n", intr->irq, (void *)intr);
    
  }
  
  
 -
 -
 -
  int v3_raise_virq(struct guest_info * info, int irq) {
      struct v3_intr_core_state * intr_state = &(info->intr_core_state);
      int major = irq / 8;
      return 0;
  }
  
 +
  int v3_lower_virq(struct guest_info * info, int irq) {
      struct v3_intr_core_state * intr_state = &(info->intr_core_state);
      int major = irq / 8;
@@@ -277,7 -277,6 +277,7 @@@ int v3_lower_irq(struct v3_vm_info * vm
      return 0;
  }
  
 +
  int v3_raise_irq(struct v3_vm_info * vm, int irq) {
      struct intr_router * router = NULL;
      struct v3_intr_routers * routers = &(vm->intr_routers);
  }
  
  
 +int v3_signal_swintr(struct guest_info * core, int vector) {
 +    struct v3_intr_core_state * intr_state = &(core->intr_core_state);
 +
 +    PrintDebug("Signaling software interrupt in vmm_intr.c\n");
 +    PrintDebug("\tINT vector: %d\n", vector);
 +    
 +    intr_state->swintr_posted = 1;
 +    intr_state->swintr_vector = vector;
 +    return 0;
 +}
 +
 +
 +int v3_handle_swintr(struct guest_info * core) {
 +
 +    int ret = 0;
 +    void * instr_ptr = NULL;
 +    struct x86_instr instr;
 +
 +    if (core->mem_mode == PHYSICAL_MEM) { 
 +        ret = v3_gpa_to_hva(core, get_addr_linear(core, core->rip, &(core->segments.cs)), (addr_t *)&instr_ptr);
 +    } else { 
 +        ret = v3_gva_to_hva(core, get_addr_linear(core, core->rip, &(core->segments.cs)), (addr_t *)&instr_ptr);
 +    }
 +    
 +    if (ret == -1) {
 +        PrintError("V3 SWintr Handler: Could not translate Instruction Address (%p)\n", (void *)core->rip);
 +        return -1;
 +    }
 +
 +    if (v3_decode(core, (addr_t)instr_ptr, &instr) == -1) {
 +        PrintError("V3 SWintr Handler: Decoding Error\n");
 +        return -1;
 +    }
 +
 +    uint8_t vector = instr.dst_operand.operand;
 +
 +    struct v3_swintr_hook * hook = core->intr_core_state.swintr_hooks[vector];
 +    if (hook == NULL) {
- #ifdef CONFIG_SWINTR_PASSTHROUGH
++#ifdef V3_CONFIG_SWINTR_PASSTHROUGH
 +        if (v3_hook_passthrough_swintr(core, vector) == -1) {
 +            PrintDebug("V3 SWintr Handler: Error hooking passthrough swintr\n");
 +            return -1;
 +        }
 +        hook = core->intr_core_state.swintr_hooks[vector];
 +#else
 +        core->rip += instr.instr_length;
 +        return v3_signal_swintr(core, vector);
 +#endif
 +    }
 +
 +    ret = hook->handler(core, vector, NULL);
 +    if (ret == -1) {
 +        PrintDebug("V3 SWintr Handler: Error in swintr hook\n");
 +        return -1;
 +    }
 +
-     /* at some point we may need to prioritize swints 
++    /* KCH: at some point we may need to prioritize swints 
 +       so that they finish in time for the next
-        instruction */
++       instruction... */
 +    core->rip += instr.instr_length;
 +    return v3_signal_swintr(core, vector);
 +}
 +
 +
 +static inline struct v3_swintr_hook * get_swintr_hook(struct guest_info * core, uint8_t vector) {
 +    return core->intr_core_state.swintr_hooks[vector];
 +}
 +
 +
 +int v3_hook_swintr(struct guest_info * core,
 +        uint8_t vector,
 +        int (*handler)(struct guest_info * core, uint8_t vector, void * priv_data),
 +        void * priv_data) 
 +{
 +
 +    struct v3_swintr_hook * hook = (struct v3_swintr_hook *)V3_Malloc(sizeof(struct v3_swintr_hook));
 +
 +    if (hook == NULL) { 
 +        return -1; 
 +    }
 +
 +    if (get_swintr_hook(core, vector) != NULL) {
 +        PrintError("SWINT %d already hooked\n", vector);
 +        return -1;
 +    }
 +
 +    hook->handler = handler;
 +    hook->priv_data = priv_data;
 +  
 +    core->intr_core_state.swintr_hooks[vector] = hook;
 +
 +    return 0;
 +}
 +    
 +
 +static int passthrough_swintr_handler(struct guest_info * core, uint8_t vector, void * priv_data) {
 +
 +    PrintDebug("[passthrough_swint_handler] INT vector=%d (guest=0x%p)\n", 
 +             vector, (void *)core);
 +
 +    return 0;
 +}
 +
 +
 +int v3_hook_passthrough_swintr(struct guest_info * core, uint8_t vector) {
 +
 +    int rc = v3_hook_swintr(core, vector, passthrough_swintr_handler, NULL);
 +
 +    if (rc) { 
 +        PrintError("guest_swintr_injection: failed to hook swint 0x%x (guest=0x%p)\n", vector, (void *)core);
 +        return -1;
 +    } else {
 +        PrintDebug("guest_swintr_injection: hooked swint 0x%x (guest=0x%p)\n", vector, (void *)core);
 +        return 0;
 +    }
 +
 +    /* shouldn't get here */
 +    return 0;
 +}
 +
 +
  void v3_clear_pending_intr(struct guest_info * core) {
      struct v3_intr_core_state * intr_state = &(core->intr_core_state);
  
      intr_state->irq_pending = 0;
 -
  }
  
  
@@@ -449,11 -328,6 +449,11 @@@ v3_intr_type_t v3_intr_pending(struct g
        }
      }
  
 +    // KCH: added for SWintr injection
 +    if (intr_state->swintr_posted == 1) {
 +        ret = V3_SOFTWARE_INTR;
 +    }
 +        
      v3_unlock_irqrestore(intr_state->irq_lock, irq_state);
  
      return ret;
@@@ -515,7 -389,7 +515,7 @@@ intr_type_t v3_get_intr_type(struct gue
        }
      }
  
- #ifdef CONFIG_DEBUG_INTERRUPTS
+ #ifdef V3_CONFIG_DEBUG_INTERRUPTS
      if (type == V3_INVALID_INTR) {
        PrintError("[get_intr_type] Invalid_Intr\n");
      }
  */
  
  
 -
 -
 -
  int v3_injecting_intr(struct guest_info * info, uint_t intr_num, v3_intr_type_t type) {
      struct v3_intr_core_state * intr_state = &(info->intr_core_state);
  
@@@ -20,7 -20,7 +20,7 @@@
  #include <palacios/vmm_decoder.h>
  #include <palacios/vmm_instr_decoder.h>
  
- #ifndef CONFIG_DEBUG_DECODER
+ #ifndef V3_CONFIG_DEBUG_DECODER
  #undef PrintDebug
  #define PrintDebug(fmt, args...)
  #endif
@@@ -75,7 -75,7 +75,7 @@@ int v3_decode(struct guest_info * core
      int length = 0;
  
  
-     V3_Print("Decoding Instruction at %p\n", (void *)instr_ptr);
+     PrintDebug("Decoding Instruction at %p\n", (void *)instr_ptr);
  
      memset(instr, 0, sizeof(struct x86_instr));
  
  
      form = op_code_to_form((uint8_t *)(instr_ptr + length), &length);
  
-     V3_Print("\t decoded as (%s)\n", op_form_to_str(form));
+     PrintDebug("\t decoded as (%s)\n", op_form_to_str(form));
  
      if (form == INVALID_INSTR) {
        PrintError("Could not find instruction form (%x)\n", *(uint32_t *)(instr_ptr + length));
  
      instr->instr_length += length;
  
+ #ifdef V3_CONFIG_DEBUG_DECODER
      v3_print_instr(instr);
+ #endif
  
      return 0;
  }
@@@ -444,23 -446,40 +446,40 @@@ static int parse_operands(struct guest_
        }
        case INVLPG: {
            uint8_t reg_code = 0;
-           
            ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
-           
            if (ret == -1) {
                PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
                return -1;
            }
-           
            instr_ptr += ret;
-           
+           instr->num_operands = 1;
+           break;
+       }
+       case LMSW: 
+       case SMSW: {
+           uint8_t reg_code = 0;
+           ret = decode_rm_operand(core, instr_ptr, form, instr, &(instr->dst_operand), &reg_code);
+           if (ret == -1) {
+               PrintError("Error decoding operand for (%s)\n", op_form_to_str(form));
+               return -1;
+           }
+           instr_ptr += ret;
+           instr->dst_operand.read = 1;
            instr->num_operands = 1;
            break;
        }
        case CLTS: {
            // no operands. 
            break;
-           
        }
        default:
            PrintError("Invalid Instruction form: %s\n", op_form_to_str(form));
@@@ -487,10 -506,6 +506,10 @@@ static v3_op_type_t op_form_to_type(op_
        case MOV_2CR:
            return V3_OP_MOV2CR;
  
 +    // KCH: for syscall interposition
 +    case INT:
 +        return V3_OP_INT;
 +
  
        case MOV_MEM2_8:
        case MOV_MEM2:
            return V3_OP_MOVZX;
  
  
-           
        case ADC_2MEM_8:
        case ADC_2MEM:
        case ADC_MEM2_8:
@@@ -35,7 -35,7 +35,7 @@@
  
  
  
- #ifndef CONFIG_DEBUG_DECODER
+ #ifndef V3_CONFIG_DEBUG_DECODER
  #undef PrintDebug
  #define PrintDebug(fmt, args...)
  #endif
@@@ -342,7 -342,7 +342,7 @@@ int v3_decode(struct guest_info * info
  
      xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
  
- #ifdef CONFIG_DEBUG_DECODER
+ #ifdef V3_CONFIG_DEBUG_DECODER
      xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
  
      PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
  
  
                case XED_OPERAND_IMM0:
 +                  {
 +                v3_op->size = xed_decoded_inst_get_immediate_width(&xed_instr);
 +
 +                if (v3_op->size > 4) {
 +                    PrintError("Unhandled 64 bit immediates\n");
 +                    return -1;
 +                }
 +                v3_op->operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
 +
 +                v3_op->type = IMM_OPERAND;
 +
 +                  }
 +                  break;
                case XED_OPERAND_AGEN:
                case XED_OPERAND_PTR:
                case XED_OPERAND_RELBR:
  
            instr->third_operand.type = REG_OPERAND;
  
 -          PrintDebug("Operand 3 mode: %s\n", xed_operand_action_enum_t2str(xed_operand_rw(op)));
 +          PrintDebug("Operand 2 mode: %s\n", xed_operand_action_enum_t2str(xed_operand_rw(op)));
  
  
            if (xed_operand_read(op)) {
@@@ -1283,10 -1270,6 +1283,10 @@@ static v3_op_type_t get_opcode(xed_ifor
        case XED_IFORM_INVLPG_MEMb:
            return V3_OP_INVLPG;
  
 +    // KCH
 +    case XED_IFORM_INT_IMM:
 +        return V3_OP_INT;
 +
  
            /* Data Instructions */