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 --cc 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
  
  
@@@ -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
  
  
  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;
  
  #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);
  
@@@ -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
@@@ -65,20 -65,11 +65,10 @@@ obj-$(V3_CONFIG_VMX) +=    vmx.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/
@@@ -135,11 -136,6 +136,11 @@@ static void Init_VMCB_BIOS(vmcb_t * vmc
      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");
        
@@@ -33,9 -33,8 +33,9 @@@
  #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
@@@ -194,18 -193,9 +194,18 @@@ int v3_handle_svm_exit(struct guest_inf
                    }
            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) {
  #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) {
@@@ -683,20 -680,6 +685,12 @@@ int v3_init_core(struct guest_info * co
      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
  
  
Simple merge
@@@ -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
Simple merge
  #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
@@@ -295,127 -294,6 +295,127 @@@ int v3_raise_irq(struct v3_vm_info * vm
  }
  
  
 +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);
  
Simple merge
Simple merge