KVM: nVMX: Add support for rdtscp
PATCH 1/1 KVM: nVMX: Add support for rdtscp
From: Jan Kiszka <[email protected]>
If the guest CPU is supposed to support rdtscp and the host has rdtscp enabled in the secondary execution controls, we can also expose this feature to L1. Just extend nested_vmx_exit_handled to properly route EXIT_REASON_RDTSCP.
--- arch/x86/include/uapi/asm/vmx.h | 1 + arch/x86/kvm/vmx.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-)
arch/x86/include/uapi/asm/vmx.h +1 -0
@@ -67,6 +67,7 @@#define EXIT_REASON_EPT_VIOLATION 48#define EXIT_REASON_EPT_MISCONFIG 49#define EXIT_REASON_INVEPT 50 +#define EXIT_REASON_RDTSCP 51#define EXIT_REASON_PREEMPTION_TIMER 52#define EXIT_REASON_INVVPID 53#define EXIT_REASON_WBINVD 54
arch/x86/kvm/vmx.c +5 -1
@@ -2467,6 +2467,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) vmx->nested.nested_vmx_secondary_ctls_low =0 ; vmx->nested.nested_vmx_secondary_ctls_high &=SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
@@ -7510,7 +7511,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)return nested_cpu_has (vmcs12,CPU_BASED_INVLPG_EXITING );case EXIT_REASON_RDPMC :return nested_cpu_has (vmcs12,CPU_BASED_RDPMC_EXITING ); -case EXIT_REASON_RDTSC : +case EXIT_REASON_RDTSC :case EXIT_REASON_RDTSCP :return nested_cpu_has (vmcs12,CPU_BASED_RDTSC_EXITING );case EXIT_REASON_VMCALL :case EXIT_REASON_VMCLEAR :case EXIT_REASON_VMLAUNCH :case EXIT_REASON_VMPTRLD :
@@ -8517,6 +8518,9 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) exec_control); } } +if (!vmx->rdtscp_enabled) + vmx->nested.nested_vmx_secondary_ctls_high &= + ~SECONDARY_EXEC_RDTSCP ; }/* Exposing INVPCID only when PCID is exposed */
Signature · 1 line
2.1.4
PATCH v2 1/1 KVM: nVMX: Add support for rdtscp
From: Jan Kiszka <[email protected]>
If the guest CPU is supposed to support rdtscp and the host has rdtscp enabled in the secondary execution controls, we can also expose this feature to L1. Just extend nested_vmx_exit_handled to properly route EXIT_REASON_RDTSCP.
---
Changes in v2 (thinko in test scenario...):
- respect L1's setting of SECONDARY_EXEC_RDTSCP
arch/x86/include/uapi/asm/vmx.h | 1 + arch/x86/kvm/vmx.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
arch/x86/include/uapi/asm/vmx.h +1 -0
@@ -67,6 +67,7 @@#define EXIT_REASON_EPT_VIOLATION 48#define EXIT_REASON_EPT_MISCONFIG 49#define EXIT_REASON_INVEPT 50 +#define EXIT_REASON_RDTSCP 51#define EXIT_REASON_PREEMPTION_TIMER 52#define EXIT_REASON_INVVPID 53#define EXIT_REASON_WBINVD 54
arch/x86/kvm/vmx.c +7 -2
@@ -2467,6 +2467,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) vmx->nested.nested_vmx_secondary_ctls_low =0 ; vmx->nested.nested_vmx_secondary_ctls_high &=SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
@@ -7510,7 +7511,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)return nested_cpu_has (vmcs12,CPU_BASED_INVLPG_EXITING );case EXIT_REASON_RDPMC :return nested_cpu_has (vmcs12,CPU_BASED_RDPMC_EXITING ); -case EXIT_REASON_RDTSC : +case EXIT_REASON_RDTSC :case EXIT_REASON_RDTSCP :return nested_cpu_has (vmcs12,CPU_BASED_RDTSC_EXITING );case EXIT_REASON_VMCALL :case EXIT_REASON_VMCLEAR :case EXIT_REASON_VMLAUNCH :case EXIT_REASON_VMPTRLD :
@@ -8517,6 +8518,9 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) exec_control); } } +if (!vmx->rdtscp_enabled) + vmx->nested.nested_vmx_secondary_ctls_high &= + ~SECONDARY_EXEC_RDTSCP ; }/* Exposing INVPCID only when PCID is exposed */
@@ -9146,8 +9150,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) exec_control &= ~SECONDARY_EXEC_RDTSCP ;/* Take the following fields only from vmcs12 */ exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -SECONDARY_EXEC_APIC_REGISTER_VIRT ); +SECONDARY_EXEC_APIC_REGISTER_VIRT );if (nested_cpu_has (vmcs12,CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )) exec_control |= vmcs12->secondary_vm_exec_control;
Signature · 1 line
2.1.4
Jan Kiszka <[email protected]> writes:
...
Quoted 20 lines
arch/x86/kvm/vmx.c +2
-1@@ -2467,6 +2467,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) vmx->nested.nested_vmx_secondary_ctls_low =0 ; vmx->nested.nested_vmx_secondary_ctls_high &=SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |@@ -7510,7 +7511,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)return nested_cpu_has (vmcs12,CPU_BASED_INVLPG_EXITING );case EXIT_REASON_RDPMC :return nested_cpu_has (vmcs12,CPU_BASED_RDPMC_EXITING ); -case EXIT_REASON_RDTSC : +case EXIT_REASON_RDTSC :case EXIT_REASON_RDTSCP :return nested_cpu_has (vmcs12,CPU_BASED_RDTSC_EXITING );case EXIT_REASON_VMCALL :case EXIT_REASON_VMCLEAR :case EXIT_REASON_VMLAUNCH :case EXIT_REASON_VMPTRLD :
arch/x86/kvm/vmx.c static void vmx_cpuid_update(struct kvm_vcpu *vcpu) · line 8523
Quoted 6 lines
arch/x86/kvm/vmx.c +3
-0@@ -8517,6 +8518,9 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) exec_control); } } +if (!vmx->rdtscp_enabled) + vmx->nested.nested_vmx_secondary_ctls_high &= + ~SECONDARY_EXEC_RDTSCP ;
No need to do this if nested is not enabled ? Or just
a "if (nested)" in the prior if else loop should be enough I think.
Bandan
Quoted 14 lines
arch/x86/kvm/vmx.c +2
-1}/* Exposing INVPCID only when PCID is exposed */ @@ -9146,8 +9150,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) exec_control &= ~SECONDARY_EXEC_RDTSCP ;/* Take the following fields only from vmcs12 */ exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -SECONDARY_EXEC_APIC_REGISTER_VIRT ); +SECONDARY_EXEC_APIC_REGISTER_VIRT );if (nested_cpu_has (vmcs12,CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )) exec_control |= vmcs12->secondary_vm_exec_control;
Quoted 22 lines · Bandan Das
Jan Kiszka <[email protected]> writes:
...Quoted 20 lines
arch/x86/kvm/vmx.c +2
-1@@ -2467,6 +2467,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) vmx->nested.nested_vmx_secondary_ctls_low =0 ; vmx->nested.nested_vmx_secondary_ctls_high &=SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |@@ -7510,7 +7511,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)return nested_cpu_has (vmcs12,CPU_BASED_INVLPG_EXITING );case EXIT_REASON_RDPMC :return nested_cpu_has (vmcs12,CPU_BASED_RDPMC_EXITING ); -case EXIT_REASON_RDTSC : +case EXIT_REASON_RDTSC :case EXIT_REASON_RDTSCP :return nested_cpu_has (vmcs12,CPU_BASED_RDTSC_EXITING );case EXIT_REASON_VMCALL :case EXIT_REASON_VMCLEAR :case EXIT_REASON_VMLAUNCH :case EXIT_REASON_VMPTRLD :@@ -8517,6 +8518,9 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
Quoted 8 lines
arch/x86/kvm/vmx.c static void vmx_cpuid_update(struct kvm_vcpu *vcpu) · line 8523
Quoted 6 lines
arch/x86/kvm/vmx.c +3
-0exec_control); } } +if (!vmx->rdtscp_enabled) + vmx->nested.nested_vmx_secondary_ctls_high &= + ~SECONDARY_EXEC_RDTSCP ;No need to do this if nested is not enabled ? Or just
a "if (nested)" in the prior if else loop should be enough I think.
I can add this - but this is far away from being a hotpath. What would be the benefit?
Thanks,
Jan
Quoted 32 lines · Jan Kiszka
Quoted 22 lines · Bandan Das
Jan Kiszka <[email protected]> writes:
...Quoted 20 lines
arch/x86/kvm/vmx.c +2
-1@@ -2467,6 +2467,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) vmx->nested.nested_vmx_secondary_ctls_low =0 ; vmx->nested.nested_vmx_secondary_ctls_high &=SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |@@ -7510,7 +7511,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)return nested_cpu_has (vmcs12,CPU_BASED_INVLPG_EXITING );case EXIT_REASON_RDPMC :return nested_cpu_has (vmcs12,CPU_BASED_RDPMC_EXITING ); -case EXIT_REASON_RDTSC : +case EXIT_REASON_RDTSC :case EXIT_REASON_RDTSCP :return nested_cpu_has (vmcs12,CPU_BASED_RDTSC_EXITING );case EXIT_REASON_VMCALL :case EXIT_REASON_VMCLEAR :case EXIT_REASON_VMLAUNCH :case EXIT_REASON_VMPTRLD :@@ -8517,6 +8518,9 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)Quoted 8 lines
arch/x86/kvm/vmx.c static void vmx_cpuid_update(struct kvm_vcpu *vcpu) · line 8523
Quoted 6 lines
arch/x86/kvm/vmx.c +3
-0exec_control); } } +if (!vmx->rdtscp_enabled) + vmx->nested.nested_vmx_secondary_ctls_high &= + ~SECONDARY_EXEC_RDTSCP ;No need to do this if nested is not enabled ? Or just
a "if (nested)" in the prior if else loop should be enough I think.
Quoted 2 lines
I can add this - but this is far away from being a hotpath. What would be the benefit?
Right, definitely not a hotpath, just seems unnecessary if nested is not enabled.
Bandan
Quoted 2 lines
Thanks,
Jan
PATCH v3 1/1 KVM: nVMX: Add support for rdtscp
From: Jan Kiszka <[email protected]>
If the guest CPU is supposed to support rdtscp and the host has rdtscp enabled in the secondary execution controls, we can also expose this feature to L1. Just extend nested_vmx_exit_handled to properly route EXIT_REASON_RDTSCP.
---
Changes in v3:
- avoid needlessly touching vmx->nested if nested is off
arch/x86/include/uapi/asm/vmx.h | 1 + arch/x86/kvm/vmx.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
arch/x86/include/uapi/asm/vmx.h +1 -0
@@ -67,6 +67,7 @@#define EXIT_REASON_EPT_VIOLATION 48#define EXIT_REASON_EPT_MISCONFIG 49#define EXIT_REASON_INVEPT 50 +#define EXIT_REASON_RDTSCP 51#define EXIT_REASON_PREEMPTION_TIMER 52#define EXIT_REASON_INVVPID 53#define EXIT_REASON_WBINVD 54
arch/x86/kvm/vmx.c +7 -2
@@ -2467,6 +2467,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) vmx->nested.nested_vmx_secondary_ctls_low =0 ; vmx->nested.nested_vmx_secondary_ctls_high &=SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
@@ -7510,7 +7511,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)return nested_cpu_has (vmcs12,CPU_BASED_INVLPG_EXITING );case EXIT_REASON_RDPMC :return nested_cpu_has (vmcs12,CPU_BASED_RDPMC_EXITING ); -case EXIT_REASON_RDTSC : +case EXIT_REASON_RDTSC :case EXIT_REASON_RDTSCP :return nested_cpu_has (vmcs12,CPU_BASED_RDTSC_EXITING );case EXIT_REASON_VMCALL :case EXIT_REASON_VMCLEAR :case EXIT_REASON_VMLAUNCH :case EXIT_REASON_VMPTRLD :
@@ -8517,6 +8518,9 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) exec_control); } } +if (nested && !vmx->rdtscp_enabled) + vmx->nested.nested_vmx_secondary_ctls_high &= + ~SECONDARY_EXEC_RDTSCP ; }/* Exposing INVPCID only when PCID is exposed */
@@ -9146,8 +9150,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) exec_control &= ~SECONDARY_EXEC_RDTSCP ;/* Take the following fields only from vmcs12 */ exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +SECONDARY_EXEC_RDTSCP |SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -SECONDARY_EXEC_APIC_REGISTER_VIRT ); +SECONDARY_EXEC_APIC_REGISTER_VIRT );if (nested_cpu_has (vmcs12,CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )) exec_control |= vmcs12->secondary_vm_exec_control;
Signature · 1 line
2.1.4
Marcelo Tosatti
AppliedQuoted 8 lines · Jan Kiszka
From: Jan Kiszka <[email protected]>
If the guest CPU is supposed to support rdtscp and the host has rdtscp enabled in the secondary execution controls, we can also expose this feature to L1. Just extend
nested_vmx_exit_handledto properly routeEXIT_REASON_RDTSCP.Signed-off-by Jan Kiszka <[email protected]>
Applied, thanks.