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.


added extension code for software interrupts
Kyle Hale [Wed, 22 Jun 2011 23:11:09 +0000 (18:11 -0500)]
palacios/include/interfaces/sw_intr.h
palacios/src/extensions/ext_sw_intr.c

index eb63cc9..5eedb3f 100644 (file)
 
 
 int v3_handle_swintr (struct guest_info * core);
-int v3_signal_swintr (struct guest_info * core, int vec);
+int v3_signal_swintr (struct guest_info * core, uint8_t 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);
+int v3_hook_passthrough_swintr (struct guest_info * core, uint8_t vector);
 
 
 #endif
index 26e8bb4..ff43f3f 100644 (file)
 #include <palacios/vmm.h>
 #include <palacios/vmcb.h>
 #include <palacios/vm_guest.h>
+#include <palacios/vm_guest_mem.h>
+#include <palacios/vmm_decoder.h>
 #include <palacios/vmm_extensions.h>
 
 #include <interfaces/sw_intr.h>
 
-static int init_swintr_intercept (struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data);
-
-    return 0;
-}
 
+static int init_swintr_intercept (struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
 
-static int deinit_swintr_intercept (struct v3_vm_info * vm, void * priv_data) {
-    
     return 0;
 }
 
@@ -40,47 +37,164 @@ static int init_swintr_intercept_core (struct guest_info * core, void * priv_dat
     vmcb_t * vmcb = (vmcb_t*)core->vmm_data;
     vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
 
-    ctrl_rea->instrs.INTn = 1;
+    ctrl_area->instrs.INTn = 1;
 
     return 0;
 }
 
 
-static int deinit_swintr_intercept_core (struct guest_info * core, void * priv_data) {
-
-    return 0;
-}
-
+struct v3_swintr_hook {
+    int (*handler)(struct guest_info * core, uint8_t vector, void * priv_data);
+    void * priv_data;
+};
 
-static int swintr_entry (struct guest_info * core, void * priv_data) {
 
-    return 0;
-}
+static struct v3_swintr_hook * swintr_hooks[256];
 
-static int swintr_exit (struct guest_info * core, void * priv_data) {
 
-    return 0;
+static inline struct v3_swintr_hook * get_swintr_hook (struct guest_info * core, uint8_t vector) {
+    return swintr_hooks[vector];
 }
 
 
-
 static struct v3_extension_impl swintr_impl = {
     .name = "swintr_intercept",
     .init = init_swintr_intercept,
-    .deinit = deinit_swintr_intercept,
+    .deinit = NULL,
     .core_init = init_swintr_intercept_core,
-    .core_deinit = deinit_swintr_intercept_core,
-    .on_entry = swintr_entry,
-    .on_exit = swintr_exit
+    .core_deinit = NULL,
+    .on_entry = NULL,
+    .on_exit = NULL
 };
 
+
 register_extension(&swintr_impl);
 
 
 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 = swintr_hooks[vector];
+    if (hook == NULL) {
+#ifdef V3_CONFIG_EXT_SWINTR_PASSTHROUGH
+        if (v3_hook_passthrough_swintr(core, vector) == -1) {
+            PrintDebug("V3 SWintr Handler: Error hooking passthrough swintr\n");
+            return -1; 
+        }
+        hook = 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) {
+#ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS
+        PrintDebug("V3 SWintr Handler: Error in swintr hook\n");
+#endif
+        return -1; 
+    }   
+
+    /* at some point we _may_ need to prioritize swints 
+       so that they finish in time for the next
+       instruction... */
+    core->rip += instr.instr_length;
+    return v3_signal_swintr(core, vector);
+}
+
+int v3_signal_swintr (struct guest_info * core, uint8_t vector) {
+    struct v3_intr_core_state * intr_state = &(core->intr_core_state);
+
+#ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS
+    PrintDebug("Signaling software interrupt in v3_signal_swintr()\n");
+    PrintDebug("\tINT vector: %d\n", vector);
+#endif
+    
+    intr_state->swintr_posted = 1;
+    intr_state->swintr_vector = vector;
+    return 0;
+}
+
+
+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;
+
+    swintr_hooks[vector] = hook;
+
     return 0;
 }
+    
+
+static int passthrough_swintr_handler (struct guest_info * core, uint8_t vector, void * priv_data) {
+#ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS
+    PrintDebug("[passthrough_swint_handler] INT vector=%d (guest=0x%p)\n",
+        vector, (void*)core);
+#endif
+    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 {
+#ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS
+        PrintDebug("guest_swintr_injection: hooked swint 0x%x (guest=0x%p)\n", vector, (void*)core);
+#endif
+        return 0;
+    }
+    
+    /* shouldn't get here */
+    return 0;
+}
+
+
+
+
+
+