diff mbox series

[v2,2/2] x86/cpuid: Detect null segment behaviour on Zen2 CPUs

Message ID 20210908081945.11047-1-jane.malalane@citrix.com (mailing list archive)
State New, archived
Headers show
Series None | expand

Commit Message

Jane Malalane Sept. 8, 2021, 8:19 a.m. UTC
Zen2 CPUs actually have this behaviour, but the CPUID bit couldn't be
introduced into Zen2 due to a lack of leaves. So, it was added in a
new leaf in Zen3. Nonetheless, hypervisors can synthesize the CPUID
bit in software.

So, Xen probes for NSCB (NullSelectorClearsBit) and
synthesizes the bit, if the behaviour is present.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jane Malalane <jane.malalane@citrix.com>
---
CC: Wei Liu <wl@xen.org>
CC: Jan Beulich <jbeulich@suse.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
CC: "Roger Pau Monné" <roger.pau@citrix.com>
CC: Pu Wen <puwen@hygon.cn>
CC: Andy Lutomirski <luto@kernel.org>

v2:
 * Mark detect_zen2_null_seg_behaviour() with __init
 * Remove model checks
---
 xen/arch/x86/cpu/amd.c           | 18 ++++++++++++++++++
 xen/arch/x86/cpu/cpu.h           |  1 +
 xen/arch/x86/cpu/hygon.c         |  5 +++++
 xen/include/asm-x86/cpufeature.h |  1 +
 4 files changed, 25 insertions(+)

Comments

Jan Beulich Sept. 8, 2021, 12:08 p.m. UTC | #1
On 08.09.2021 10:19, Jane Malalane wrote:
> Zen2 CPUs actually have this behaviour, but the CPUID bit couldn't be
> introduced into Zen2 due to a lack of leaves. So, it was added in a
> new leaf in Zen3. Nonetheless, hypervisors can synthesize the CPUID
> bit in software.

Considering the prior model checks, I understand this isn't all Zen2s?
No matter what the answer, I'd like to ask that the first sentence
start with either "All" or "Some" (or something along these lines).
Which is of course fine to insert while committing, so not need to
send a v3.

> So, Xen probes for NSCB (NullSelectorClearsBit) and
> synthesizes the bit, if the behaviour is present.
> 
> Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Jane Malalane <jane.malalane@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
Andrew Cooper Sept. 8, 2021, 12:28 p.m. UTC | #2
On 08/09/2021 13:08, Jan Beulich wrote:
> On 08.09.2021 10:19, Jane Malalane wrote:
>> Zen2 CPUs actually have this behaviour, but the CPUID bit couldn't be
>> introduced into Zen2 due to a lack of leaves. So, it was added in a
>> new leaf in Zen3. Nonetheless, hypervisors can synthesize the CPUID
>> bit in software.
> Considering the prior model checks, I understand this isn't all Zen2s?
> No matter what the answer, I'd like to ask that the first sentence
> start with either "All" or "Some" (or something along these lines).
> Which is of course fine to insert while committing, so not need to
> send a v3.

All Zen2's have this behaviour.

The model checks were trying to avoid running the probe on Zen1, but
"model >= 0x30 && mode != 0x50" is error prone.

There are no faults in the probe, and its fast, so running on all Zen1/2
is better than hoping that we got the model list correct.

~Andrew
diff mbox series

Patch

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 2260eef3aa..cb12861481 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -681,6 +681,19 @@  void amd_init_lfence(struct cpuinfo_x86 *c)
 			  c->x86_capability);
 }
 
+void __init detect_zen2_null_seg_behaviour(void)
+{
+	uint64_t base;
+
+	wrmsrl(MSR_FS_BASE, 1);
+	asm volatile ( "mov %0, %%fs" :: "rm" (0) );
+	rdmsrl(MSR_FS_BASE, base);
+
+	if (base == 0)
+		setup_force_cpu_cap(X86_FEATURE_NSCB);
+
+}
+
 static void init_amd(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
@@ -731,6 +744,11 @@  static void init_amd(struct cpuinfo_x86 *c)
 	else /* Implicily "== 0x10 || >= 0x12" by being 64bit. */
 		amd_init_lfence(c);
 
+	/* Probe for NSCB on Zen2 CPUs when not virtualised */
+	if (!cpu_has_hypervisor && !cpu_has_nscb && c == &boot_cpu_data &&
+	    c->x86 == 0x17)
+		detect_zen2_null_seg_behaviour();
+
 	/*
 	 * If the user has explicitly chosen to disable Memory Disambiguation
 	 * to mitigiate Speculative Store Bypass, poke the appropriate MSR.
diff --git a/xen/arch/x86/cpu/cpu.h b/xen/arch/x86/cpu/cpu.h
index 1ac3b2867a..0dd1b762ff 100644
--- a/xen/arch/x86/cpu/cpu.h
+++ b/xen/arch/x86/cpu/cpu.h
@@ -21,3 +21,4 @@  extern bool detect_extended_topology(struct cpuinfo_x86 *c);
 void early_init_amd(struct cpuinfo_x86 *c);
 void amd_log_freq(const struct cpuinfo_x86 *c);
 void amd_init_lfence(struct cpuinfo_x86 *c);
+void detect_zen2_null_seg_behaviour(void);
diff --git a/xen/arch/x86/cpu/hygon.c b/xen/arch/x86/cpu/hygon.c
index 67e23c5df9..d7a04af2bb 100644
--- a/xen/arch/x86/cpu/hygon.c
+++ b/xen/arch/x86/cpu/hygon.c
@@ -34,6 +34,11 @@  static void init_hygon(struct cpuinfo_x86 *c)
 
 	amd_init_lfence(c);
 
+	/* Probe for NSCB on Zen2 CPUs when not virtualised */
+	if (!cpu_has_hypervisor && !cpu_has_nscb && c == &boot_cpu_data &&
+	    c->x86 == 0x18)
+		detect_zen2_null_seg_behaviour();
+
 	/*
 	 * If the user has explicitly chosen to disable Memory Disambiguation
 	 * to mitigiate Speculative Store Bypass, poke the appropriate MSR.
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 5f6b83f71c..4faf9bff29 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -146,6 +146,7 @@ 
 #define cpu_has_cpuid_faulting  boot_cpu_has(X86_FEATURE_CPUID_FAULTING)
 #define cpu_has_aperfmperf      boot_cpu_has(X86_FEATURE_APERFMPERF)
 #define cpu_has_lfence_dispatch boot_cpu_has(X86_FEATURE_LFENCE_DISPATCH)
+#define cpu_has_nscb            boot_cpu_has(X86_FEATURE_NSCB)
 #define cpu_has_xen_lbr         boot_cpu_has(X86_FEATURE_XEN_LBR)
 #define cpu_has_xen_shstk       boot_cpu_has(X86_FEATURE_XEN_SHSTK)