# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 2fbf11ad58f37313350e71f98f2eadb8ac37a8e4
# Parent 02506a7443155611d6bbf03e49fbf193e96d24db
[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@xxxxxxx>
Signed-off-by: Wei Huang <wei.huang2@xxxxxxx>
Signed-off-by: Tom Woller <thomas.woller@xxxxxxx>
---
xen/arch/x86/hvm/svm/intr.c | 14 ++++++++++++--
xen/arch/x86/hvm/svm/svm.c | 5 +++++
2 files changed, 17 insertions(+), 2 deletions(-)
diff -r 02506a744315 -r 2fbf11ad58f3 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Fri Oct 20 09:50:09 2006 +0100
+++ b/xen/arch/x86/hvm/svm/intr.c Fri Oct 20 10:09:55 2006 +0100
@@ -43,7 +43,7 @@
* to be suitable for SVM.
*/
-static inline int svm_inject_extint(struct vcpu *v, int trap, int error_code)
+static inline int svm_inject_extint(struct vcpu *v, int trap)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
vintr_t intr;
@@ -87,6 +87,16 @@ asmlinkage void svm_intr_assist(void)
re_injecting = 1;
}
+ /*
+ * create a 'fake' virtual interrupt on to intercept as soon
+ * as the guest _can_ take interrupts
+ */
+ if (irq_masked(vmcb->rflags) || vmcb->interrupt_shadow) {
+ vmcb->general1_intercepts |= GENERAL1_INTERCEPT_VINTR;
+ svm_inject_extint(v, 0x0); /* actual vector doesn't really matter */
+ return;
+ }
+
/* Guest's interrputs masked? */
rflags = vmcb->rflags;
if (irq_masked(rflags)) {
@@ -146,7 +156,7 @@ asmlinkage void svm_intr_assist(void)
}
/* let's inject this interrupt */
TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, intr_vector, 0);
- svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
+ svm_inject_extint(v, intr_vector);
hvm_interrupt_post(v, intr_vector, intr_type);
break;
case APIC_DM_SMI:
diff -r 02506a744315 -r 2fbf11ad58f3 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Oct 20 09:50:09 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Fri Oct 20 10:09:55 2006 +0100
@@ -2811,6 +2811,11 @@ asmlinkage void svm_vmexit_handler(struc
svm_inject_exception(v, TRAP_double_fault, 1, 0);
break;
+ case VMEXIT_VINTR:
+ vmcb->vintr.fields.irq = 0;
+ vmcb->general1_intercepts &= ~GENERAL1_INTERCEPT_VINTR;
+ break;
+
case VMEXIT_INTR:
break;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|