* [PATCH] KVM: svm: add support for RDTSCP
@ 2015-11-12 13:49 Paolo Bonzini
2015-11-12 13:49 ` [PATCH] KVM: x86: expose MSR_TSC_AUX to userspace Paolo Bonzini
2015-11-12 14:45 ` [PATCH] KVM: svm: add support for RDTSCP Joerg Roedel
0 siblings, 2 replies; 6+ messages in thread
From: Paolo Bonzini @ 2015-11-12 13:49 UTC (permalink / raw)
To: kvm, linux-kernel; +Cc: Joerg Roedel
RDTSCP was never supported for AMD CPUs, which nobody noticed because
Linux does not use it. But exactly the fact that Linux does not
use it makes the implementation very simple; we can freely trash
MSR_TSC_AUX while running the guest.
Cc: Joerg Roedel <joro@8bytes.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/svm.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 83a1c64..c302614 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -86,6 +86,7 @@ static const u32 host_save_user_msrs[] = {
MSR_FS_BASE,
#endif
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
+ MSR_TSC_AUX,
};
#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
@@ -135,6 +136,7 @@ struct vcpu_svm {
uint64_t asid_generation;
uint64_t sysenter_esp;
uint64_t sysenter_eip;
+ uint64_t tsc_aux;
u64 next_rip;
@@ -1238,6 +1240,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
}
}
+ /* This assumes that the kernel never uses MSR_TSC_AUX */
+ if (static_cpu_has(X86_FEATURE_RDTSCP))
+ wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
}
static void svm_vcpu_put(struct kvm_vcpu *vcpu)
@@ -3024,6 +3029,11 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_IA32_SYSENTER_ESP:
msr_info->data = svm->sysenter_esp;
break;
+ case MSR_TSC_AUX:
+ if (!boot_cpu_has(X86_FEATURE_RDTSCP))
+ return 1;
+ msr_info->data = svm->tsc_aux;
+ break;
/*
* Nobody will change the following 5 values in the VMCB so we can
* safely return them on rdmsr. They will always be 0 until LBRV is
@@ -3145,6 +3155,18 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
svm->sysenter_esp = data;
svm->vmcb->save.sysenter_esp = data;
break;
+ case MSR_TSC_AUX:
+ if (!boot_cpu_has(X86_FEATURE_RDTSCP))
+ return 1;
+
+ /*
+ * This is rare, so we update the MSR here instead of using
+ * direct_access_msrs. Doing that would require a rdmsr in
+ * svm_vcpu_put.
+ */
+ svm->tsc_aux = data;
+ wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
+ break;
case MSR_IA32_DEBUGCTLMSR:
if (!boot_cpu_has(X86_FEATURE_LBRV)) {
vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
@@ -4037,7 +4059,7 @@ static int svm_get_lpage_level(void)
static bool svm_rdtscp_supported(void)
{
- return false;
+ return boot_cpu_has(X86_FEATURE_RDTSCP);
}
static bool svm_invpcid_supported(void)
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH] KVM: x86: expose MSR_TSC_AUX to userspace
2015-11-12 13:49 [PATCH] KVM: svm: add support for RDTSCP Paolo Bonzini
@ 2015-11-12 13:49 ` Paolo Bonzini
[not found] ` <CA+0KQ4P7Hy5C1MFHPN0Fib2+O3xE1j-px4NhBvU_CncPmTenHA@mail.gmail.com>
2015-11-12 14:45 ` [PATCH] KVM: svm: add support for RDTSCP Joerg Roedel
1 sibling, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2015-11-12 13:49 UTC (permalink / raw)
To: kvm, linux-kernel; +Cc: Radim Krcmar, stable
If we do not do this, it is not properly saved and restored across
migration. Windows notices due to its self-protection mechanisms,
and is very upset about it (blue screen of death).
Cc: Radim Krcmar <rkrcmar@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/x86.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index aba7f95..377160d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -950,7 +950,7 @@ static u32 msrs_to_save[] = {
MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
#endif
MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
- MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS
+ MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
};
static unsigned num_msrs_to_save;
@@ -3979,16 +3979,17 @@ static void kvm_init_msr_list(void)
/*
* Even MSRs that are valid in the host may not be exposed
- * to the guests in some cases. We could work around this
- * in VMX with the generic MSR save/load machinery, but it
- * is not really worthwhile since it will really only
- * happen with nested virtualization.
+ * to the guests in some cases.
*/
switch (msrs_to_save[i]) {
case MSR_IA32_BNDCFGS:
if (!kvm_x86_ops->mpx_supported())
continue;
break;
+ case MSR_TSC_AUX:
+ if (!kvm_x86_ops->rdtscp_supported())
+ continue;
+ break;
default:
break;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH] KVM: svm: add support for RDTSCP
2015-11-12 13:49 [PATCH] KVM: svm: add support for RDTSCP Paolo Bonzini
2015-11-12 13:49 ` [PATCH] KVM: x86: expose MSR_TSC_AUX to userspace Paolo Bonzini
@ 2015-11-12 14:45 ` Joerg Roedel
2015-11-12 16:18 ` Paolo Bonzini
1 sibling, 1 reply; 6+ messages in thread
From: Joerg Roedel @ 2015-11-12 14:45 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: kvm, linux-kernel
Hi Paolo,
On Thu, Nov 12, 2015 at 02:49:16PM +0100, Paolo Bonzini wrote:
> RDTSCP was never supported for AMD CPUs, which nobody noticed because
> Linux does not use it. But exactly the fact that Linux does not
> use it makes the implementation very simple; we can freely trash
> MSR_TSC_AUX while running the guest.
>
> Cc: Joerg Roedel <joro@8bytes.org>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> arch/x86/kvm/svm.c | 24 +++++++++++++++++++++++-
> 1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 83a1c64..c302614 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -86,6 +86,7 @@ static const u32 host_save_user_msrs[] = {
> MSR_FS_BASE,
> #endif
> MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
> + MSR_TSC_AUX,
> };
>
> #define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
> @@ -135,6 +136,7 @@ struct vcpu_svm {
> uint64_t asid_generation;
> uint64_t sysenter_esp;
> uint64_t sysenter_eip;
> + uint64_t tsc_aux;
>
> u64 next_rip;
>
> @@ -1238,6 +1240,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
> wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
> }
> }
> + /* This assumes that the kernel never uses MSR_TSC_AUX */
> + if (static_cpu_has(X86_FEATURE_RDTSCP))
> + wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
> }
Hmm, you seem to still intercept MSR_TSC_AUX, is that intentional?
Loading the guests value into the real cpu msr only makes sense to me
when the MSR is no longer intercepted.
Joerg
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] KVM: svm: add support for RDTSCP
2015-11-12 14:45 ` [PATCH] KVM: svm: add support for RDTSCP Joerg Roedel
@ 2015-11-12 16:18 ` Paolo Bonzini
0 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2015-11-12 16:18 UTC (permalink / raw)
To: Joerg Roedel; +Cc: kvm, linux-kernel
On 12/11/2015 15:45, Joerg Roedel wrote:
> Hi Paolo,
>
> On Thu, Nov 12, 2015 at 02:49:16PM +0100, Paolo Bonzini wrote:
>> RDTSCP was never supported for AMD CPUs, which nobody noticed because
>> Linux does not use it. But exactly the fact that Linux does not
>> use it makes the implementation very simple; we can freely trash
>> MSR_TSC_AUX while running the guest.
>>
>> Cc: Joerg Roedel <joro@8bytes.org>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>> arch/x86/kvm/svm.c | 24 +++++++++++++++++++++++-
>> 1 file changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
>> index 83a1c64..c302614 100644
>> --- a/arch/x86/kvm/svm.c
>> +++ b/arch/x86/kvm/svm.c
>> @@ -86,6 +86,7 @@ static const u32 host_save_user_msrs[] = {
>> MSR_FS_BASE,
>> #endif
>> MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
>> + MSR_TSC_AUX,
>> };
>>
>> #define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
>> @@ -135,6 +136,7 @@ struct vcpu_svm {
>> uint64_t asid_generation;
>> uint64_t sysenter_esp;
>> uint64_t sysenter_eip;
>> + uint64_t tsc_aux;
>>
>> u64 next_rip;
>>
>> @@ -1238,6 +1240,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>> wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
>> }
>> }
>> + /* This assumes that the kernel never uses MSR_TSC_AUX */
>> + if (static_cpu_has(X86_FEATURE_RDTSCP))
>> + wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
>> }
>
> Hmm, you seem to still intercept MSR_TSC_AUX, is that intentional?
Yes. If I didn't intercept MSR_TSC_AUX, I would have to read it into
svm->tsc_aux on every svm_vcpu_put. Because writing MSR_TSC_AUX is a
rare operation, I intercept the write, and update both svm->tsc_aux and
the processor MSR_TSC_AUX in svm_set_msr.
This is different from other host_save_msrs because the processor does
not save MSR_TSC_AUX automatically in the VMCB. As remarked above, it
only works because the kernel never uses RDTSCP.
> Loading the guests value into the real cpu msr only makes sense to me
> when the MSR is no longer intercepted.
It's necessary for the correct operation of RDTSCP. Since we don't
intercept RDTSCP, we need to load MSR_TSC_AUX.
Paolo
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-11-13 17:49 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-12 13:49 [PATCH] KVM: svm: add support for RDTSCP Paolo Bonzini
2015-11-12 13:49 ` [PATCH] KVM: x86: expose MSR_TSC_AUX to userspace Paolo Bonzini
[not found] ` <CA+0KQ4P7Hy5C1MFHPN0Fib2+O3xE1j-px4NhBvU_CncPmTenHA@mail.gmail.com>
2015-11-13 9:42 ` Paolo Bonzini
2015-11-13 17:49 ` Peter Hornyack
2015-11-12 14:45 ` [PATCH] KVM: svm: add support for RDTSCP Joerg Roedel
2015-11-12 16:18 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox