diff mbox

[v2] KVM: nVMX: Add support for rdtscp

Message ID 55102EAA.4000502@web.de (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka March 23, 2015, 3:18 p.m. UTC
From: Jan Kiszka <jan.kiszka@siemens.com>

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.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

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(-)

Comments

Bandan Das March 23, 2015, 5:01 p.m. UTC | #1
Jan Kiszka <jan.kiszka@web.de> writes:
...
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -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;
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
>  	}
>  
>  	/* 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;
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Kiszka March 23, 2015, 6:11 p.m. UTC | #2
On 2015-03-23 18:01, Bandan Das wrote:
> Jan Kiszka <jan.kiszka@web.de> writes:
> ...
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -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;
> 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
Bandan Das March 23, 2015, 6:18 p.m. UTC | #3
Jan Kiszka <jan.kiszka@web.de> writes:

> On 2015-03-23 18:01, Bandan Das wrote:
>> Jan Kiszka <jan.kiszka@web.de> writes:
>> ...
>>> --- a/arch/x86/kvm/vmx.c
>>> +++ b/arch/x86/kvm/vmx.c
>>> @@ -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;
>> 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?

Right, definitely not a hotpath, just seems unnecessary if nested is not enabled.

Bandan
> Thanks,
> Jan
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h
index c5f1a1d..1fe9218 100644
--- a/arch/x86/include/uapi/asm/vmx.h
+++ b/arch/x86/include/uapi/asm/vmx.h
@@ -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
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 50c675b..45e0a6b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -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;