76 lines
2.8 KiB
Diff
76 lines
2.8 KiB
Diff
# HG changeset patch
|
|
# User kfraser@localhost.localdomain
|
|
# Date Fri Oct 20 10:09:55 2006 +0100
|
|
# 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@amd.com>
|
|
Signed-off-by: Wei Huang <wei.huang2@amd.com>
|
|
Signed-off-by: Tom Woller <thomas.woller@amd.com>
|
|
|
|
Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/intr.c
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/intr.c
|
|
+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/intr.c
|
|
@@ -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_INT, 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:
|
|
Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c
|
|
===================================================================
|
|
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/svm.c
|
|
+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c
|
|
@@ -2802,6 +2802,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;
|
|
|