diff options
author | Avi Kivity <avi@redhat.com> | 2011-03-07 05:51:22 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-11 07:56:54 -0400 |
commit | 6de12732c42c7070af42e3d6e42ecee2838fc920 (patch) | |
tree | 54de4d4a9407d071229daf42ad37042affbc61d6 /arch/x86 | |
parent | f6e78475894d6534d7d62714a95e2265f53d2a92 (diff) |
KVM: VMX: Optimize vmx_get_rflags()
If called several times within the same exit, return cached results.
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 20 |
2 files changed, 15 insertions, 6 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c8af0991fdf..5af42646495 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -118,6 +118,7 @@ enum kvm_reg { | |||
118 | enum kvm_reg_ex { | 118 | enum kvm_reg_ex { |
119 | VCPU_EXREG_PDPTR = NR_VCPU_REGS, | 119 | VCPU_EXREG_PDPTR = NR_VCPU_REGS, |
120 | VCPU_EXREG_CR3, | 120 | VCPU_EXREG_CR3, |
121 | VCPU_EXREG_RFLAGS, | ||
121 | }; | 122 | }; |
122 | 123 | ||
123 | enum { | 124 | enum { |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index d09833e45f6..4d117072acf 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -130,6 +130,7 @@ struct vcpu_vmx { | |||
130 | u8 fail; | 130 | u8 fail; |
131 | u32 exit_intr_info; | 131 | u32 exit_intr_info; |
132 | u32 idt_vectoring_info; | 132 | u32 idt_vectoring_info; |
133 | ulong rflags; | ||
133 | struct shared_msr_entry *guest_msrs; | 134 | struct shared_msr_entry *guest_msrs; |
134 | int nmsrs; | 135 | int nmsrs; |
135 | int save_nmsrs; | 136 | int save_nmsrs; |
@@ -970,17 +971,23 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) | |||
970 | { | 971 | { |
971 | unsigned long rflags, save_rflags; | 972 | unsigned long rflags, save_rflags; |
972 | 973 | ||
973 | rflags = vmcs_readl(GUEST_RFLAGS); | 974 | if (!test_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail)) { |
974 | if (to_vmx(vcpu)->rmode.vm86_active) { | 975 | __set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail); |
975 | rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS; | 976 | rflags = vmcs_readl(GUEST_RFLAGS); |
976 | save_rflags = to_vmx(vcpu)->rmode.save_rflags; | 977 | if (to_vmx(vcpu)->rmode.vm86_active) { |
977 | rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; | 978 | rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS; |
979 | save_rflags = to_vmx(vcpu)->rmode.save_rflags; | ||
980 | rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; | ||
981 | } | ||
982 | to_vmx(vcpu)->rflags = rflags; | ||
978 | } | 983 | } |
979 | return rflags; | 984 | return to_vmx(vcpu)->rflags; |
980 | } | 985 | } |
981 | 986 | ||
982 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | 987 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) |
983 | { | 988 | { |
989 | __set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail); | ||
990 | to_vmx(vcpu)->rflags = rflags; | ||
984 | if (to_vmx(vcpu)->rmode.vm86_active) { | 991 | if (to_vmx(vcpu)->rmode.vm86_active) { |
985 | to_vmx(vcpu)->rmode.save_rflags = rflags; | 992 | to_vmx(vcpu)->rmode.save_rflags = rflags; |
986 | rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; | 993 | rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
@@ -4124,6 +4131,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
4124 | ); | 4131 | ); |
4125 | 4132 | ||
4126 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) | 4133 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) |
4134 | | (1 << VCPU_EXREG_RFLAGS) | ||
4127 | | (1 << VCPU_EXREG_PDPTR) | 4135 | | (1 << VCPU_EXREG_PDPTR) |
4128 | | (1 << VCPU_EXREG_CR3)); | 4136 | | (1 << VCPU_EXREG_CR3)); |
4129 | vcpu->arch.regs_dirty = 0; | 4137 | vcpu->arch.regs_dirty = 0; |