direct-io.hg
changeset 11841: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>
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