diff options
author | Avi Kivity <avi@redhat.com> | 2011-03-07 08:26:44 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-11 07:56:54 -0400 |
commit | 69c730289011df706a1c9890d6e6c5ee822623c7 (patch) | |
tree | 773398749dde9980fb12c13c016ca9b780673329 /arch/x86/kvm/vmx.c | |
parent | f4c63e5d5a356b652a3d984edbefca289176c40f (diff) |
KVM: VMX: Cache cpl
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>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e8a35ee00735..8f9e77edc016 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -128,6 +128,7 @@ struct vcpu_vmx { | |||
128 | unsigned long host_rsp; | 128 | unsigned long host_rsp; |
129 | int launched; | 129 | int launched; |
130 | u8 fail; | 130 | u8 fail; |
131 | u8 cpl; | ||
131 | u32 exit_intr_info; | 132 | u32 exit_intr_info; |
132 | u32 idt_vectoring_info; | 133 | u32 idt_vectoring_info; |
133 | ulong rflags; | 134 | ulong rflags; |
@@ -987,6 +988,7 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) | |||
987 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | 988 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) |
988 | { | 989 | { |
989 | __set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail); | 990 | __set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail); |
991 | __clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); | ||
990 | to_vmx(vcpu)->rflags = rflags; | 992 | to_vmx(vcpu)->rflags = rflags; |
991 | if (to_vmx(vcpu)->rmode.vm86_active) { | 993 | if (to_vmx(vcpu)->rmode.vm86_active) { |
992 | to_vmx(vcpu)->rmode.save_rflags = rflags; | 994 | to_vmx(vcpu)->rmode.save_rflags = rflags; |
@@ -2005,6 +2007,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
2005 | vmcs_writel(CR0_READ_SHADOW, cr0); | 2007 | vmcs_writel(CR0_READ_SHADOW, cr0); |
2006 | vmcs_writel(GUEST_CR0, hw_cr0); | 2008 | vmcs_writel(GUEST_CR0, hw_cr0); |
2007 | vcpu->arch.cr0 = cr0; | 2009 | vcpu->arch.cr0 = cr0; |
2010 | __clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); | ||
2008 | } | 2011 | } |
2009 | 2012 | ||
2010 | static u64 construct_eptp(unsigned long root_hpa) | 2013 | static u64 construct_eptp(unsigned long root_hpa) |
@@ -2115,7 +2118,7 @@ static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg) | |||
2115 | return vmcs_readl(sf->base); | 2118 | return vmcs_readl(sf->base); |
2116 | } | 2119 | } |
2117 | 2120 | ||
2118 | static int vmx_get_cpl(struct kvm_vcpu *vcpu) | 2121 | static int __vmx_get_cpl(struct kvm_vcpu *vcpu) |
2119 | { | 2122 | { |
2120 | if (!is_protmode(vcpu)) | 2123 | if (!is_protmode(vcpu)) |
2121 | return 0; | 2124 | return 0; |
@@ -2127,6 +2130,16 @@ static int vmx_get_cpl(struct kvm_vcpu *vcpu) | |||
2127 | return vmcs_read16(GUEST_CS_SELECTOR) & 3; | 2130 | return vmcs_read16(GUEST_CS_SELECTOR) & 3; |
2128 | } | 2131 | } |
2129 | 2132 | ||
2133 | static int vmx_get_cpl(struct kvm_vcpu *vcpu) | ||
2134 | { | ||
2135 | if (!test_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail)) { | ||
2136 | __set_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); | ||
2137 | to_vmx(vcpu)->cpl = __vmx_get_cpl(vcpu); | ||
2138 | } | ||
2139 | return to_vmx(vcpu)->cpl; | ||
2140 | } | ||
2141 | |||
2142 | |||
2130 | static u32 vmx_segment_access_rights(struct kvm_segment *var) | 2143 | static u32 vmx_segment_access_rights(struct kvm_segment *var) |
2131 | { | 2144 | { |
2132 | u32 ar; | 2145 | u32 ar; |
@@ -2192,6 +2205,7 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu, | |||
2192 | ar |= 0x1; /* Accessed */ | 2205 | ar |= 0x1; /* Accessed */ |
2193 | 2206 | ||
2194 | vmcs_write32(sf->ar_bytes, ar); | 2207 | vmcs_write32(sf->ar_bytes, ar); |
2208 | __clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail); | ||
2195 | } | 2209 | } |
2196 | 2210 | ||
2197 | static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) | 2211 | static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) |
@@ -4133,6 +4147,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
4133 | 4147 | ||
4134 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) | 4148 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) |
4135 | | (1 << VCPU_EXREG_RFLAGS) | 4149 | | (1 << VCPU_EXREG_RFLAGS) |
4150 | | (1 << VCPU_EXREG_CPL) | ||
4136 | | (1 << VCPU_EXREG_PDPTR) | 4151 | | (1 << VCPU_EXREG_PDPTR) |
4137 | | (1 << VCPU_EXREG_CR3)); | 4152 | | (1 << VCPU_EXREG_CR3)); |
4138 | vcpu->arch.regs_dirty = 0; | 4153 | vcpu->arch.regs_dirty = 0; |