[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvm: Clean up intr_assist() functions (both VMX and SVM, . but mainly
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1175017867 -3600 # Node ID faf0a055aa92c5967e8ef2e3dc2bb04afe5d75ba # Parent 2864754a398f3defeaad0494b8b6c23f82a1417d hvm: Clean up intr_assist() functions (both VMX and SVM,. but mainly the latter!). Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/hvm/svm/intr.c | 110 ++++++++++++++----------------------- xen/arch/x86/hvm/svm/svm.c | 2 xen/arch/x86/hvm/vmx/intr.c | 35 +++-------- xen/include/asm-x86/hvm/svm/vmcb.h | 1 4 files changed, 51 insertions(+), 97 deletions(-) diff -r 2864754a398f -r faf0a055aa92 xen/arch/x86/hvm/svm/intr.c --- a/xen/arch/x86/hvm/svm/intr.c Tue Mar 27 17:43:36 2007 +0100 +++ b/xen/arch/x86/hvm/svm/intr.c Tue Mar 27 18:51:07 2007 +0100 @@ -64,87 +64,61 @@ asmlinkage void svm_intr_assist(void) { struct vcpu *v = current; struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - struct periodic_time *pt; int intr_type = APIC_DM_EXTINT; int intr_vector = -1; - int re_injecting = 0; - /* Check if an Injection is active */ - /* Previous Interrupt delivery caused this Intercept? */ + /* + * Previous Interrupt delivery caused this intercept? + * This will happen if the injection is latched by the processor (hence + * clearing vintr.fields.irq) but then subsequently a fault occurs (e.g., + * due to lack of shadow mapping of guest IDT or guest-kernel stack). + * + * NB. Exceptions that fault during delivery are lost. This needs to be + * fixed but we'll usually get away with it since faults are usually + * idempotent. But this isn't the case for e.g. software interrupts! + */ if ( vmcb->exitintinfo.fields.v && (vmcb->exitintinfo.fields.type == 0) ) { - v->arch.hvm_svm.saved_irq_vector = vmcb->exitintinfo.fields.vector; + intr_vector = vmcb->exitintinfo.fields.vector; vmcb->exitintinfo.bytes = 0; - re_injecting = 1; + HVMTRACE_1D(REINJ_VIRQ, v, intr_vector); + svm_inject_extint(v, intr_vector); + return; } - /* Previous interrupt still pending? */ + /* + * Previous interrupt still pending? This occurs if we return from VMRUN + * very early in the entry-to-guest process. Usually this is because an + * external physical interrupt was pending when we executed VMRUN. + */ if ( vmcb->vintr.fields.irq ) + return; + + /* Crank the handle on interrupt state and check for new interrrupts. */ + pt_update_irq(v); + hvm_set_callback_irq_level(); + if ( !cpu_has_pending_irq(v) ) + return; + + /* + * Create a 'fake' virtual interrupt on to intercept as soon as the + * guest _can_ take interrupts. Do not obtain the next interrupt from + * the vlapic/pic if unable to inject. + */ + if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow ) { - intr_vector = vmcb->vintr.fields.vector; - vmcb->vintr.bytes = 0; - re_injecting = 1; - } - /* Pending IRQ saved at last VMExit? */ - else if ( v->arch.hvm_svm.saved_irq_vector >= 0 ) - { - intr_vector = v->arch.hvm_svm.saved_irq_vector; - v->arch.hvm_svm.saved_irq_vector = -1; - re_injecting = 1; - } - /* Now let's check for newer interrrupts */ - else - { - pt_update_irq(v); - - hvm_set_callback_irq_level(); - - if ( cpu_has_pending_irq(v) ) - { - /* - * Create a 'fake' virtual interrupt on to intercept as soon - * as the guest _can_ take interrupts. Do not obtain the next - * interrupt from the vlapic/pic if unable to inject. - */ - if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow ) - { - vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR; - HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1); - svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */ - return; - } - intr_vector = cpu_get_interrupt(v, &intr_type); - } + vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR; + HVMTRACE_2D(INJ_VIRQ, v, 0x0, /*fake=*/ 1); + svm_inject_extint(v, 0x0); /* actual vector doesn't matter */ + return; } - /* have we got an interrupt to inject? */ - if ( intr_vector < 0 ) - return; + /* Okay, we can deliver the interrupt: grab it and update PIC state. */ + intr_vector = cpu_get_interrupt(v, &intr_type); + BUG_ON(intr_vector < 0); - switch ( intr_type ) - { - case APIC_DM_EXTINT: - case APIC_DM_FIXED: - case APIC_DM_LOWEST: - /* Re-injecting a PIT interruptt? */ - if ( re_injecting && (pt = is_pt_irq(v, intr_vector, intr_type)) ) - ++pt->pending_intr_nr; - /* let's inject this interrupt */ - if (re_injecting) - HVMTRACE_1D(REINJ_VIRQ, v, intr_vector); - else - HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0); - svm_inject_extint(v, intr_vector); - break; - case APIC_DM_SMI: - case APIC_DM_NMI: - case APIC_DM_INIT: - case APIC_DM_STARTUP: - default: - printk("Unsupported interrupt type: %d\n", intr_type); - BUG(); - break; - } + HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0); + svm_inject_extint(v, intr_vector); pt_intr_post(v, intr_vector, intr_type); } diff -r 2864754a398f -r faf0a055aa92 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Tue Mar 27 17:43:36 2007 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Tue Mar 27 18:51:07 2007 +0100 @@ -962,8 +962,6 @@ static int svm_vcpu_initialise(struct vc v->arch.schedule_tail = arch_svm_do_resume; v->arch.ctxt_switch_from = svm_ctxt_switch_from; v->arch.ctxt_switch_to = svm_ctxt_switch_to; - - v->arch.hvm_svm.saved_irq_vector = -1; v->arch.hvm_svm.launch_core = -1; diff -r 2864754a398f -r faf0a055aa92 xen/arch/x86/hvm/vmx/intr.c --- a/xen/arch/x86/hvm/vmx/intr.c Tue Mar 27 17:43:36 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/intr.c Tue Mar 27 18:51:07 2007 +0100 @@ -89,7 +89,7 @@ asmlinkage void vmx_intr_assist(void) asmlinkage void vmx_intr_assist(void) { int intr_type = 0; - int highest_vector; + int intr_vector; unsigned long eflags; struct vcpu *v = current; unsigned int idtv_info_field; @@ -106,8 +106,9 @@ asmlinkage void vmx_intr_assist(void) if ( unlikely(v->arch.hvm_vmx.vector_injected) ) { - v->arch.hvm_vmx.vector_injected=0; - if (unlikely(has_ext_irq)) enable_irq_window(v); + v->arch.hvm_vmx.vector_injected = 0; + if ( unlikely(has_ext_irq) ) + enable_irq_window(v); return; } @@ -132,7 +133,6 @@ asmlinkage void vmx_intr_assist(void) enable_irq_window(v); HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field); - return; } @@ -154,30 +154,13 @@ asmlinkage void vmx_intr_assist(void) return; } - highest_vector = cpu_get_interrupt(v, &intr_type); - if ( highest_vector < 0 ) - return; + intr_vector = cpu_get_interrupt(v, &intr_type); + BUG_ON(intr_vector < 0); - switch ( intr_type ) - { - case APIC_DM_EXTINT: - case APIC_DM_FIXED: - case APIC_DM_LOWEST: - HVMTRACE_2D(INJ_VIRQ, v, highest_vector, /*fake=*/ 0); - vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE); - break; + HVMTRACE_2D(INJ_VIRQ, v, intr_vector, /*fake=*/ 0); + vmx_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE); - case APIC_DM_SMI: - case APIC_DM_NMI: - case APIC_DM_INIT: - case APIC_DM_STARTUP: - default: - printk("Unsupported interrupt type\n"); - BUG(); - break; - } - - pt_intr_post(v, highest_vector, intr_type); + pt_intr_post(v, intr_vector, intr_type); } /* diff -r 2864754a398f -r faf0a055aa92 xen/include/asm-x86/hvm/svm/vmcb.h --- a/xen/include/asm-x86/hvm/svm/vmcb.h Tue Mar 27 17:43:36 2007 +0100 +++ b/xen/include/asm-x86/hvm/svm/vmcb.h Tue Mar 27 18:51:07 2007 +0100 @@ -446,7 +446,6 @@ struct arch_svm_struct { u64 vmcb_pa; u32 *msrpm; u64 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */ - int saved_irq_vector; int launch_core; unsigned long flags; /* VMCB flags */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |