Optimize atomic efer loading
cover Optimize atomic efer loading
In some cases we resort to loading EFER via the atomic msr load on entry/exit facility. This is incredibly slow. Use the faster entry/exit LOAD_IA32_EFER controls instead, when available.
Avi Kivity (2):
KVM: VMX: Add definitions for more vm entry/exit control bits
KVM: VMX: Optimize atomic EFER load
arch/x86/include/asm/vmx.h | 8 ++++++++ arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 0 deletions(-)
PATCH 1/2 KVM: VMX: Add definitions for more vm entry/exit control bits
--- arch/x86/include/asm/vmx.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
arch/x86/include/asm/vmx.h +8 -0
@@ -66,15 +66,23 @@#define PIN_BASED_NMI_EXITING 0x00000008#define PIN_BASED_VIRTUAL_NMIS 0x00000020 +#define VM_EXIT_SAVE_DEBUG_CONTROLS 0x00000002#define VM_EXIT_HOST_ADDR_SPACE_SIZE 0x00000200 +#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL 0x00001000#define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000#define VM_EXIT_SAVE_IA32_PAT 0x00040000#define VM_EXIT_LOAD_IA32_PAT 0x00080000 +#define VM_EXIT_SAVE_IA32_EFER 0x00100000 +#define VM_EXIT_LOAD_IA32_EFER 0x00200000 +#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER 0x00400000 +#define VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000002#define VM_ENTRY_IA32E_MODE 0x00000200#define VM_ENTRY_SMM 0x00000400#define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 +#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL 0x00002000#define VM_ENTRY_LOAD_IA32_PAT 0x00004000 +#define VM_ENTRY_LOAD_IA32_EFER 0x00008000/* VMCS Encodings */ enum vmcs_field {
Signature · 1 line
1.7.1
PATCH 2/2 KVM: VMX: Optimize atomic EFER load
In reply to Avi KivityWhen NX is enabled on the host but not on the guest, we use the entry/exit msr load facility, which is slow. Optimize it to use entry/exit efer load, which is ~1200 cycles faster.
--- arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-)
arch/x86/kvm/vmx.c +30 -0
@@ -191,6 +191,8 @@ static unsigned long *vmx_io_bitmap_b;static unsigned long *vmx_msr_bitmap_legacy;static unsigned long *vmx_msr_bitmap_longmode; +static bool cpu_has_load_ia32_efer; + static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS);static DEFINE_SPINLOCK (vmx_vpid_lock);
@@ -664,6 +666,12 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr)unsigned i;struct msr_autoload *m = &vmx->msr_autoload; +if (msr ==MSR_EFER && cpu_has_load_ia32_efer) { +vmcs_clear_bits (VM_ENTRY_CONTROLS ,VM_ENTRY_LOAD_IA32_EFER ); +vmcs_clear_bits (VM_EXIT_CONTROLS ,VM_EXIT_LOAD_IA32_EFER ); +return ; + } +for (i =0 ; i < m->nr; ++i)if (m->guest[i].index == msr)break ;
@@ -683,6 +691,14 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr,unsigned i;struct msr_autoload *m = &vmx->msr_autoload; +if (msr ==MSR_EFER && cpu_has_load_ia32_efer) { +vmcs_write64 (GUEST_IA32_EFER , guest_val); +vmcs_write64 (HOST_IA32_EFER , host_val); +vmcs_set_bits (VM_ENTRY_CONTROLS ,VM_ENTRY_LOAD_IA32_EFER ); +vmcs_set_bits (VM_EXIT_CONTROLS ,VM_EXIT_LOAD_IA32_EFER ); +return ; + } +for (i =0 ; i < m->nr; ++i)if (m->guest[i].index == msr)break ;
@@ -1418,6 +1434,14 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,return 0 ; } +static __init bool allow_1_setting (u32 msr,u32 ctl) +{ +u32 vmx_msr_low, vmx_msr_high; + +rdmsr (msr, vmx_msr_low, vmx_msr_high); +return vmx_msr_high & ctl; +} +static __init int setup_vmcs_config (struct vmcs_config *vmcs_conf) {u32 vmx_msr_low, vmx_msr_high;
@@ -1532,6 +1556,12 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) vmcs_conf->vmexit_ctrl = _vmexit_control; vmcs_conf->vmentry_ctrl = _vmentry_control; + cpu_has_load_ia32_efer = +allow_1_setting (MSR_IA32_VMX_ENTRY_CTLS , +VM_ENTRY_LOAD_IA32_EFER ) + &&allow_1_setting (MSR_IA32_VMX_EXIT_CTLS , +VM_EXIT_LOAD_IA32_EFER ); +return 0 ; }
Signature · 1 line
1.7.1
Marcelo Tosatti
AppliedQuoted 11 lines · Avi Kivity
In some cases we resort to loading EFER via the atomic msr load on entry/exit facility. This is incredibly slow. Use the faster entry/exit
LOAD_IA32_EFERcontrols instead, when available.Avi Kivity (2):
KVM: VMX: Add definitions for more vm entry/exit control bits
KVM: VMX: Optimize atomic EFER loadarch/x86/include/asm/vmx.h | 8 ++++++++ arch/x86/kvm/vmx.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 0 deletions(-)
Applied, thanks.