]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 4 Jan 2018 00:41:07 +0000 (16:41 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 4 Jan 2018 00:41:07 +0000 (16:41 -0800)
Pull x86 page table isolation fixes from Thomas Gleixner:
 "A couple of urgent fixes for PTI:

   - Fix a PTE mismatch between user and kernel visible mapping of the
     cpu entry area (differs vs. the GLB bit) and causes a TLB mismatch
     MCE on older AMD K8 machines

   - Fix the misplaced CR3 switch in the SYSCALL compat entry code which
     causes access to unmapped kernel memory resulting in double faults.

   - Fix the section mismatch of the cpu_tss_rw percpu storage caused by
     using a different mechanism for declaration and definition.

   - Two fixes for dumpstack which help to decode entry stack issues
     better

   - Enable PTI by default in Kconfig. We should have done that earlier,
     but it slipped through the cracks.

   - Exclude AMD from the PTI enforcement. Not necessarily a fix, but if
     AMD is so confident that they are not affected, then we should not
     burden users with the overhead"

* 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/process: Define cpu_tss_rw in same section as declaration
  x86/pti: Switch to kernel CR3 at early in entry_SYSCALL_compat()
  x86/dumpstack: Print registers for first stack frame
  x86/dumpstack: Fix partial register dumps
  x86/pti: Make sure the user/kernel PTEs match
  x86/cpu, x86/pti: Do not enable PTI on AMD processors
  x86/pti: Enable PTI by default

1  2 
arch/x86/kernel/cpu/common.c
arch/x86/kernel/process.c
arch/x86/kernel/stacktrace.c

index c47de4ebf63a3e84a64511662c08d5b20faa94db,b1be494ab4e8badf1bb225e34a7a7e4203af6de4..7d9e3b06209b8f36bf1ddd690308df76485c7950
@@@ -329,30 -329,6 +329,30 @@@ static __always_inline void setup_smap(
        }
  }
  
 +static __always_inline void setup_umip(struct cpuinfo_x86 *c)
 +{
 +      /* Check the boot processor, plus build option for UMIP. */
 +      if (!cpu_feature_enabled(X86_FEATURE_UMIP))
 +              goto out;
 +
 +      /* Check the current processor's cpuid bits. */
 +      if (!cpu_has(c, X86_FEATURE_UMIP))
 +              goto out;
 +
 +      cr4_set_bits(X86_CR4_UMIP);
 +
 +      pr_info("x86/cpu: Activated the Intel User Mode Instruction Prevention (UMIP) CPU feature\n");
 +
 +      return;
 +
 +out:
 +      /*
 +       * Make sure UMIP is disabled in case it was enabled in a
 +       * previous boot (e.g., via kexec).
 +       */
 +      cr4_clear_bits(X86_CR4_UMIP);
 +}
 +
  /*
   * Protection Keys are not available in 32-bit mode.
   */
@@@ -882,8 -858,8 +882,8 @@@ static void identify_cpu_without_cpuid(
   * cache alignment.
   * The others are not touched to avoid unwanted side effects.
   *
 - * WARNING: this function is only called on the BP.  Don't add code here
 - * that is supposed to run on all CPUs.
 + * WARNING: this function is only called on the boot CPU.  Don't add code
 + * here that is supposed to run on all CPUs.
   */
  static void __init early_identify_cpu(struct cpuinfo_x86 *c)
  {
  
        setup_force_cpu_cap(X86_FEATURE_ALWAYS);
  
-       /* Assume for now that ALL x86 CPUs are insecure */
-       setup_force_cpu_bug(X86_BUG_CPU_INSECURE);
+       if (c->x86_vendor != X86_VENDOR_AMD)
+               setup_force_cpu_bug(X86_BUG_CPU_INSECURE);
  
        fpu__init_system(c);
  
@@@ -1170,10 -1146,9 +1170,10 @@@ static void identify_cpu(struct cpuinfo
        /* Disable the PN if appropriate */
        squash_the_stupid_serial_number(c);
  
 -      /* Set up SMEP/SMAP */
 +      /* Set up SMEP/SMAP/UMIP */
        setup_smep(c);
        setup_smap(c);
 +      setup_umip(c);
  
        /*
         * The vendor-specific functions might have changed features.
index aed9d94bd46f41bb049b8e0153a44a43d97e80b4,3cb2486c47e48a16e5daf9335f912ecda0324ac9..832a6acd730fad70e1426052d502f6438b30e38e
@@@ -47,7 -47,7 +47,7 @@@
   * section. Since TSS's are completely CPU-local, we want them
   * on exact cacheline boundaries, to eliminate cacheline ping-pong.
   */
- __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss_rw) = {
+ __visible DEFINE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss_rw) = {
        .x86_tss = {
                /*
                 * .sp0 is only used when entering ring 0 from a lower
@@@ -306,7 -306,7 +306,7 @@@ void __switch_to_xtra(struct task_struc
        }
  
        if ((tifp ^ tifn) & _TIF_NOTSC)
 -              cr4_toggle_bits(X86_CR4_TSD);
 +              cr4_toggle_bits_irqsoff(X86_CR4_TSD);
  
        if ((tifp ^ tifn) & _TIF_NOCPUID)
                set_cpuid_faulting(!!(tifn & _TIF_NOCPUID));
index 20161ef53537c760d858388295f57d21ae2f7346,60244bfaf88f69c91732929ddda712767e1ff030..093f2ea5dd56b613d03ccaeeb87fd50900f64ba1
@@@ -30,7 -30,7 +30,7 @@@ static int save_stack_address(struct st
        return 0;
  }
  
 -static void __save_stack_trace(struct stack_trace *trace,
 +static void noinline __save_stack_trace(struct stack_trace *trace,
                               struct task_struct *task, struct pt_regs *regs,
                               bool nosched)
  {
@@@ -56,7 -56,6 +56,7 @@@
   */
  void save_stack_trace(struct stack_trace *trace)
  {
 +      trace->skip++;
        __save_stack_trace(trace, current, NULL, false);
  }
  EXPORT_SYMBOL_GPL(save_stack_trace);
@@@ -71,8 -70,6 +71,8 @@@ void save_stack_trace_tsk(struct task_s
        if (!try_get_task_stack(tsk))
                return;
  
 +      if (tsk == current)
 +              trace->skip++;
        __save_stack_trace(trace, tsk, NULL, true);
  
        put_task_stack(tsk);
@@@ -91,9 -88,8 +91,9 @@@ EXPORT_SYMBOL_GPL(save_stack_trace_tsk)
        }                                                       \
  })
  
 -static int __save_stack_trace_reliable(struct stack_trace *trace,
 -                                     struct task_struct *task)
 +static int __always_inline
 +__save_stack_trace_reliable(struct stack_trace *trace,
 +                          struct task_struct *task)
  {
        struct unwind_state state;
        struct pt_regs *regs;
        for (unwind_start(&state, task, NULL, NULL); !unwind_done(&state);
             unwind_next_frame(&state)) {
  
-               regs = unwind_get_entry_regs(&state);
+               regs = unwind_get_entry_regs(&state, NULL);
                if (regs) {
                        /*
                         * Kernel mode registers on the stack indicate an
@@@ -164,12 -160,8 +164,12 @@@ int save_stack_trace_tsk_reliable(struc
  {
        int ret;
  
 +      /*
 +       * If the task doesn't have a stack (e.g., a zombie), the stack is
 +       * "reliably" empty.
 +       */
        if (!try_get_task_stack(tsk))
 -              return -EINVAL;
 +              return 0;
  
        ret = __save_stack_trace_reliable(trace, tsk);