direct-io.hg

changeset 13095:b17d1bc1febf

[HVM][SVM] Modify the interrupt/event injection logic.

Resolves performance issues concerning AMD-V virtual interrupt/event
injection:
- Remove extra VINTRs vmexits, and only setup fake interrupt if intr
pending.
- Allow both event injection and interrupt injection concurrently in
vmcb.

Signed-off-by: Tom Woller <thomas.woller@amd.com>
author kfraser@localhost.localdomain
date Wed Dec 20 10:14:50 2006 +0000 (2006-12-20)
parents 87dceaa715af
children 2a1edeedf28d
files xen/arch/x86/hvm/svm/intr.c xen/arch/x86/hvm/svm/svm.c xen/include/asm-x86/hvm/svm/vmcb.h
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/intr.c	Wed Dec 20 10:11:45 2006 +0000
     1.2 +++ b/xen/arch/x86/hvm/svm/intr.c	Wed Dec 20 10:14:50 2006 +0000
     1.3 @@ -78,26 +78,6 @@ asmlinkage void svm_intr_assist(void)
     1.4          re_injecting = 1;
     1.5      }
     1.6  
     1.7 -    /*
     1.8 -     * If event requires injecting then do not inject int.
     1.9 -     */
    1.10 -    if ( unlikely(v->arch.hvm_svm.inject_event) )
    1.11 -    {
    1.12 -        v->arch.hvm_svm.inject_event = 0;
    1.13 -        return;
    1.14 -    }
    1.15 -
    1.16 -    /*
    1.17 -     * Create a 'fake' virtual interrupt on to intercept as soon
    1.18 -     * as the guest _can_ take interrupts.
    1.19 -     */
    1.20 -    if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )
    1.21 -    {
    1.22 -        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
    1.23 -        svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */
    1.24 -        return;
    1.25 -    }
    1.26 -
    1.27      /* Previous interrupt still pending? */
    1.28      if ( vmcb->vintr.fields.irq )
    1.29      {
    1.30 @@ -124,7 +104,20 @@ asmlinkage void svm_intr_assist(void)
    1.31          hvm_set_callback_irq_level();
    1.32  
    1.33          if ( cpu_has_pending_irq(v) )
    1.34 +        {
    1.35 +            /*
    1.36 +             * Create a 'fake' virtual interrupt on to intercept as soon
    1.37 +             * as the guest _can_ take interrupts.  Do not obtain the next
    1.38 +             * interrupt from the vlapic/pic if unable to inject.
    1.39 +             */
    1.40 +            if ( irq_masked(vmcb->rflags) || vmcb->interrupt_shadow )  
    1.41 +            {
    1.42 +                vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
    1.43 +                svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */
    1.44 +                return;
    1.45 +            }
    1.46              intr_vector = cpu_get_interrupt(v, &intr_type);
    1.47 +        }
    1.48      }
    1.49  
    1.50      /* have we got an interrupt to inject? */
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Dec 20 10:11:45 2006 +0000
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed Dec 20 10:14:50 2006 +0000
     2.3 @@ -191,7 +191,6 @@ static inline void svm_inject_exception(
     2.4      ASSERT(vmcb->eventinj.fields.v == 0);
     2.5      
     2.6      vmcb->eventinj = event;
     2.7 -    v->arch.hvm_svm.inject_event=1;
     2.8  }
     2.9  
    2.10  static void stop_svm(void)
    2.11 @@ -2564,8 +2563,6 @@ asmlinkage void svm_vmexit_handler(struc
    2.12      exit_reason = vmcb->exitcode;
    2.13      save_svm_cpu_user_regs(v, regs);
    2.14  
    2.15 -    v->arch.hvm_svm.inject_event = 0;
    2.16 -
    2.17      if (exit_reason == VMEXIT_INVALID)
    2.18      {
    2.19          svm_dump_vmcb(__func__, vmcb);
    2.20 @@ -2933,7 +2930,7 @@ asmlinkage void svm_asid(void)
    2.21          clear_bit( ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags );
    2.22      }
    2.23  }
    2.24 -
    2.25 +  
    2.26  /*
    2.27   * Local variables:
    2.28   * mode: C
     3.1 --- a/xen/include/asm-x86/hvm/svm/vmcb.h	Wed Dec 20 10:11:45 2006 +0000
     3.2 +++ b/xen/include/asm-x86/hvm/svm/vmcb.h	Wed Dec 20 10:14:50 2006 +0000
     3.3 @@ -456,7 +456,6 @@ struct arch_svm_struct {
     3.4      u32                 *msrpm;
     3.5      u64                 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */
     3.6      int                 saved_irq_vector;
     3.7 -    u32                 inject_event;
     3.8      u32                 launch_core;
     3.9      u32                 asid_core;
    3.10