Skip to content

Commit

Permalink
KVM: VMX: Cache cpl
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Avi Kivity <avi@redhat.com>
  • Loading branch information
Avi Kivity committed May 11, 2011
1 parent f4c63e5 commit 69c7302
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
1 change: 1 addition & 0 deletions arch/x86/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ enum kvm_reg_ex {
VCPU_EXREG_PDPTR = NR_VCPU_REGS,
VCPU_EXREG_CR3,
VCPU_EXREG_RFLAGS,
VCPU_EXREG_CPL,
};

enum {
Expand Down
17 changes: 16 additions & 1 deletion arch/x86/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -987,6 +988,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;
Expand Down Expand Up @@ -2005,6 +2007,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)
Expand Down Expand Up @@ -2115,7 +2118,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;
Expand All @@ -2127,6 +2130,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;
Expand Down Expand Up @@ -2192,6 +2205,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)
Expand Down Expand Up @@ -4133,6 +4147,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;
Expand Down

0 comments on commit 69c7302

Please sign in to comment.