KVM: vmx: skip VMWRITE of HOST_{FS,GS}_BASE when possible
authorSean Christopherson <sean.j.christopherson@intel.com>
Mon, 23 Jul 2018 19:32:50 +0000 (12:32 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 6 Aug 2018 15:59:17 +0000 (17:59 +0200)
The host's FS.base and GS.base rarely change, e.g. ~0.1% of host/guest
swaps on my system.  Cache the last value written to the VMCS and skip
the VMWRITE to the associated VMCS fields when loading host state if
the value hasn't changed since the last VMWRITE.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/vmx.c

index 4937e11f971a79664bee308b925eacd25c0f7829..b23ecc04ca51254264c2746d3aca156cd9d05b58 100644 (file)
@@ -226,6 +226,8 @@ struct vmcs {
 struct vmcs_host_state {
        unsigned long cr3;      /* May not match real cr3 */
        unsigned long cr4;      /* May not match real cr4 */
+       unsigned long gs_base;
+       unsigned long fs_base;
 
        u16           fs_sel, gs_sel, ldt_sel;
 #ifdef CONFIG_X86_64
@@ -2731,9 +2733,14 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
                        vmcs_write16(HOST_GS_SELECTOR, 0);
                host_state->gs_sel = gs_sel;
        }
-
-       vmcs_writel(HOST_FS_BASE, fs_base);
-       vmcs_writel(HOST_GS_BASE, gs_base);
+       if (unlikely(fs_base != host_state->fs_base)) {
+               vmcs_writel(HOST_FS_BASE, fs_base);
+               host_state->fs_base = fs_base;
+       }
+       if (unlikely(gs_base != host_state->gs_base)) {
+               vmcs_writel(HOST_GS_BASE, gs_base);
+               host_state->gs_base = gs_base;
+       }
 
        for (i = 0; i < vmx->save_nmsrs; ++i)
                kvm_set_shared_msr(vmx->guest_msrs[i].index,