From: Greg Kroah-Hartman Date: Mon, 15 Nov 2021 16:51:36 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v5.4.160~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=607d24f60762c3dbca909519fb3b5c8bd67086ba;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: x86-cpu-fix-migration-safety-with-x86_bug_null_sel.patch --- diff --git a/queue-4.19/series b/queue-4.19/series index eea1c5202f0..f968500fc13 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -249,3 +249,4 @@ s390-cio-check-the-subchannel-validity-for-dev_busid.patch s390-tape-fix-timer-initialization-in-tape_std_assign.patch pci-add-pci_exp_devctl_payload_-macros.patch fuse-truncate-pagecache-on-atomic_o_trunc.patch +x86-cpu-fix-migration-safety-with-x86_bug_null_sel.patch diff --git a/queue-4.19/x86-cpu-fix-migration-safety-with-x86_bug_null_sel.patch b/queue-4.19/x86-cpu-fix-migration-safety-with-x86_bug_null_sel.patch new file mode 100644 index 00000000000..7f95f812141 --- /dev/null +++ b/queue-4.19/x86-cpu-fix-migration-safety-with-x86_bug_null_sel.patch @@ -0,0 +1,136 @@ +From 415de44076640483648d6c0f6d645a9ee61328ad Mon Sep 17 00:00:00 2001 +From: Jane Malalane +Date: Thu, 21 Oct 2021 11:47:44 +0100 +Subject: x86/cpu: Fix migration safety with X86_BUG_NULL_SEL + +From: Jane Malalane + +commit 415de44076640483648d6c0f6d645a9ee61328ad upstream. + +Currently, Linux probes for X86_BUG_NULL_SEL unconditionally which +makes it unsafe to migrate in a virtualised environment as the +properties across the migration pool might differ. + +To be specific, the case which goes wrong is: + +1. Zen1 (or earlier) and Zen2 (or later) in a migration pool +2. Linux boots on Zen2, probes and finds the absence of X86_BUG_NULL_SEL +3. Linux is then migrated to Zen1 + +Linux is now running on a X86_BUG_NULL_SEL-impacted CPU while believing +that the bug is fixed. + +The only way to address the problem is to fully trust the "no longer +affected" CPUID bit when virtualised, because in the above case it would +be clear deliberately to indicate the fact "you might migrate to +somewhere which has this behaviour". + +Zen3 adds the NullSelectorClearsBase CPUID bit to indicate that loading +a NULL segment selector zeroes the base and limit fields, as well as +just attributes. Zen2 also has this behaviour but doesn't have the NSCB +bit. + + [ bp: Minor touchups. ] + +Signed-off-by: Jane Malalane +Signed-off-by: Borislav Petkov +CC: +Link: https://lkml.kernel.org/r/20211021104744.24126-1-jane.malalane@citrix.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/amd.c | 2 + + arch/x86/kernel/cpu/common.c | 44 ++++++++++++++++++++++++++++++++++++------- + arch/x86/kernel/cpu/cpu.h | 1 + 3 files changed, 40 insertions(+), 7 deletions(-) + +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -993,6 +993,8 @@ static void init_amd(struct cpuinfo_x86 + if (cpu_has(c, X86_FEATURE_IRPERF) && + !cpu_has_amd_erratum(c, amd_erratum_1054)) + msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); ++ ++ check_null_seg_clears_base(c); + } + + #ifdef CONFIG_X86_32 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -1254,9 +1254,8 @@ void __init early_cpu_init(void) + early_identify_cpu(&boot_cpu_data); + } + +-static void detect_null_seg_behavior(struct cpuinfo_x86 *c) ++static bool detect_null_seg_behavior(void) + { +-#ifdef CONFIG_X86_64 + /* + * Empirically, writing zero to a segment selector on AMD does + * not clear the base, whereas writing zero to a segment +@@ -1277,10 +1276,43 @@ static void detect_null_seg_behavior(str + wrmsrl(MSR_FS_BASE, 1); + loadsegment(fs, 0); + rdmsrl(MSR_FS_BASE, tmp); +- if (tmp != 0) +- set_cpu_bug(c, X86_BUG_NULL_SEG); + wrmsrl(MSR_FS_BASE, old_base); +-#endif ++ return tmp == 0; ++} ++ ++void check_null_seg_clears_base(struct cpuinfo_x86 *c) ++{ ++ /* BUG_NULL_SEG is only relevant with 64bit userspace */ ++ if (!IS_ENABLED(CONFIG_X86_64)) ++ return; ++ ++ /* Zen3 CPUs advertise Null Selector Clears Base in CPUID. */ ++ if (c->extended_cpuid_level >= 0x80000021 && ++ cpuid_eax(0x80000021) & BIT(6)) ++ return; ++ ++ /* ++ * CPUID bit above wasn't set. If this kernel is still running ++ * as a HV guest, then the HV has decided not to advertize ++ * that CPUID bit for whatever reason. For example, one ++ * member of the migration pool might be vulnerable. Which ++ * means, the bug is present: set the BUG flag and return. ++ */ ++ if (cpu_has(c, X86_FEATURE_HYPERVISOR)) { ++ set_cpu_bug(c, X86_BUG_NULL_SEG); ++ return; ++ } ++ ++ /* ++ * Zen2 CPUs also have this behaviour, but no CPUID bit. ++ * 0x18 is the respective family for Hygon. ++ */ ++ if ((c->x86 == 0x17 || c->x86 == 0x18) && ++ detect_null_seg_behavior()) ++ return; ++ ++ /* All the remaining ones are affected */ ++ set_cpu_bug(c, X86_BUG_NULL_SEG); + } + + static void generic_identify(struct cpuinfo_x86 *c) +@@ -1316,8 +1348,6 @@ static void generic_identify(struct cpui + + get_model_name(c); /* Default name */ + +- detect_null_seg_behavior(c); +- + /* + * ESPFIX is a strange bug. All real CPUs have it. Paravirt + * systems that run Linux at CPL > 0 may or may not have the +--- a/arch/x86/kernel/cpu/cpu.h ++++ b/arch/x86/kernel/cpu/cpu.h +@@ -76,6 +76,7 @@ extern int detect_extended_topology_earl + extern int detect_extended_topology(struct cpuinfo_x86 *c); + extern int detect_ht_early(struct cpuinfo_x86 *c); + extern void detect_ht(struct cpuinfo_x86 *c); ++extern void check_null_seg_clears_base(struct cpuinfo_x86 *c); + + unsigned int aperfmperf_get_khz(int cpu); +