* Dave Hansen <d...@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 <d...@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.han...@linux.intel.com>
> Cc: Andy Lutomirski <l...@amacapital.net>
> Cc: Borislav Petkov <b...@alien8.de>
> Cc: Brian Gerst <brge...@gmail.com>
> Cc: Dave Hansen <d...@sr71.net>
> Cc: Denys Vlasenko <dvlas...@redhat.com>
> Cc: H. Peter Anvin <h...@zytor.com>
> Cc: Linus Torvalds <torva...@linux-foundation.org>
> Cc: Peter Zijlstra <pet...@infradead.org>
> Cc: Thomas Gleixner <t...@linutronix.de>
> Link: http://lkml.kernel.org/r/20160504205359.19db7...@viggo.jf.intel.com
> Signed-off-by: Ingo Molnar <mi...@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

Reply via email to