[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@amd.com>
This commit is contained in:
kfraser@localhost.localdomain committed 2006-12-20 10:14:50 +00:00
1 parent db6dca73cd
commit 625141e5d7
3 files changed
+14 -25

No files matched your search

+13 -20
View File
@@ -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? */
+1 -4
View File
@@ -191,7 +191,6 @@ static inline void svm_inject_exception(struct vcpu *v, int trap,
ASSERT(vmcb->eventinj.fields.v == 0);
vmcb->eventinj = event;
v->arch.hvm_svm.inject_event=1;
}
static void stop_svm(void)
@@ -2564,8 +2563,6 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
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);
@@ -2933,7 +2930,7 @@ asmlinkage void svm_asid(void)
clear_bit( ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags );
}
}
/*
* Local variables:
* mode: C
-1
View File
@@ -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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.