Message ID | 20210908081945.11047-1-jane.malalane@citrix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | None | expand |
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>
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 --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)
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(+)