Skip to content

Commit e69e72f

Browse files
taoxu916bonzini
authored andcommitted
KVM: x86: Add support for user wait instructions
UMONITOR, UMWAIT and TPAUSE are a set of user wait instructions. This patch adds support for user wait instructions in KVM. Availability of the user wait instructions is indicated by the presence of the CPUID feature flag WAITPKG CPUID.0x07.0x0:ECX[5]. User wait instructions may be executed at any privilege level, and use 32bit IA32_UMWAIT_CONTROL MSR to set the maximum time. The behavior of user wait instructions in VMX non-root operation is determined first by the setting of the "enable user wait and pause" secondary processor-based VM-execution control bit 26. If the VM-execution control is 0, UMONITOR/UMWAIT/TPAUSE cause an invalid-opcode exception (#UD). If the VM-execution control is 1, treatment is based on the setting of the “RDTSC exiting†VM-execution control. Because KVM never enables RDTSC exiting, if the instruction causes a delay, the amount of time delayed is called here the physical delay. The physical delay is first computed by determining the virtual delay. If IA32_UMWAIT_CONTROL[31:2] is zero, the virtual delay is the value in EDX:EAX minus the value that RDTSC would return; if IA32_UMWAIT_CONTROL[31:2] is not zero, the virtual delay is the minimum of that difference and AND(IA32_UMWAIT_CONTROL,FFFFFFFCH). Because umwait and tpause can put a (psysical) CPU into a power saving state, by default we dont't expose it to kvm and enable it only when guest CPUID has it. Detailed information about user wait instructions can be found in the latest Intel 64 and IA-32 Architectures Software Developer's Manual. Co-developed-by: Jingqi Liu <[email protected]> Signed-off-by: Jingqi Liu <[email protected]> Signed-off-by: Tao Xu <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 41577ab commit e69e72f

File tree

5 files changed

+27
-1
lines changed

5 files changed

+27
-1
lines changed

arch/x86/include/asm/vmx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#define SECONDARY_EXEC_PT_USE_GPA 0x01000000
7070
#define SECONDARY_EXEC_MODE_BASED_EPT_EXEC 0x00400000
7171
#define SECONDARY_EXEC_TSC_SCALING 0x02000000
72+
#define SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE 0x04000000
7273

7374
#define PIN_BASED_EXT_INTR_MASK 0x00000001
7475
#define PIN_BASED_NMI_EXITING 0x00000008

arch/x86/kvm/cpuid.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ static inline void do_cpuid_7_mask(struct kvm_cpuid_entry2 *entry, int index)
360360
F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ |
361361
F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) |
362362
F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) |
363-
F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B);
363+
F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/;
364364

365365
/* cpuid 7.0.edx*/
366366
const u32 kvm_cpuid_7_0_edx_x86_features =

arch/x86/kvm/vmx/capabilities.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,12 @@ static inline bool vmx_xsaves_supported(void)
247247
SECONDARY_EXEC_XSAVES;
248248
}
249249

250+
static inline bool vmx_waitpkg_supported(void)
251+
{
252+
return vmcs_config.cpu_based_2nd_exec_ctrl &
253+
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
254+
}
255+
250256
static inline bool cpu_has_vmx_tsc_scaling(void)
251257
{
252258
return vmcs_config.cpu_based_2nd_exec_ctrl &

arch/x86/kvm/vmx/nested.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12)
20892089
SECONDARY_EXEC_ENABLE_INVPCID |
20902090
SECONDARY_EXEC_RDTSCP |
20912091
SECONDARY_EXEC_XSAVES |
2092+
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE |
20922093
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
20932094
SECONDARY_EXEC_APIC_REGISTER_VIRT |
20942095
SECONDARY_EXEC_ENABLE_VMFUNC);

arch/x86/kvm/vmx/vmx.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2323,6 +2323,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
23232323
SECONDARY_EXEC_RDRAND_EXITING |
23242324
SECONDARY_EXEC_ENABLE_PML |
23252325
SECONDARY_EXEC_TSC_SCALING |
2326+
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE |
23262327
SECONDARY_EXEC_PT_USE_GPA |
23272328
SECONDARY_EXEC_PT_CONCEAL_VMX |
23282329
SECONDARY_EXEC_ENABLE_VMFUNC |
@@ -4059,6 +4060,23 @@ static void vmx_compute_secondary_exec_control(struct vcpu_vmx *vmx)
40594060
}
40604061
}
40614062

4063+
if (vmx_waitpkg_supported()) {
4064+
bool waitpkg_enabled =
4065+
guest_cpuid_has(vcpu, X86_FEATURE_WAITPKG);
4066+
4067+
if (!waitpkg_enabled)
4068+
exec_control &= ~SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
4069+
4070+
if (nested) {
4071+
if (waitpkg_enabled)
4072+
vmx->nested.msrs.secondary_ctls_high |=
4073+
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
4074+
else
4075+
vmx->nested.msrs.secondary_ctls_high &=
4076+
~SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
4077+
}
4078+
}
4079+
40624080
vmx->secondary_exec_control = exec_control;
40634081
}
40644082

0 commit comments

Comments
 (0)