X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_intr.c;h=fa8c69fedca386c6bd911fb488a29d89e489c705;hb=626494b00fd477070f7eb43693eb16c4dc45f66b;hp=2e78872f57d2ac5e2e4d18e67c96894b456141c6;hpb=1f8ac11d4550b1113d9a8c23e62b236cb8ad8404;p=palacios.git diff --git a/palacios/src/palacios/vmm_intr.c b/palacios/src/palacios/vmm_intr.c index 2e78872..fa8c69f 100644 --- a/palacios/src/palacios/vmm_intr.c +++ b/palacios/src/palacios/vmm_intr.c @@ -69,11 +69,13 @@ void v3_deinit_intr_controllers(struct guest_info * core) { struct intr_controller * tmp; // clear out any controllers that were left around - list_for_each_entry_safe(ctrlr, tmp, &(intr_state->controller_list), ctrl_node) { - v3_remove_intr_controller(core, ctrlr); - } + if (*(void**)&intr_state->controller_list) { + list_for_each_entry_safe(ctrlr, tmp, &(intr_state->controller_list), ctrl_node) { + v3_remove_intr_controller(core, ctrlr); + } - v3_lock_deinit(&(intr_state->irq_lock)); + v3_lock_deinit(&(intr_state->irq_lock)); + } } @@ -92,12 +94,14 @@ void v3_deinit_intr_routers(struct v3_vm_info * vm) { struct intr_router * rtr = NULL; struct intr_router * tmp = NULL; - // clear out any controllers that were left around - list_for_each_entry_safe(rtr, tmp, &(vm->intr_routers.router_list), router_node) { - v3_remove_intr_router(vm, rtr); - } + // clear out any routers that were left around + if (*(void**)&vm->intr_routers.router_list) { + list_for_each_entry_safe(rtr, tmp, &(vm->intr_routers.router_list), router_node) { + v3_remove_intr_router(vm, rtr); + } - v3_lock_deinit(&(vm->intr_routers.irq_lock)); + v3_lock_deinit(&(vm->intr_routers.irq_lock)); + } } void * v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * priv_data) { @@ -369,7 +373,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 +398,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 +415,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 +424,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; }