Commit 5e079c7e authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini

KVM: vmx: skip VMWRITE of HOST_{FS,GS}_BASE when possible

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: default avatarSean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 8f21a0bb
...@@ -226,6 +226,8 @@ struct vmcs { ...@@ -226,6 +226,8 @@ struct vmcs {
struct vmcs_host_state { struct vmcs_host_state {
unsigned long cr3; /* May not match real cr3 */ unsigned long cr3; /* May not match real cr3 */
unsigned long cr4; /* May not match real cr4 */ unsigned long cr4; /* May not match real cr4 */
unsigned long gs_base;
unsigned long fs_base;
u16 fs_sel, gs_sel, ldt_sel; u16 fs_sel, gs_sel, ldt_sel;
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
...@@ -2731,9 +2733,14 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) ...@@ -2731,9 +2733,14 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
vmcs_write16(HOST_GS_SELECTOR, 0); vmcs_write16(HOST_GS_SELECTOR, 0);
host_state->gs_sel = gs_sel; host_state->gs_sel = gs_sel;
} }
if (unlikely(fs_base != host_state->fs_base)) {
vmcs_writel(HOST_FS_BASE, 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); vmcs_writel(HOST_GS_BASE, gs_base);
host_state->gs_base = gs_base;
}
for (i = 0; i < vmx->save_nmsrs; ++i) for (i = 0; i < vmx->save_nmsrs; ++i)
kvm_set_shared_msr(vmx->guest_msrs[i].index, kvm_set_shared_msr(vmx->guest_msrs[i].index,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment