All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [v3] x86/mm/mpx: Work around MPX erratum SKD046
@ 2016-05-11 21:16 Dave Hansen
  2016-05-12  6:50 ` Ingo Molnar
  0 siblings, 1 reply; 6+ messages in thread
From: Dave Hansen @ 2016-05-11 21:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: Dave Hansen, dave.hansen, luto, bp, brgerst, dvlasenk, hpa,
	torvalds, peterz, tglx, mingo


Changes from v1:
 * Unconditionally enable workaround on all CPUs with MPX despite
   whether we know it to be affected or not
 * Add a pr_warn() when the workaround is active

Changes from v2:
 * fix build breakage from #ifdefs in bug.h

--

From: Dave Hansen <dave@sr71.net>

This erratum essentially causes the CPU to forget which privilege
level it is operating on (kernel vs. user) for the purposes of MPX.

This erratum can only be triggered when a system is not using
Supervisor Mode Execution Prevention (SMEP).  Our workaround for
the erratum is to ensure that MPX can only be used in cases where
SMEP is present in the processor and is enabled.

This erratum only affects Core processors.  Atom is unaffected.
But, there is no architectural way to determine Atom vs. Core.
So, we just apply this workaround to all processors.  It's
possible that it will mistakenly disable MPX on some Atom
processsors or future unaffected Core processors.  There are
currently no processors that have MPX and not SMEP.  It would
take something akin to a hypervisor masking SMEP out on an Atom
processor for this to present itself on current hardware.

More details can be found at:

  http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/desktop-6th-gen-core-family-spec-update.pdf

"
  SKD046 Branch Instructions May Initialize MPX Bound Registers Incorrectly

  Problem:

  Depending on the current Intel MPX (Memory Protection
  Extensions) configuration, execution of certain branch
  instructions (near CALL, near RET, near JMP, and Jcc
  instructions) without a BND prefix (F2H) initialize the MPX bound
  registers. Due to this erratum, such a branch instruction that is
  executed both with CPL = 3 and with CPL < 3 may not use the
  correct MPX configuration register (BNDCFGU or BNDCFGS,
  respectively) for determining whether to initialize the bound
  registers; it may thus initialize the bound registers when it
  should not, or fail to initialize them when it should.

  Implication:

  A branch instruction that has executed both in user mode and in
  supervisor mode (from the same linear address) may cause a #BR
  (bound range fault) when it should not have or may not cause a
  #BR when it should have.  Workaround An operating system can
  avoid this erratum by setting CR4.SMEP[bit 20] to enable
  supervisor-mode execution prevention (SMEP). When SMEP is
  enabled, no code can be executed both with CPL = 3 and with CPL < 3.
"

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave@sr71.net>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20160504205359.19DB7812@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---

 b/arch/x86/include/asm/bugs.h  |    6 ++++++
 b/arch/x86/kernel/cpu/common.c |    3 +++
 b/arch/x86/kernel/cpu/intel.c  |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+)

diff -puN arch/x86/include/asm/bugs.h~x86-mm-mpx-Work-around-MPX-erratum-SKD046 arch/x86/include/asm/bugs.h
--- a/arch/x86/include/asm/bugs.h~x86-mm-mpx-Work-around-MPX-erratum-SKD046	2016-05-11 12:54:09.926505090 -0700
+++ b/arch/x86/include/asm/bugs.h	2016-05-11 12:55:41.213689895 -0700
@@ -3,6 +3,12 @@
 
 extern void check_bugs(void);
 
+#if defined(CONFIG_CPU_SUP_INTEL)
+void check_mpx_erratum(struct cpuinfo_x86 *c);
+#else
+static inline void check_mpx_erratum(struct cpuinfo_x86 *c) {}
+#endif
+
 #if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
 int ppro_with_ram_bug(void);
 #else
diff -puN arch/x86/kernel/cpu/common.c~x86-mm-mpx-Work-around-MPX-erratum-SKD046 arch/x86/kernel/cpu/common.c
--- a/arch/x86/kernel/cpu/common.c~x86-mm-mpx-Work-around-MPX-erratum-SKD046	2016-05-11 12:54:09.928505181 -0700
+++ b/arch/x86/kernel/cpu/common.c	2016-05-11 12:54:09.933505411 -0700
@@ -37,6 +37,7 @@
 #include <asm/mtrr.h>
 #include <linux/numa.h>
 #include <asm/asm.h>
+#include <asm/bugs.h>
 #include <asm/cpu.h>
 #include <asm/mce.h>
 #include <asm/msr.h>
@@ -270,6 +271,8 @@ static inline void squash_the_stupid_ser
 static __init int setup_disable_smep(char *arg)
 {
 	setup_clear_cpu_cap(X86_FEATURE_SMEP);
+	/* Check for things that depend on SMEP being enabled: */
+	check_mpx_erratum(&boot_cpu_data);
 	return 1;
 }
 __setup("nosmep", setup_disable_smep);
diff -puN arch/x86/kernel/cpu/intel.c~x86-mm-mpx-Work-around-MPX-erratum-SKD046 arch/x86/kernel/cpu/intel.c
--- a/arch/x86/kernel/cpu/intel.c~x86-mm-mpx-Work-around-MPX-erratum-SKD046	2016-05-11 12:54:09.930505273 -0700
+++ b/arch/x86/kernel/cpu/intel.c	2016-05-11 12:54:09.934505457 -0700
@@ -25,6 +25,41 @@
 #include <asm/apic.h>
 #endif
 
+/*
+ * Just in case our CPU detection goes bad, or you have a weird system,
+ * allow a way to override the automatic disabling of MPX.
+ */
+static int forcempx;
+
+static int __init forcempx_setup(char *__unused)
+{
+	forcempx = 1;
+
+	return 1;
+}
+__setup("intel-skd-046-workaround=disable", forcempx_setup);
+
+void check_mpx_erratum(struct cpuinfo_x86 *c)
+{
+	if (forcempx)
+		return;
+	/*
+	 * Turn off the MPX feature on CPUs where SMEP is not
+	 * available or disabled.
+	 *
+	 * Works around Intel Erratum SKD046: "Branch Instructions
+	 * May Initialize MPX Bound Registers Incorrectly".
+	 *
+	 * This might falsely disable MPX on systems without
+	 * SMEP, like Atom processors without SMEP.  But there
+	 * is no such hardware known at the moment.
+	 */
+	if (cpu_has(c, X86_FEATURE_MPX) && !cpu_has(c, X86_FEATURE_SMEP)) {
+		setup_clear_cpu_cap(X86_FEATURE_MPX);
+		pr_warn("x86/mpx: Disabling MPX since SMEP not present\n");
+	}
+}
+
 static void early_init_intel(struct cpuinfo_x86 *c)
 {
 	u64 misc_enable;
@@ -173,6 +208,8 @@ static void early_init_intel(struct cpui
 		if (edx & (1U << 28))
 			c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff);
 	}
+
+	check_mpx_erratum(c);
 }
 
 #ifdef CONFIG_X86_32
_

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] [v3] x86/mm/mpx: Work around MPX erratum SKD046
  2016-05-11 21:16 [PATCH] [v3] x86/mm/mpx: Work around MPX erratum SKD046 Dave Hansen
@ 2016-05-12  6:50 ` Ingo Molnar
  2016-05-12  7:16   ` Ingo Molnar
  0 siblings, 1 reply; 6+ messages in thread
From: Ingo Molnar @ 2016-05-12  6:50 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, dave.hansen, luto, bp, brgerst, dvlasenk, hpa,
	torvalds, peterz, tglx


* Dave Hansen <dave@sr71.net> wrote:

> 
> Changes from v1:
>  * Unconditionally enable workaround on all CPUs with MPX despite
>    whether we know it to be affected or not
>  * Add a pr_warn() when the workaround is active
> 
> Changes from v2:
>  * fix build breakage from #ifdefs in bug.h
> 
> --
> 
> From: Dave Hansen <dave@sr71.net>
> 
> This erratum essentially causes the CPU to forget which privilege
> level it is operating on (kernel vs. user) for the purposes of MPX.
> 
> This erratum can only be triggered when a system is not using
> Supervisor Mode Execution Prevention (SMEP).  Our workaround for
> the erratum is to ensure that MPX can only be used in cases where
> SMEP is present in the processor and is enabled.
> 
> This erratum only affects Core processors.  Atom is unaffected.
> But, there is no architectural way to determine Atom vs. Core.
> So, we just apply this workaround to all processors.  It's
> possible that it will mistakenly disable MPX on some Atom
> processsors or future unaffected Core processors.  There are
> currently no processors that have MPX and not SMEP.  It would
> take something akin to a hypervisor masking SMEP out on an Atom
> processor for this to present itself on current hardware.
> 
> More details can be found at:
> 
>   http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/desktop-6th-gen-core-family-spec-update.pdf
> 
> "
>   SKD046 Branch Instructions May Initialize MPX Bound Registers Incorrectly
> 
>   Problem:
> 
>   Depending on the current Intel MPX (Memory Protection
>   Extensions) configuration, execution of certain branch
>   instructions (near CALL, near RET, near JMP, and Jcc
>   instructions) without a BND prefix (F2H) initialize the MPX bound
>   registers. Due to this erratum, such a branch instruction that is
>   executed both with CPL = 3 and with CPL < 3 may not use the
>   correct MPX configuration register (BNDCFGU or BNDCFGS,
>   respectively) for determining whether to initialize the bound
>   registers; it may thus initialize the bound registers when it
>   should not, or fail to initialize them when it should.
> 
>   Implication:
> 
>   A branch instruction that has executed both in user mode and in
>   supervisor mode (from the same linear address) may cause a #BR
>   (bound range fault) when it should not have or may not cause a
>   #BR when it should have.  Workaround An operating system can
>   avoid this erratum by setting CR4.SMEP[bit 20] to enable
>   supervisor-mode execution prevention (SMEP). When SMEP is
>   enabled, no code can be executed both with CPL = 3 and with CPL < 3.
> "
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Andy Lutomirski <luto@amacapital.net>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Brian Gerst <brgerst@gmail.com>
> Cc: Dave Hansen <dave@sr71.net>
> Cc: Denys Vlasenko <dvlasenk@redhat.com>
> Cc: H. Peter Anvin <hpa@zytor.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Link: http://lkml.kernel.org/r/20160504205359.19DB7812@viggo.jf.intel.com
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> ---
> 
>  b/arch/x86/include/asm/bugs.h  |    6 ++++++
>  b/arch/x86/kernel/cpu/common.c |    3 +++
>  b/arch/x86/kernel/cpu/intel.c  |   37 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 46 insertions(+)
> 
> diff -puN arch/x86/include/asm/bugs.h~x86-mm-mpx-Work-around-MPX-erratum-SKD046 arch/x86/include/asm/bugs.h
> --- a/arch/x86/include/asm/bugs.h~x86-mm-mpx-Work-around-MPX-erratum-SKD046	2016-05-11 12:54:09.926505090 -0700
> +++ b/arch/x86/include/asm/bugs.h	2016-05-11 12:55:41.213689895 -0700
> @@ -3,6 +3,12 @@
>  
>  extern void check_bugs(void);
>  
> +#if defined(CONFIG_CPU_SUP_INTEL)
> +void check_mpx_erratum(struct cpuinfo_x86 *c);
> +#else
> +static inline void check_mpx_erratum(struct cpuinfo_x86 *c) {}
> +#endif
> +
>  #if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
>  int ppro_with_ram_bug(void);
>  #else
> diff -puN arch/x86/kernel/cpu/common.c~x86-mm-mpx-Work-around-MPX-erratum-SKD046 arch/x86/kernel/cpu/common.c
> --- a/arch/x86/kernel/cpu/common.c~x86-mm-mpx-Work-around-MPX-erratum-SKD046	2016-05-11 12:54:09.928505181 -0700
> +++ b/arch/x86/kernel/cpu/common.c	2016-05-11 12:54:09.933505411 -0700
> @@ -37,6 +37,7 @@
>  #include <asm/mtrr.h>
>  #include <linux/numa.h>
>  #include <asm/asm.h>
> +#include <asm/bugs.h>
>  #include <asm/cpu.h>
>  #include <asm/mce.h>
>  #include <asm/msr.h>
> @@ -270,6 +271,8 @@ static inline void squash_the_stupid_ser
>  static __init int setup_disable_smep(char *arg)
>  {
>  	setup_clear_cpu_cap(X86_FEATURE_SMEP);
> +	/* Check for things that depend on SMEP being enabled: */
> +	check_mpx_erratum(&boot_cpu_data);
>  	return 1;
>  }
>  __setup("nosmep", setup_disable_smep);
> diff -puN arch/x86/kernel/cpu/intel.c~x86-mm-mpx-Work-around-MPX-erratum-SKD046 arch/x86/kernel/cpu/intel.c
> --- a/arch/x86/kernel/cpu/intel.c~x86-mm-mpx-Work-around-MPX-erratum-SKD046	2016-05-11 12:54:09.930505273 -0700
> +++ b/arch/x86/kernel/cpu/intel.c	2016-05-11 12:54:09.934505457 -0700
> @@ -25,6 +25,41 @@
>  #include <asm/apic.h>
>  #endif
>  
> +/*
> + * Just in case our CPU detection goes bad, or you have a weird system,
> + * allow a way to override the automatic disabling of MPX.
> + */
> +static int forcempx;
> +
> +static int __init forcempx_setup(char *__unused)
> +{
> +	forcempx = 1;
> +
> +	return 1;
> +}
> +__setup("intel-skd-046-workaround=disable", forcempx_setup);

I've done a s/forcempx/force_mpx/ (readable variable names are cheap!), but 
otherwise this patch is looking good to me and I'll try to get it to Linus later 
today.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] [v3] x86/mm/mpx: Work around MPX erratum SKD046
  2016-05-12  6:50 ` Ingo Molnar
@ 2016-05-12  7:16   ` Ingo Molnar
  0 siblings, 0 replies; 6+ messages in thread
From: Ingo Molnar @ 2016-05-12  7:16 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, dave.hansen, luto, bp, brgerst, dvlasenk, hpa,
	torvalds, peterz, tglx


* Ingo Molnar <mingo@kernel.org> wrote:

> > Changes from v1:
> >  * Unconditionally enable workaround on all CPUs with MPX despite
> >    whether we know it to be affected or not
> >  * Add a pr_warn() when the workaround is active
> > 
> > Changes from v2:
> >  * fix build breakage from #ifdefs in bug.h

It now emits ugly warnings (x86-64 defconfig):

./arch/x86/include/asm/bugs.h:7:31: warning: ‘struct cpuinfo_x86’ declared inside parameter list
./arch/x86/include/asm/bugs.h:7:31: warning: its scope is only this definition or declaration, which is probably not what you want

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] x86/mm/mpx: Work around MPX erratum SKD046
  2016-05-05  7:01 ` [PATCH v3] x86/mm/mpx: Work around MPX erratum SKD046 Ingo Molnar
  2016-05-05  7:26   ` Ingo Molnar
@ 2016-05-05 17:03   ` Dave Hansen
  1 sibling, 0 replies; 6+ messages in thread
From: Dave Hansen @ 2016-05-05 17:03 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, x86, luto, torvalds, Thomas Gleixner,
	H. Peter Anvin, Borislav Petkov

On 05/05/2016 12:01 AM, Ingo Molnar wrote:
> I also slightly twiddled the wording, removed the linebreak from the condition (it 
> was not over col80), removed whitespace noise and added your Signed-off-by, which 
> I suppose you intended to add? I also tidied up the changelog a bit.
> 
> Final patch from tip:x86/urgent attached - please holler if you disagree with it!

This all looks fine to me.  I also tested that it works.  Thanks!

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] x86/mm/mpx: Work around MPX erratum SKD046
  2016-05-05  7:01 ` [PATCH v3] x86/mm/mpx: Work around MPX erratum SKD046 Ingo Molnar
@ 2016-05-05  7:26   ` Ingo Molnar
  2016-05-05 17:03   ` Dave Hansen
  1 sibling, 0 replies; 6+ messages in thread
From: Ingo Molnar @ 2016-05-05  7:26 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, x86, luto, torvalds, Thomas Gleixner,
	H. Peter Anvin, Borislav Petkov


* Ingo Molnar <mingo@kernel.org> wrote:

> > -#if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
> > +#if defined(CONFIG_CPU_SUP_INTEL)
> > +void check_mpx_erratum(struct cpuinfo_x86 *c);
> > +#else
> > +static inline void check_mpx_erratum(struct cpuinfo_x86 *c) {}
> > +#if defined(CONFIG_X86_32)
> >  int ppro_with_ram_bug(void);
> >  #else
> >  static inline int ppro_with_ram_bug(void) { return 0; }
> > -#endif
> > +#endif /* CONFIG_X86_32 */
> > +#endif /* CONFIG_CPU_SUP_INTEL */

Sigh. So this broke the ppro_with_ram_bug() definition, because in the new code 
you put it into the wrong branch, breaking the build ...

I've dropped this for now, please fix and test the v3 version of the patch I sent 
and re-send.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3] x86/mm/mpx: Work around MPX erratum SKD046
  2016-05-04 20:53 [PATCH] [v2] x86, mpx: Workaround for MPX erratum Dave Hansen
@ 2016-05-05  7:01 ` Ingo Molnar
  2016-05-05  7:26   ` Ingo Molnar
  2016-05-05 17:03   ` Dave Hansen
  0 siblings, 2 replies; 6+ messages in thread
From: Ingo Molnar @ 2016-05-05  7:01 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, x86, luto, torvalds, Thomas Gleixner,
	H. Peter Anvin, Borislav Petkov


* Dave Hansen <dave@sr71.net> wrote:

> 
> Changes from v1:
>  * Unconditionally enable workaround on all CPUs with MPX despite
>    whether we know it to be affected or not
>  * Add a pr_warn() when the workaround is active
> 
> --
> 
> This erratum essentially causes the CPU to forget which privilege
> mode it is operating in (kernel vs. user) for the purposes of MPX.
> 
> This erratum can only be triggered when a system is not using
> Supervisor Mode Execution Prevention (SMEP).  Our workaround for
> the erratum is to ensure that MPX can only be used in cases where
> SMEP is present in the processor and enabled.
> 
> This erratum only affects Core processors.  Atom is unaffected.
> But, there is no architectural way to determine Atom vs. Core.
> So, we just apply this workaround to all processors.  It's
> possible that it will mistakenly disable MPX on some Atom
> processsors or future unaffected Core processors.  There are
> currently no processors that have MPX and not SMEP.  It would
> take something akin to a hypervisor masking SMEP out on an Atom
> processor for this to present itself on current hardware.
> 
> More details:
> 
> http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/desktop-6th-gen-core-family-spec-update.pdf
> 
> SKD046 Branch Instructions May Initialize MPX Bound Registers Incorrectly
> 
> Problem:
> 
> Depending on the current Intel MPX (Memory Protection
> Extensions) configuration, execution of certain branch
> instructions (near CALL, near RET, near JMP, and Jcc
> instructions) without a BND prefix (F2H) initialize the MPX bound
> registers. Due to this erratum, such a branch instruction that is
> executed both with CPL = 3 and with CPL < 3 may not use the
> correct MPX configuration register (BNDCFGU or BNDCFGS,
> respectively) for determining whether to initialize the bound
> registers; it may thus initialize the bound registers when it
> should not, or fail to initialize them when it should.
> 
> Implication:
> 
> A branch instruction that has executed both in user mode and in
> supervisor mode (from the same linear address) may cause a #BR
> (bound range fault) when it should not have or may not cause a
> #BR when it should have.  Workaround An operating system can
> avoid this erratum by setting CR4.SMEP[bit 20] to enable
> supervisor-mode execution prevention (SMEP). When SMEP is
> enabled, no code can be executed both with CPL = 3 and with CPL <
> 3.
> 
> Cc: x86@kernel.org
> Cc: luto@amacapital.net
> Cc: torvalds@linux-foundation.org
> Cc: Ingo Molnar <mingo@kernel.org>
> 
> ---
> 
>  b/arch/x86/include/asm/bugs.h  |    9 +++++++--
>  b/arch/x86/kernel/cpu/common.c |    3 +++
>  b/arch/x86/kernel/cpu/intel.c  |   37 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 47 insertions(+), 2 deletions(-)
> 
> diff -puN arch/x86/include/asm/bugs.h~neversend-skl-mpx-errata-simple arch/x86/include/asm/bugs.h
> --- a/arch/x86/include/asm/bugs.h~neversend-skl-mpx-errata-simple	2016-05-04 09:46:22.323444051 -0700
> +++ b/arch/x86/include/asm/bugs.h	2016-05-04 09:46:22.329444321 -0700
> @@ -3,10 +3,15 @@
>  
>  extern void check_bugs(void);
>  
> -#if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
> +#if defined(CONFIG_CPU_SUP_INTEL)
> +void check_mpx_erratum(struct cpuinfo_x86 *c);
> +#else
> +static inline void check_mpx_erratum(struct cpuinfo_x86 *c) {}
> +#if defined(CONFIG_X86_32)
>  int ppro_with_ram_bug(void);
>  #else
>  static inline int ppro_with_ram_bug(void) { return 0; }
> -#endif
> +#endif /* CONFIG_X86_32 */
> +#endif /* CONFIG_CPU_SUP_INTEL */
>  
>  #endif /* _ASM_X86_BUGS_H */
> diff -puN arch/x86/kernel/cpu/common.c~neversend-skl-mpx-errata-simple arch/x86/kernel/cpu/common.c
> --- a/arch/x86/kernel/cpu/common.c~neversend-skl-mpx-errata-simple	2016-05-04 09:46:22.324444096 -0700
> +++ b/arch/x86/kernel/cpu/common.c	2016-05-04 09:46:22.330444366 -0700
> @@ -37,6 +37,7 @@
>  #include <asm/mtrr.h>
>  #include <linux/numa.h>
>  #include <asm/asm.h>
> +#include <asm/bugs.h>
>  #include <asm/cpu.h>
>  #include <asm/mce.h>
>  #include <asm/msr.h>
> @@ -270,6 +271,8 @@ static inline void squash_the_stupid_ser
>  static __init int setup_disable_smep(char *arg)
>  {
>  	setup_clear_cpu_cap(X86_FEATURE_SMEP);
> +	/* also check for things that depend on SMEP being enabled */
> +	check_mpx_erratum(&boot_cpu_data);
>  	return 1;
>  }
>  __setup("nosmep", setup_disable_smep);
> diff -puN arch/x86/kernel/cpu/intel.c~neversend-skl-mpx-errata-simple arch/x86/kernel/cpu/intel.c
> --- a/arch/x86/kernel/cpu/intel.c~neversend-skl-mpx-errata-simple	2016-05-04 09:46:22.326444186 -0700
> +++ b/arch/x86/kernel/cpu/intel.c	2016-05-04 10:54:08.923959470 -0700
> @@ -25,6 +25,41 @@
>  #include <asm/apic.h>
>  #endif
>  
> +/*
> + * Just in case our CPU detection goes bad, allow a way to
> + * override the disabling of MPX.
> + */
> +static int forcempx;
> +static int __init forcempx_setup(char *__unused)

I've added a newline after the static variable.

> +{
> +	forcempx = 1;
> +	return 1;
> +}
> +__setup("intel-skd-046-workaround=disable", forcempx_setup);

I guess this is good - but our __setup() logic is sad - people who use 
intel-skd-046-workaround=0 won't even get a warning.

> +
> +void check_mpx_erratum(struct cpuinfo_x86 *c)
> +{
> +	if (forcempx)
> +	       return;
> +	/*
> +	 * Turn off MPX feature on CPUs where SMEP is not
> +	 * available or disabled.
> +	 *
> +	 * Works around Intel Erratum: SKD046 Branch Instructions
> +	 * May Initialize MPX Bound Registers Incorrectly.
> +	 *
> +	 * This might falsely-disable MPX on systems without
> +	 * SMEP, like Atom processors without SMEP.  But, there
> +	 * are not any known places where that happens with
> +	 * actual hardware.
> +	 */
> +	if (cpu_has(c, X86_FEATURE_MPX) &&
> +	    !cpu_has(c, X86_FEATURE_SMEP)) {
> +		setup_clear_cpu_cap(X86_FEATURE_MPX);
> +		pr_warn("x86/mpx: disabling since SMEP not present\n");
> +	}

I also slightly twiddled the wording, removed the linebreak from the condition (it 
was not over col80), removed whitespace noise and added your Signed-off-by, which 
I suppose you intended to add? I also tidied up the changelog a bit.

Final patch from tip:x86/urgent attached - please holler if you disagree with it!

Thanks,

	Ingo

===================>
>From 41a057b30fe1c27c0a6b89b2f6bfea6a9ca43a6b Mon Sep 17 00:00:00 2001
From: Dave Hansen <dave@sr71.net>
Date: Wed, 4 May 2016 13:53:59 -0700
Subject: [PATCH] x86/mm/mpx: Work around Intel MPX erratum SKD046

This erratum essentially causes the CPU to forget which privilege
level it is operating on (kernel vs. user) for the purposes of MPX.

This erratum can only be triggered when a system is not using
Supervisor Mode Execution Prevention (SMEP).  Our workaround for
the erratum is to ensure that MPX can only be used in cases where
SMEP is present in the processor and is enabled.

This erratum only affects Core processors.  Atom is unaffected.
But, there is no architectural way to determine Atom vs. Core.
So, we just apply this workaround to all processors.  It's
possible that it will mistakenly disable MPX on some Atom
processsors or future unaffected Core processors.  There are
currently no processors that have MPX and not SMEP.  It would
take something akin to a hypervisor masking SMEP out on an Atom
processor for this to present itself on current hardware.

More details can be found at:

  http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/desktop-6th-gen-core-family-spec-update.pdf

"
  SKD046 Branch Instructions May Initialize MPX Bound Registers Incorrectly

  Problem:

  Depending on the current Intel MPX (Memory Protection
  Extensions) configuration, execution of certain branch
  instructions (near CALL, near RET, near JMP, and Jcc
  instructions) without a BND prefix (F2H) initialize the MPX bound
  registers. Due to this erratum, such a branch instruction that is
  executed both with CPL = 3 and with CPL < 3 may not use the
  correct MPX configuration register (BNDCFGU or BNDCFGS,
  respectively) for determining whether to initialize the bound
  registers; it may thus initialize the bound registers when it
  should not, or fail to initialize them when it should.

  Implication:

  A branch instruction that has executed both in user mode and in
  supervisor mode (from the same linear address) may cause a #BR
  (bound range fault) when it should not have or may not cause a
  #BR when it should have.  Workaround An operating system can
  avoid this erratum by setting CR4.SMEP[bit 20] to enable
  supervisor-mode execution prevention (SMEP). When SMEP is
  enabled, no code can be executed both with CPL = 3 and with CPL < 3.
"

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave@sr71.net>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20160504205359.19DB7812@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/bugs.h  |  7 ++++++-
 arch/x86/kernel/cpu/common.c |  3 +++
 arch/x86/kernel/cpu/intel.c  | 37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/bugs.h b/arch/x86/include/asm/bugs.h
index 08abf639075f..9247f2f05a2b 100644
--- a/arch/x86/include/asm/bugs.h
+++ b/arch/x86/include/asm/bugs.h
@@ -3,10 +3,15 @@
 
 extern void check_bugs(void);
 
-#if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
+#if defined(CONFIG_CPU_SUP_INTEL)
+void check_mpx_erratum(struct cpuinfo_x86 *c);
+#else
+static inline void check_mpx_erratum(struct cpuinfo_x86 *c) {}
+#ifdef CONFIG_X86_32
 int ppro_with_ram_bug(void);
 #else
 static inline int ppro_with_ram_bug(void) { return 0; }
 #endif
+#endif
 
 #endif /* _ASM_X86_BUGS_H */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 8394b3d1f94f..5782c6d87a33 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -37,6 +37,7 @@
 #include <asm/mtrr.h>
 #include <linux/numa.h>
 #include <asm/asm.h>
+#include <asm/bugs.h>
 #include <asm/cpu.h>
 #include <asm/mce.h>
 #include <asm/msr.h>
@@ -270,6 +271,8 @@ static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
 static __init int setup_disable_smep(char *arg)
 {
 	setup_clear_cpu_cap(X86_FEATURE_SMEP);
+	/* Check for things that depend on SMEP being enabled: */
+	check_mpx_erratum(&boot_cpu_data);
 	return 1;
 }
 __setup("nosmep", setup_disable_smep);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 1f7fdb91a818..6a80ffd17336 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -25,6 +25,41 @@
 #include <asm/apic.h>
 #endif
 
+/*
+ * Just in case our CPU detection goes bad, or you have a weird system,
+ * allow a way to override the automatic disabling of MPX.
+ */
+static int forcempx;
+
+static int __init forcempx_setup(char *__unused)
+{
+	forcempx = 1;
+
+	return 1;
+}
+__setup("intel-skd-046-workaround=disable", forcempx_setup);
+
+void check_mpx_erratum(struct cpuinfo_x86 *c)
+{
+	if (forcempx)
+		return;
+	/*
+	 * Turn off the MPX feature on CPUs where SMEP is not
+	 * available or disabled.
+	 *
+	 * Works around Intel Erratum SKD046: "Branch Instructions
+	 * May Initialize MPX Bound Registers Incorrectly".
+	 *
+	 * This might falsely disable MPX on systems without
+	 * SMEP, like Atom processors without SMEP.  But there
+	 * is no such hardware known at the moment.
+	 */
+	if (cpu_has(c, X86_FEATURE_MPX) && !cpu_has(c, X86_FEATURE_SMEP)) {
+		setup_clear_cpu_cap(X86_FEATURE_MPX);
+		pr_warn("x86/mpx: Disabling MPX since SMEP not present\n");
+	}
+}
+
 static void early_init_intel(struct cpuinfo_x86 *c)
 {
 	u64 misc_enable;
@@ -173,6 +208,8 @@ static void early_init_intel(struct cpuinfo_x86 *c)
 		if (edx & (1U << 28))
 			c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff);
 	}
+
+	check_mpx_erratum(c);
 }
 
 #ifdef CONFIG_X86_32

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-05-12  7:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-11 21:16 [PATCH] [v3] x86/mm/mpx: Work around MPX erratum SKD046 Dave Hansen
2016-05-12  6:50 ` Ingo Molnar
2016-05-12  7:16   ` Ingo Molnar
  -- strict thread matches above, loose matches on Subject: below --
2016-05-04 20:53 [PATCH] [v2] x86, mpx: Workaround for MPX erratum Dave Hansen
2016-05-05  7:01 ` [PATCH v3] x86/mm/mpx: Work around MPX erratum SKD046 Ingo Molnar
2016-05-05  7:26   ` Ingo Molnar
2016-05-05 17:03   ` Dave Hansen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.