KVM: VMX: Optimize vmx_get_rflags()
authorAvi Kivity <avi@redhat.com>
Mon, 7 Mar 2011 10:51:22 +0000 (12:51 +0200)
committerAvi Kivity <avi@redhat.com>
Wed, 11 May 2011 11:56:54 +0000 (07:56 -0400)
If called several times within the same exit, return cached results.

Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/vmx.c

index c8af0991fdf0c4210c751e6f46aba6091f4c47ac..5af426464954ebf4c12bd246b05d49b430a9fd77 100644 (file)
@@ -118,6 +118,7 @@ enum kvm_reg {
 enum kvm_reg_ex {
        VCPU_EXREG_PDPTR = NR_VCPU_REGS,
        VCPU_EXREG_CR3,
+       VCPU_EXREG_RFLAGS,
 };
 
 enum {
index d09833e45f6f1c9f2a5c0408f48215bb2ffff44e..4d117072acf85040f0fab5b207c575c8cf2f4673 100644 (file)
@@ -130,6 +130,7 @@ struct vcpu_vmx {
        u8                    fail;
        u32                   exit_intr_info;
        u32                   idt_vectoring_info;
+       ulong                 rflags;
        struct shared_msr_entry *guest_msrs;
        int                   nmsrs;
        int                   save_nmsrs;
@@ -970,17 +971,23 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 {
        unsigned long rflags, save_rflags;
 
-       rflags = vmcs_readl(GUEST_RFLAGS);
-       if (to_vmx(vcpu)->rmode.vm86_active) {
-               rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
-               save_rflags = to_vmx(vcpu)->rmode.save_rflags;
-               rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
+       if (!test_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail)) {
+               __set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
+               rflags = vmcs_readl(GUEST_RFLAGS);
+               if (to_vmx(vcpu)->rmode.vm86_active) {
+                       rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+                       save_rflags = to_vmx(vcpu)->rmode.save_rflags;
+                       rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
+               }
+               to_vmx(vcpu)->rflags = rflags;
        }
-       return rflags;
+       return to_vmx(vcpu)->rflags;
 }
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
+       __set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
+       to_vmx(vcpu)->rflags = rflags;
        if (to_vmx(vcpu)->rmode.vm86_active) {
                to_vmx(vcpu)->rmode.save_rflags = rflags;
                rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
@@ -4124,6 +4131,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_PDPTR)
                                  | (1 << VCPU_EXREG_CR3));
        vcpu->arch.regs_dirty = 0;