From: Jack Lange Date: Fri, 24 Apr 2009 20:26:49 +0000 (-0500) Subject: Ok. One more time. Please, please, please let this fix the interrupt injection mechanism. X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=6d57b915c82345c4dfb1897209f4778b4548bc31 Ok. One more time. Please, please, please let this fix the interrupt injection mechanism. --- diff --git a/palacios/include/palacios/vmm_intr.h b/palacios/include/palacios/vmm_intr.h index 82de275..50e1b22 100644 --- a/palacios/include/palacios/vmm_intr.h +++ b/palacios/include/palacios/vmm_intr.h @@ -49,6 +49,7 @@ struct v3_intr_state { struct list_head controller_list; uint_t irq_pending; + uint_t irq_started; uint_t irq_vector; /* some way to get the [A]PIC intr */ diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index 5b0b761..1e96118 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -77,17 +77,27 @@ int v3_handle_svm_exit(struct guest_info * info) { if ((info->intr_state.irq_pending == 1) && (guest_ctrl->guest_ctrl.V_IRQ == 0)) { #ifdef DEBUG_INTERRUPTS + PrintDebug("INTAK cycle completed for irq %d\n", info->intr_state.irq_vector); +#endif + + info->intr_state.irq_started = 1; + info->intr_state.irq_pending = 0; + + v3_injecting_intr(info, info->intr_state.irq_vector, EXTERNAL_IRQ); + } + + if ((info->intr_state.irq_started == 1) && (guest_ctrl->exit_int_info.valid == 0)) { +#ifdef DEBUG_INTERRUPTS PrintDebug("Interrupt %d taken by guest\n", info->intr_state.irq_vector); #endif - if (!guest_ctrl->exit_int_info.valid) { - info->intr_state.irq_pending = 0; - // PrintDebug("Injected Interrupt %d\n", info->intr_state.irq_vector); - v3_injecting_intr(info, info->intr_state.irq_vector, EXTERNAL_IRQ); - } else { + + // Interrupt was taken fully vectored + info->intr_state.irq_started = 0; + + } else { #ifdef DEBUG_INTERRUPTS - PrintDebug("EXIT INT INFO is set (vec=%d)\n", guest_ctrl->exit_int_info.vector); + PrintDebug("EXIT INT INFO is set (vec=%d)\n", guest_ctrl->exit_int_info.vector); #endif - } } @@ -384,7 +394,7 @@ int v3_handle_svm_exit(struct guest_info * info) { (void *)(addr_t)info->rip); #endif v3_injecting_excp(info, excp); - } else if (info->intr_state.irq_pending == 1) { + } else if (info->intr_state.irq_started == 1) { #ifdef DEBUG_INTERRUPTS PrintDebug("IRQ pending from previous injection\n"); #endif diff --git a/palacios/src/palacios/vmm_intr.c b/palacios/src/palacios/vmm_intr.c index e29285a..865a9fd 100644 --- a/palacios/src/palacios/vmm_intr.c +++ b/palacios/src/palacios/vmm_intr.c @@ -43,6 +43,7 @@ struct intr_controller { void v3_init_interrupt_state(struct guest_info * info) { info->intr_state.irq_pending = 0; + info->intr_state.irq_started = 0; info->intr_state.irq_vector = 0; INIT_LIST_HEAD(&(info->intr_state.controller_list)); @@ -181,7 +182,7 @@ int v3_intr_pending(struct guest_info * info) { // Check if the guest has interrupts enabled if (flags->intr == 0) { - return 0; + //return 0; } list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {