# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1166609690 0
# Node ID 2ec9711cd03acda5aa10510ff7131548cadf2835
# Parent 5700d0a35f896c0a2d4eda36a41af95a9c496e49
[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@xxxxxxx>
Based on xen-unstable changeset 13095:b17d1bc1febf265b3700dbd34d511947c0cd02e2
---
xen/arch/x86/hvm/svm/intr.c | 33 +++++++++++++--------------------
xen/arch/x86/hvm/svm/svm.c | 5 +----
xen/include/asm-x86/hvm/svm/vmcb.h | 1 -
3 files changed, 14 insertions(+), 25 deletions(-)
diff -r 5700d0a35f89 -r 2ec9711cd03a xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Wed Dec 20 10:06:33 2006 +0000
+++ b/xen/arch/x86/hvm/svm/intr.c Wed Dec 20 10:14:50 2006 +0000
@@ -78,26 +78,6 @@ asmlinkage void svm_intr_assist(void)
re_injecting = 1;
}
- /*
- * If event requires injecting then do not inject int.
- */
- if ( unlikely(v->arch.hvm_svm.inject_event) )
- {
- v->arch.hvm_svm.inject_event = 0;
- return;
- }
-
- /*
- * 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;
- }
-
/* Previous interrupt still pending? */
if ( vmcb->vintr.fields.irq )
{
@@ -124,7 +104,20 @@ asmlinkage void svm_intr_assist(void)
hvm_set_callback_irq_level();
if ( cpu_has_pending_irq(v) )
+ {
+ /*
+ * Create a 'fake' virtual interrupt on to intercept as soon
+ * as the guest _can_ take interrupts. Do not obtain the next
+ * interrupt from the vlapic/pic if unable to inject.
+ */
+ 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;
+ }
intr_vector = cpu_get_interrupt(v, &intr_type);
+ }
}
/* have we got an interrupt to inject? */
diff -r 5700d0a35f89 -r 2ec9711cd03a xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Wed Dec 20 10:06:33 2006 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Wed Dec 20 10:14:50 2006 +0000
@@ -191,7 +191,6 @@ static inline void svm_inject_exception(
ASSERT(vmcb->eventinj.fields.v == 0);
vmcb->eventinj = event;
- v->arch.hvm_svm.inject_event=1;
}
static void stop_svm(void)
@@ -2596,8 +2595,6 @@ asmlinkage void svm_vmexit_handler(struc
exit_reason = vmcb->exitcode;
save_svm_cpu_user_regs(v, regs);
- v->arch.hvm_svm.inject_event = 0;
-
if (exit_reason == VMEXIT_INVALID)
{
svm_dump_vmcb(__func__, vmcb);
@@ -2965,7 +2962,7 @@ asmlinkage void svm_asid(void)
clear_bit( ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags );
}
}
-
+
/*
* Local variables:
* mode: C
diff -r 5700d0a35f89 -r 2ec9711cd03a xen/include/asm-x86/hvm/svm/vmcb.h
--- a/xen/include/asm-x86/hvm/svm/vmcb.h Wed Dec 20 10:06:33 2006 +0000
+++ b/xen/include/asm-x86/hvm/svm/vmcb.h Wed Dec 20 10:14:50 2006 +0000
@@ -456,7 +456,6 @@ struct arch_svm_struct {
u32 *msrpm;
u64 vmexit_tsc; /* tsc read at #VMEXIT. for TSC_OFFSET */
int saved_irq_vector;
- u32 inject_event;
u32 launch_core;
u32 asid_core;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|