From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: Re: [PATCH 4/9] KVM: VMX: Cache cpl Date: Tue, 8 Mar 2011 16:20:10 +0200 Message-ID: <20110308142010.GE2504@redhat.com> References: <1299592665-12325-1-git-send-email-avi@redhat.com> <1299592665-12325-5-git-send-email-avi@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Marcelo Tosatti , kvm@vger.kernel.org, Jan Kiszka To: Avi Kivity Return-path: Received: from mx1.redhat.com ([209.132.183.28]:30849 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750931Ab1CHOUO (ORCPT ); Tue, 8 Mar 2011 09:20:14 -0500 Content-Disposition: inline In-Reply-To: <1299592665-12325-5-git-send-email-avi@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: On Tue, Mar 08, 2011 at 03:57:40PM +0200, Avi Kivity wrote: > We may read the cpl quite often in the same vmexit (instruction privilege > check, memory access checks for instruction and operands), so we gain > a bit if we cache the value. > Shouldn't VCPU_EXREG_CPL be cleared in vmx_set_efer too? > Signed-off-by: Avi Kivity > --- > arch/x86/include/asm/kvm_host.h | 1 + > arch/x86/kvm/vmx.c | 17 ++++++++++++++++- > 2 files changed, 17 insertions(+), 1 deletions(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 80f3070..4a2496d 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -119,6 +119,7 @@ enum kvm_reg_ex { > VCPU_EXREG_PDPTR = NR_VCPU_REGS, > VCPU_EXREG_CR3, > VCPU_EXREG_RFLAGS, > + VCPU_EXREG_CPL, > }; > > enum { > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index 82dbebd..87e3d86 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -128,6 +128,7 @@ struct vcpu_vmx { > unsigned long host_rsp; > int launched; > u8 fail; > + u8 cpl; > u32 exit_intr_info; > u32 idt_vectoring_info; > ulong rflags; > @@ -986,6 +987,7 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) > static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) > { > __set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail); > + __clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); > to_vmx(vcpu)->rflags = rflags; > if (to_vmx(vcpu)->rmode.vm86_active) { > to_vmx(vcpu)->rmode.save_rflags = rflags; > @@ -1992,6 +1994,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) > vmcs_writel(CR0_READ_SHADOW, cr0); > vmcs_writel(GUEST_CR0, hw_cr0); > vcpu->arch.cr0 = cr0; > + __clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); > } > > static u64 construct_eptp(unsigned long root_hpa) > @@ -2102,7 +2105,7 @@ static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg) > return vmcs_readl(sf->base); > } > > -static int vmx_get_cpl(struct kvm_vcpu *vcpu) > +static int __vmx_get_cpl(struct kvm_vcpu *vcpu) > { > if (!is_protmode(vcpu)) > return 0; > @@ -2114,6 +2117,16 @@ static int vmx_get_cpl(struct kvm_vcpu *vcpu) > return vmcs_read16(GUEST_CS_SELECTOR) & 3; > } > > +static int vmx_get_cpl(struct kvm_vcpu *vcpu) > +{ > + if (!test_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail)) { > + __set_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); > + to_vmx(vcpu)->cpl = __vmx_get_cpl(vcpu); > + } > + return to_vmx(vcpu)->cpl; > +} > + > + > static u32 vmx_segment_access_rights(struct kvm_segment *var) > { > u32 ar; > @@ -2179,6 +2192,7 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu, > ar |= 0x1; /* Accessed */ > > vmcs_write32(sf->ar_bytes, ar); > + __clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); > } > > static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) > @@ -4116,6 +4130,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) > > vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) > | (1 << VCPU_EXREG_RFLAGS) > + | (1 << VCPU_EXREG_CPL) > | (1 << VCPU_EXREG_PDPTR) > | (1 << VCPU_EXREG_CR3)); > vcpu->arch.regs_dirty = 0; > -- > 1.7.1 -- Gleb.