All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: APIC: avoid instruction emulation for EOI writes
@ 2011-08-29  6:09 Tian, Kevin
  2011-08-29  7:23 ` Avi Kivity
  2011-08-29 10:24 ` Jan Kiszka
  0 siblings, 2 replies; 14+ messages in thread
From: Tian, Kevin @ 2011-08-29  6:09 UTC (permalink / raw)
  To: Avi Kivity
  Cc: kvm@vger.kernel.org, Nakajima, Jun, Dong, Eddie, Marcelo Tosatti

[-- Attachment #1: Type: text/plain, Size: 3392 bytes --]

Hi, Avi,

Here comes the patch:

    KVM: APIC: avoid instruction emulation for EOI writes
    
    Instruction emulation for EOI writes can be skipped, since sane
    guest simply uses MOV instead of string operations. This is a nice
    improvement when guest doesn't support x2apic or hyper-V EOI
    support.
    
    a single VM bandwidth is observed with ~8% bandwidth improvement
    (7.4Gbps->8Gbps), by saving ~5% cycles from EOI emulation.
    
    Signed-off-by: Kevin Tian <kevin.tian@intel.com>
    <Based on earlier work from>:
    Signed-off-by: Eddie Dong <eddie.dong@intel.com>
    Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 57dcbd4..933187e 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -864,6 +864,15 @@ static int apic_mmio_write(struct kvm_io_device *this,
 	return 0;
 }
 
+void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
+{
+	struct kvm_lapic *apic = vcpu->arch.apic;
+
+	if (apic)
+		apic_set_eoi(vcpu->arch.apic);
+}
+EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
+
 void kvm_free_lapic(struct kvm_vcpu *vcpu)
 {
 	if (!vcpu->arch.apic)
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 52c9e6b..8287243 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -26,6 +26,7 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu);
 void kvm_lapic_reset(struct kvm_vcpu *vcpu);
 u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
+void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
 u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
 void kvm_apic_set_version(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 5e8d411..35e4af7 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4540,6 +4540,22 @@ static int handle_xsetbv(struct kvm_vcpu *vcpu)
 
 static int handle_apic_access(struct kvm_vcpu *vcpu)
 {
+	unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
+	int access_type, offset;
+
+	access_type = (exit_qualification >> 12) & 0xf;
+	offset = exit_qualification & 0xfff;
+	/*
+	 * Sane guest uses MOV instead of string operations to
+	 * write EOI, with written value not cared. So make a
+	 * short-circuit here by avoiding heavy instruction 
+	 * emulation.
+	 */
+	if ((access_type == 1) && (offset == APIC_EOI)) {
+		kvm_lapic_set_eoi(vcpu);
+		skip_emulated_instruction(vcpu);
+		return 1;
+	}
 	return emulate_instruction(vcpu, 0) == EMULATE_DONE;
 }

Thanks
Kevin

> -----Original Message-----
> From: Avi Kivity [mailto:avi@redhat.com]
> Sent: Thursday, August 25, 2011 12:39 PM
> To: Tian, Kevin
> Cc: kvm@vger.kernel.org; Nakajima, Jun
> Subject: Re: about vEOI optimization
> 
> On 08/25/2011 05:24 AM, Tian, Kevin wrote:
> > >
> > >  Another option is the hyper-V EOI support, which can also eliminate the
> > >  EOI exit when no additional interrupt is pending.  This can improve EOI
> > >  performance even more.
> > >
> >
> > yes, and this is an orthogonal option.
> >
> > So if you agree, I'll send out an updated patch atop their work.
> >
> >
> 
> Thanks.
> 
> --
> I have a truly marvellous patch that fixes the bug which this
> signature is too narrow to contain.


[-- Attachment #2: 20110829_kvm_eoi_opt.patch --]
[-- Type: application/octet-stream, Size: 2656 bytes --]

commit 0a52eaa0e8781bbbab46dd4e8b768bc522f6cb16
Author: Kevin Tian <kevin.tian@intel.com>
Date:   Mon Aug 29 13:08:28 2011 +0800

    KVM: APIC: avoid instruction emulation for EOI writes
    
    Instruction emulation for EOI writes can be skipped, since sane
    guest simply uses MOV instead of string operations. This is a nice
    improvement when guest doesn't support x2apic or hyper-V EOI
    support.
    
    a single VM bandwidth is observed with ~8% bandwidth improvement
    (7.4Gbps->8Gbps), by saving ~5% cycles from EOI emulation.
    
    Signed-off-by: Kevin Tian <kevin.tian@intel.com>
    <Based on earlier work from>:
    Signed-off-by: Eddie Dong <eddie.dong@intel.com>
    Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 57dcbd4..933187e 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -864,6 +864,15 @@ static int apic_mmio_write(struct kvm_io_device *this,
 	return 0;
 }
 
+void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
+{
+	struct kvm_lapic *apic = vcpu->arch.apic;
+
+	if (apic)
+		apic_set_eoi(vcpu->arch.apic);
+}
+EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
+
 void kvm_free_lapic(struct kvm_vcpu *vcpu)
 {
 	if (!vcpu->arch.apic)
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 52c9e6b..8287243 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -26,6 +26,7 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu);
 void kvm_lapic_reset(struct kvm_vcpu *vcpu);
 u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
+void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
 u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
 void kvm_apic_set_version(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 5e8d411..35e4af7 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4540,6 +4540,22 @@ static int handle_xsetbv(struct kvm_vcpu *vcpu)
 
 static int handle_apic_access(struct kvm_vcpu *vcpu)
 {
+	unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
+	int access_type, offset;
+
+	access_type = (exit_qualification >> 12) & 0xf;
+	offset = exit_qualification & 0xfff;
+	/*
+	 * Sane guest uses MOV instead of string operations to
+	 * write EOI, with written value not cared. So make a
+	 * short-circuit here by avoiding heavy instruction 
+	 * emulation.
+	 */
+	if ((access_type == 1) && (offset == APIC_EOI)) {
+		kvm_lapic_set_eoi(vcpu);
+		skip_emulated_instruction(vcpu);
+		return 1;
+	}
 	return emulate_instruction(vcpu, 0) == EMULATE_DONE;
 }
 

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2011-09-11  8:05 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-29  6:09 [PATCH] KVM: APIC: avoid instruction emulation for EOI writes Tian, Kevin
2011-08-29  7:23 ` Avi Kivity
2011-08-29  7:35   ` Tian, Kevin
2011-08-29  8:15     ` Sasha Levin
2011-08-29  8:51       ` Avi Kivity
2011-08-29 10:24 ` Jan Kiszka
2011-08-29 10:59   ` Avi Kivity
2011-08-29 11:03     ` Jan Kiszka
2011-08-29 11:11       ` Avi Kivity
2011-08-29 13:55         ` Jan Kiszka
2011-08-29 14:14           ` Avi Kivity
2011-09-10  8:41             ` ya su
2011-09-11  7:11               ` Avi Kivity
2011-09-11  8:05                 ` Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.