* [PATCH 0/2] KVM: x86: add support for CPUID leaf 0x80000021
@ 2022-03-09 17:09 Paolo Bonzini
2022-03-09 17:09 ` [PATCH 1/2] " Paolo Bonzini
2022-03-09 17:09 ` [PATCH 2/2] KVM: x86: synthesize CPUID leaf 0x80000021h if useful Paolo Bonzini
0 siblings, 2 replies; 4+ messages in thread
From: Paolo Bonzini @ 2022-03-09 17:09 UTC (permalink / raw)
To: linux-kernel, kvm; +Cc: vkuznets, jmattson
CPUID leaf 0x80000021 defines some features (or lack of bugs) of AMD
processors. This small series implements it, and also synthesizes
for use on processors that do not have the "Null selector clear base"
erratum but do not support the leaf 0x80000021 either.
Paolo
Paolo Bonzini (2):
KVM: x86: add support for CPUID leaf 0x80000021
KVM: x86: synthesize CPUID leaf 0x80000021h if useful
arch/x86/kvm/cpuid.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
--
2.31.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] KVM: x86: add support for CPUID leaf 0x80000021
2022-03-09 17:09 [PATCH 0/2] KVM: x86: add support for CPUID leaf 0x80000021 Paolo Bonzini
@ 2022-03-09 17:09 ` Paolo Bonzini
2022-03-09 17:09 ` [PATCH 2/2] KVM: x86: synthesize CPUID leaf 0x80000021h if useful Paolo Bonzini
1 sibling, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2022-03-09 17:09 UTC (permalink / raw)
To: linux-kernel, kvm; +Cc: vkuznets, jmattson
CPUID leaf 0x80000021 defines some features (or lack of bugs) of AMD
processors. Expose the ones that make sense via KVM_GET_SUPPORTED_CPUID.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/cpuid.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 419eb8e14f79..30832aad402f 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -1068,7 +1068,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
entry->edx = 0;
break;
case 0x80000000:
- entry->eax = min(entry->eax, 0x8000001f);
+ entry->eax = min(entry->eax, 0x80000021);
break;
case 0x80000001:
cpuid_entry_override(entry, CPUID_8000_0001_EDX);
@@ -1139,6 +1139,23 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
entry->ebx &= ~GENMASK(11, 6);
}
break;
+ case 0x80000020:
+ entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
+ break;
+ case 0x80000021:
+ entry->ebx = entry->ecx = entry->edx = 0;
+ /*
+ * Pass down these bits:
+ * EAX 0 NNDBP, Processor ignores nested data breakpoints
+ * EAX 2 LAS, LFENCE always serializing
+ * EAX 6 NSCB, Null selector clear base
+ *
+ * Other defined bits are for MSRs that KVM does not expose:
+ * EAX 3 SPCL, SMM page configuration lock
+ * EAX 13 PCMSR, Prefetch control MSR
+ */
+ entry->eax &= BIT(0) | BIT(2) | BIT(6);
+ break;
/*Add support for Centaur's CPUID instruction*/
case 0xC0000000:
/*Just support up to 0xC0000004 now*/
--
2.31.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] KVM: x86: synthesize CPUID leaf 0x80000021h if useful
2022-03-09 17:09 [PATCH 0/2] KVM: x86: add support for CPUID leaf 0x80000021 Paolo Bonzini
2022-03-09 17:09 ` [PATCH 1/2] " Paolo Bonzini
@ 2022-03-09 17:09 ` Paolo Bonzini
2022-03-11 9:23 ` Vitaly Kuznetsov
1 sibling, 1 reply; 4+ messages in thread
From: Paolo Bonzini @ 2022-03-09 17:09 UTC (permalink / raw)
To: linux-kernel, kvm; +Cc: vkuznets, jmattson
Guests should have X86_BUG_NULL_SEG if and only if the host has the bug.
Use the info from static_cpu_has_bug to form the 0x80000021 CPUID leaf
that was defined for Zen3. Userspace can then set the bit even on older
CPUs that do not have the bug, such as Zen2.
Do the same for X86_FEATURE_LFENCE_RDTSC as well, since various processors
have had very different ways of detecting it and not all of them are
available to userspace.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/cpuid.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 30832aad402f..58b0b4e0263c 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -723,6 +723,19 @@ static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
/* Hypervisor leaves are always synthesized by __do_cpuid_func. */
return entry;
+ case 0x80000000:
+ /*
+ * 0x80000021 is sometimes synthesized by __do_cpuid_func, which
+ * would result in out-of-bounds calls to do_host_cpuid.
+ */
+ {
+ static int max_cpuid_80000000;
+ if (!READ_ONCE(max_cpuid_80000000))
+ WRITE_ONCE(max_cpuid_80000000, cpuid_eax(0x80000000));
+ if (function > READ_ONCE(max_cpuid_80000000))
+ return entry;
+ }
+
default:
break;
}
@@ -1069,6 +1082,14 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
break;
case 0x80000000:
entry->eax = min(entry->eax, 0x80000021);
+ /*
+ * Serializing LFENCE is reported in a multitude of ways,
+ * and NullSegClearsBase is not reported in CPUID on Zen2;
+ * help userspace by providing the CPUID leaf ourselves.
+ */
+ if (static_cpu_has(X86_FEATURE_LFENCE_RDTSC)
+ || !static_cpu_has_bug(X86_BUG_NULL_SEG))
+ entry->eax = max(entry->eax, 0x80000021);
break;
case 0x80000001:
cpuid_entry_override(entry, CPUID_8000_0001_EDX);
@@ -1155,6 +1176,10 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
* EAX 13 PCMSR, Prefetch control MSR
*/
entry->eax &= BIT(0) | BIT(2) | BIT(6);
+ if (static_cpu_has(X86_FEATURE_LFENCE_RDTSC))
+ entry->eax |= BIT(2);
+ if (!static_cpu_has_bug(X86_BUG_NULL_SEG))
+ entry->eax |= BIT(6);
break;
/*Add support for Centaur's CPUID instruction*/
case 0xC0000000:
--
2.31.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] KVM: x86: synthesize CPUID leaf 0x80000021h if useful
2022-03-09 17:09 ` [PATCH 2/2] KVM: x86: synthesize CPUID leaf 0x80000021h if useful Paolo Bonzini
@ 2022-03-11 9:23 ` Vitaly Kuznetsov
0 siblings, 0 replies; 4+ messages in thread
From: Vitaly Kuznetsov @ 2022-03-11 9:23 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: jmattson, linux-kernel, kvm
Paolo Bonzini <pbonzini@redhat.com> writes:
> Guests should have X86_BUG_NULL_SEG if and only if the host has the bug.
> Use the info from static_cpu_has_bug to form the 0x80000021 CPUID leaf
> that was defined for Zen3. Userspace can then set the bit even on older
> CPUs that do not have the bug, such as Zen2.
>
> Do the same for X86_FEATURE_LFENCE_RDTSC as well, since various processors
> have had very different ways of detecting it and not all of them are
> available to userspace.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> arch/x86/kvm/cpuid.c | 25 +++++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
>
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 30832aad402f..58b0b4e0263c 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -723,6 +723,19 @@ static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
> /* Hypervisor leaves are always synthesized by __do_cpuid_func. */
> return entry;
>
> + case 0x80000000:
> + /*
> + * 0x80000021 is sometimes synthesized by __do_cpuid_func, which
> + * would result in out-of-bounds calls to do_host_cpuid.
> + */
> + {
> + static int max_cpuid_80000000;
> + if (!READ_ONCE(max_cpuid_80000000))
> + WRITE_ONCE(max_cpuid_80000000, cpuid_eax(0x80000000));
> + if (function > READ_ONCE(max_cpuid_80000000))
Out of pure curiosity: what READ_ONCE/WRITE_ONCEs are for here?
> + return entry;
> + }
> +
This hunk seems to have a small side effect beyond its description:
previously, KVM_CPUID_FLAG_SIGNIFCANT_INDEX was always returned for
0x8000001d leaf, even when it wasn't present on the host. With the
change, we will return 'entry' directly from here, with no flag
set. This is likely insignificant in the absence of the leaf.
> default:
> break;
> }
> @@ -1069,6 +1082,14 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
> break;
> case 0x80000000:
> entry->eax = min(entry->eax, 0x80000021);
> + /*
> + * Serializing LFENCE is reported in a multitude of ways,
> + * and NullSegClearsBase is not reported in CPUID on Zen2;
> + * help userspace by providing the CPUID leaf ourselves.
> + */
> + if (static_cpu_has(X86_FEATURE_LFENCE_RDTSC)
> + || !static_cpu_has_bug(X86_BUG_NULL_SEG))
> + entry->eax = max(entry->eax, 0x80000021);
> break;
> case 0x80000001:
> cpuid_entry_override(entry, CPUID_8000_0001_EDX);
> @@ -1155,6 +1176,10 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
> * EAX 13 PCMSR, Prefetch control MSR
> */
> entry->eax &= BIT(0) | BIT(2) | BIT(6);
> + if (static_cpu_has(X86_FEATURE_LFENCE_RDTSC))
> + entry->eax |= BIT(2);
> + if (!static_cpu_has_bug(X86_BUG_NULL_SEG))
> + entry->eax |= BIT(6);
> break;
> /*Add support for Centaur's CPUID instruction*/
> case 0xC0000000:
--
Vitaly
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-03-11 9:23 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-09 17:09 [PATCH 0/2] KVM: x86: add support for CPUID leaf 0x80000021 Paolo Bonzini
2022-03-09 17:09 ` [PATCH 1/2] " Paolo Bonzini
2022-03-09 17:09 ` [PATCH 2/2] KVM: x86: synthesize CPUID leaf 0x80000021h if useful Paolo Bonzini
2022-03-11 9:23 ` Vitaly Kuznetsov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).