ia64/xen-unstable

changeset 11914:2fbf11ad58f3

[HVM][SVM] Fix 1/2 to interrupt delivery logic.

This patch uses the VINTR intercept to signal the hypervisor when a
guest can take an interrupt. When guest's interrupts are masked by
EFLAGS.IF or the guests are in an interrupt shadow, we create a 'fake'
virtual interrupt to inject while also enabling the VINTR intercept.
When the guest _can_ take interrupts, the hypervisor will #VMEXIT
on VINTR. The VINTR exit handler then clears the VINTR intercept bit
and clears the V_IRQ bit so that svm_intr_assist() can inject a
legitimate interrupt.

Signed-off-by: Travis Betak <travis.betak@amd.com>
Signed-off-by: Wei Huang <wei.huang2@amd.com>
Signed-off-by: Tom Woller <thomas.woller@amd.com>
author kfraser@localhost.localdomain
date Fri Oct 20 10:09:55 2006 +0100 (2006-10-20)
parents 02506a744315
children c436ab500c99
files xen/arch/x86/hvm/svm/intr.c xen/arch/x86/hvm/svm/svm.c
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/intr.c	Fri Oct 20 09:50:09 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/svm/intr.c	Fri Oct 20 10:09:55 2006 +0100
     1.3 @@ -43,7 +43,7 @@
     1.4   * to be suitable for SVM.
     1.5   */
     1.6  
     1.7 -static inline int svm_inject_extint(struct vcpu *v, int trap, int error_code)
     1.8 +static inline int svm_inject_extint(struct vcpu *v, int trap)
     1.9  {
    1.10      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    1.11      vintr_t intr;
    1.12 @@ -87,6 +87,16 @@ asmlinkage void svm_intr_assist(void)
    1.13          re_injecting = 1;
    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 +        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
    1.22 +        svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */
    1.23 +        return;
    1.24 +    }
    1.25 +
    1.26      /* Guest's interrputs masked? */
    1.27      rflags = vmcb->rflags;
    1.28      if (irq_masked(rflags)) {
    1.29 @@ -146,7 +156,7 @@ asmlinkage void svm_intr_assist(void)
    1.30              }
    1.31              /* let's inject this interrupt */
    1.32              TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, intr_vector, 0);
    1.33 -            svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
    1.34 +            svm_inject_extint(v, intr_vector);
    1.35              hvm_interrupt_post(v, intr_vector, intr_type);
    1.36              break;
    1.37          case APIC_DM_SMI:
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Oct 20 09:50:09 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Oct 20 10:09:55 2006 +0100
     2.3 @@ -2811,6 +2811,11 @@ asmlinkage void svm_vmexit_handler(struc
     2.4          svm_inject_exception(v, TRAP_double_fault, 1, 0);
     2.5          break;
     2.6  
     2.7 +    case VMEXIT_VINTR:
     2.8 +	vmcb->vintr.fields.irq = 0;
     2.9 +	vmcb->general1_intercepts &= ~GENERAL1_INTERCEPT_VINTR;
    2.10 +	break;
    2.11 +
    2.12      case VMEXIT_INTR:
    2.13          break;
    2.14