]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Nov 2021 16:51:36 +0000 (17:51 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Nov 2021 16:51:36 +0000 (17:51 +0100)
added patches:
x86-cpu-fix-migration-safety-with-x86_bug_null_sel.patch

queue-4.19/series
queue-4.19/x86-cpu-fix-migration-safety-with-x86_bug_null_sel.patch [new file with mode: 0644]

index eea1c5202f08ea00d1f9ef1ff15d0669133a0443..f968500fc134a0c3522cc5606b78fc4e0326b410 100644 (file)
@@ -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 (file)
index 0000000..7f95f81
--- /dev/null
@@ -0,0 +1,136 @@
+From 415de44076640483648d6c0f6d645a9ee61328ad Mon Sep 17 00:00:00 2001
+From: Jane Malalane <jane.malalane@citrix.com>
+Date: Thu, 21 Oct 2021 11:47:44 +0100
+Subject: x86/cpu: Fix migration safety with X86_BUG_NULL_SEL
+
+From: Jane Malalane <jane.malalane@citrix.com>
+
+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 <jane.malalane@citrix.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+CC: <stable@vger.kernel.org>
+Link: https://lkml.kernel.org/r/20211021104744.24126-1-jane.malalane@citrix.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);