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.


Fixes to interrupt (IRQ and VIRQ) injection logic:
Peter Dinda [Fri, 2 Aug 2013 20:41:13 +0000 (15:41 -0500)]
- eliminates potential race condition between intr being
  pending when intially checked, and no vector available before
  injection begins

- differentiates "do no have a vector" from "vector 0"

- detects VIRQ 0 correctly if it is raised

palacios/include/palacios/vmm_intr.h
palacios/src/palacios/svm.c
palacios/src/palacios/vmm_intr.c
palacios/src/palacios/vmx.c

index de98185..df1750b 100644 (file)
@@ -28,7 +28,7 @@
 #include <palacios/vmm_lock.h>
 
 
-typedef enum {V3_INVALID_INTR, V3_EXTERNAL_IRQ, V3_VIRTUAL_IRQ, V3_NMI, V3_SOFTWARE_INTR} v3_intr_type_t;
+typedef enum {V3_INVALID_INTR=0, V3_EXTERNAL_IRQ, V3_VIRTUAL_IRQ, V3_NMI, V3_SOFTWARE_INTR} v3_intr_type_t;
 
 struct guest_info;
 struct v3_vm_info;
@@ -121,7 +121,7 @@ void v3_remove_intr_controller(struct guest_info * core, void * handle);
 void v3_remove_intr_router(struct v3_vm_info * vm, void * handle);
 
 v3_intr_type_t v3_intr_pending(struct guest_info * info);
-uint32_t v3_get_intr(struct guest_info * info);
+int v3_get_intr(struct guest_info * info);
 int v3_injecting_intr(struct guest_info * info, uint_t intr_num, v3_intr_type_t type);
 
 
index 847bb1e..c226e68 100644 (file)
@@ -527,7 +527,11 @@ static int update_irq_entry_state(struct guest_info * info) {
     } else {
        switch (v3_intr_pending(info)) {
            case V3_EXTERNAL_IRQ: {
-               uint32_t irq = v3_get_intr(info);
+               int irq = v3_get_intr(info); 
+
+               if (irq<0) {
+                 break;
+               }
 
                guest_ctrl->guest_ctrl.V_IRQ = 1;
                guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
index 2e78872..ee54bef 100644 (file)
@@ -369,7 +369,7 @@ v3_intr_type_t v3_intr_pending(struct guest_info * info) {
 
     // External IRQs have lowest priority
     list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
-       if (ctrl->ctrl_ops->intr_pending(info, ctrl->priv_data) == 1) {
+       if (ctrl->ctrl_ops->intr_pending(info, ctrl->priv_data)) {
            ret = V3_EXTERNAL_IRQ;
            break;
        }
@@ -394,12 +394,14 @@ v3_intr_type_t v3_intr_pending(struct guest_info * info) {
 }
 
 
-uint32_t v3_get_intr(struct guest_info * info) {
+int v3_get_intr(struct guest_info * info) {
     struct v3_intr_core_state * intr_state = &(info->intr_core_state);
     struct intr_controller * ctrl = NULL;
-    uint_t ret = 0;
+    int ret = -1;
     int i = 0;
     int j = 0;
+    int found_virq=0;
+    int found_irq=0;
 
     addr_t irq_state = v3_lock_irqsave(intr_state->irq_lock);    
 
@@ -409,6 +411,8 @@ uint32_t v3_get_intr(struct guest_info * info) {
            for (j = 0; j < 8; j++) {
                if (intr_state->virq_map[i] & (1 << j)) {
                    ret = (i * 8) + j;
+                   // need to be able to find virq 0
+                   found_virq=1;
                    break;
                }
            }
@@ -416,20 +420,28 @@ uint32_t v3_get_intr(struct guest_info * info) {
        }
     }
 
-    if (!ret) {
+    if (!found_virq) {
        list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
            if (ctrl->ctrl_ops->intr_pending(info, ctrl->priv_data)) {
-               uint_t intr_num = ctrl->ctrl_ops->get_intr_number(info, ctrl->priv_data);
+               int intr_num = ctrl->ctrl_ops->get_intr_number(info, ctrl->priv_data);
                
-               //      PrintDebug(info->vm_info, info, "[get_intr_number] intr_number = %d\n", intr_num);
-               ret = intr_num;
-               break;
+               if (intr_num >= 0) {
+                 //    PrintDebug(info->vm_info, info, "[get_intr_number] intr_number = %d\n", intr_num);
+                 ret = intr_num;
+                 found_irq=1;
+                 break;
+               }
+
            }
        }
     }
 
     v3_unlock_irqrestore(intr_state->irq_lock, irq_state);
 
+    if (!found_virq && !found_irq) { 
+      PrintError(info->vm_info,info,"Strange... neither a VIRQ nor an IRQ was found...\n");
+    }
+
     return ret;
 }
 
index 2741051..2653af0 100644 (file)
@@ -820,7 +820,14 @@ static int update_irq_entry_state(struct guest_info * info) {
 
             switch (v3_intr_pending(info)) {
                 case V3_EXTERNAL_IRQ: {
-                    info->intr_core_state.irq_vector = v3_get_intr(info); 
+                 
+                   int irq = v3_get_intr(info); 
+
+                   if (irq<0) {
+                     break;
+                   }
+
+                    info->intr_core_state.irq_vector = irq; 
                     ent_int.vector = info->intr_core_state.irq_vector;
                     ent_int.type = 0;
                     ent_int.error_code = 0;