Skip to content

Commit

Permalink
KVM: vmx: skip VMWRITE of HOST_{FS,GS}_BASE when possible
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sean Christopherson authored and Paolo Bonzini committed Aug 6, 2018
1 parent 8f21a0b commit 5e079c7
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions arch/x86/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 5e079c7

Please sign in to comment.