diff mbox series

[11/11] KVM: vmx: skip VMWRITE of HOST_{FS,GS}_BASE when possible

Message ID 20180723193250.13555-12-sean.j.christopherson@intel.com (mailing list archive)
State New, archived
Headers show
Series KVM: vmx: optimize VMWRITEs to host FS/GS fields | expand

Commit Message

Sean Christopherson July 23, 2018, 7:32 p.m. UTC
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>
---
 arch/x86/kvm/vmx.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

Comments

Peter Shier July 24, 2018, 10:41 p.m. UTC | #1
On Mon, Jul 23, 2018 at 12:33 PM Sean Christopherson
<sean.j.christopherson@intel.com> wrote:
>
> 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>

Reviewed-by: Peter Shier <pshier@google.com>
Tested-by: Peter Shier <pshier@google.com>
diff mbox series

Patch

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 9f3bd199dc8c..32ed0c154df3 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -212,6 +212,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
@@ -2633,9 +2635,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;
+	}
 
 	if (boot_cpu_has(X86_FEATURE_MPX))
 		rdmsrl(MSR_IA32_BNDCFGS, vmx->msr_host_bndcfgs);