From patchwork Mon Aug 29 06:09:08 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tian, Kevin" X-Patchwork-Id: 1106332 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p7T6AuLD022329 for ; Mon, 29 Aug 2011 06:10:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752805Ab1H2GKy (ORCPT ); Mon, 29 Aug 2011 02:10:54 -0400 Received: from mga09.intel.com ([134.134.136.24]:16268 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750738Ab1H2GKx (ORCPT ); Mon, 29 Aug 2011 02:10:53 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 28 Aug 2011 23:10:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.67,352,1309762800"; d="scan'208";a="43156124" Received: from pgsmsx601.gar.corp.intel.com ([10.221.43.69]) by orsmga001.jf.intel.com with ESMTP; 28 Aug 2011 23:10:51 -0700 Received: from shsmsx602.ccr.corp.intel.com (10.239.4.104) by pgsmsx601.gar.corp.intel.com (10.221.43.69) with Microsoft SMTP Server (TLS) id 8.2.255.0; Mon, 29 Aug 2011 14:09:10 +0800 Received: from shsmsx502.ccr.corp.intel.com ([10.239.4.96]) by SHSMSX602.ccr.corp.intel.com ([10.239.4.104]) with mapi; Mon, 29 Aug 2011 14:09:10 +0800 From: "Tian, Kevin" To: Avi Kivity CC: "kvm@vger.kernel.org" , "Nakajima, Jun" , "Dong, Eddie" , Marcelo Tosatti Date: Mon, 29 Aug 2011 14:09:08 +0800 Subject: [PATCH] KVM: APIC: avoid instruction emulation for EOI writes Thread-Topic: [PATCH] KVM: APIC: avoid instruction emulation for EOI writes Thread-Index: AcxmEgEVEkq+yCp6T6K3CBUcDd5DYw== Message-ID: <625BA99ED14B2D499DC4E29D8138F15063045B0C0C@shsmsx502.ccr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Mon, 29 Aug 2011 06:10:57 +0000 (UTC) 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 : Signed-off-by: Eddie Dong Signed-off-by: Marcelo Tosatti 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. 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; }