Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 8 Jul 2019 23:59:34 +0000 (16:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 8 Jul 2019 23:59:34 +0000 (16:59 -0700)
Pull x86 asm updates from Ingo Molnar:
 "Most of the changes relate to Peter Zijlstra's cleanup of ptregs
  handling, in particular the i386 part is now much simplified and
  standardized - no more partial ptregs stack frames via the esp/ss
  oddity. This simplifies ftrace, kprobes, the unwinder, ptrace, kdump
  and kgdb.

  There's also a CR4 hardening enhancements by Kees Cook, to make the
  generic platform functions such as native_write_cr4() less useful as
  ROP gadgets that disable SMEP/SMAP. Also protect the WP bit of CR0
  against similar attacks.

  The rest is smaller cleanups/fixes"

* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/alternatives: Add int3_emulate_call() selftest
  x86/stackframe/32: Allow int3_emulate_push()
  x86/stackframe/32: Provide consistent pt_regs
  x86/stackframe, x86/ftrace: Add pt_regs frame annotations
  x86/stackframe, x86/kprobes: Fix frame pointer annotations
  x86/stackframe: Move ENCODE_FRAME_POINTER to asm/frame.h
  x86/entry/32: Clean up return from interrupt preemption path
  x86/asm: Pin sensitive CR0 bits
  x86/asm: Pin sensitive CR4 bits
  Documentation/x86: Fix path to entry_32.S
  x86/asm: Remove unused TASK_TI_flags from asm-offsets.c

1  2 
arch/x86/entry/entry_32.S
arch/x86/include/asm/text-patching.h
arch/x86/kernel/alternative.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/ftrace.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/time.c
arch/x86/kernel/unwind_orc.c

index 44c6e6f54bf7d4732ace4fc3f8267be8f46a2f1d,ab54923c2bd2a487476edfc142a9fe072e2b7960..1285e5abf669db58d94b0481f5f5aed9958e2d3e
@@@ -67,7 -67,6 +67,6 @@@
  # define preempt_stop(clobbers)       DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF
  #else
  # define preempt_stop(clobbers)
- # define resume_kernel                restore_all_kernel
  #endif
  
  .macro TRACE_IRQS_IRET
  .Lend_\@:
  .endm
  
+ #define CS_FROM_ENTRY_STACK   (1 << 31)
+ #define CS_FROM_USER_CR3      (1 << 30)
+ #define CS_FROM_KERNEL                (1 << 29)
+ .macro FIXUP_FRAME
+       /*
+        * The high bits of the CS dword (__csh) are used for CS_FROM_*.
+        * Clear them in case hardware didn't do this for us.
+        */
+       andl    $0x0000ffff, 3*4(%esp)
+ #ifdef CONFIG_VM86
+       testl   $X86_EFLAGS_VM, 4*4(%esp)
+       jnz     .Lfrom_usermode_no_fixup_\@
+ #endif
+       testl   $SEGMENT_RPL_MASK, 3*4(%esp)
+       jnz     .Lfrom_usermode_no_fixup_\@
+       orl     $CS_FROM_KERNEL, 3*4(%esp)
+       /*
+        * When we're here from kernel mode; the (exception) stack looks like:
+        *
+        *  5*4(%esp) - <previous context>
+        *  4*4(%esp) - flags
+        *  3*4(%esp) - cs
+        *  2*4(%esp) - ip
+        *  1*4(%esp) - orig_eax
+        *  0*4(%esp) - gs / function
+        *
+        * Lets build a 5 entry IRET frame after that, such that struct pt_regs
+        * is complete and in particular regs->sp is correct. This gives us
+        * the original 5 enties as gap:
+        *
+        * 12*4(%esp) - <previous context>
+        * 11*4(%esp) - gap / flags
+        * 10*4(%esp) - gap / cs
+        *  9*4(%esp) - gap / ip
+        *  8*4(%esp) - gap / orig_eax
+        *  7*4(%esp) - gap / gs / function
+        *  6*4(%esp) - ss
+        *  5*4(%esp) - sp
+        *  4*4(%esp) - flags
+        *  3*4(%esp) - cs
+        *  2*4(%esp) - ip
+        *  1*4(%esp) - orig_eax
+        *  0*4(%esp) - gs / function
+        */
+       pushl   %ss             # ss
+       pushl   %esp            # sp (points at ss)
+       addl    $6*4, (%esp)    # point sp back at the previous context
+       pushl   6*4(%esp)       # flags
+       pushl   6*4(%esp)       # cs
+       pushl   6*4(%esp)       # ip
+       pushl   6*4(%esp)       # orig_eax
+       pushl   6*4(%esp)       # gs / function
+ .Lfrom_usermode_no_fixup_\@:
+ .endm
+ .macro IRET_FRAME
+       testl $CS_FROM_KERNEL, 1*4(%esp)
+       jz .Lfinished_frame_\@
+       /*
+        * Reconstruct the 3 entry IRET frame right after the (modified)
+        * regs->sp without lowering %esp in between, such that an NMI in the
+        * middle doesn't scribble our stack.
+        */
+       pushl   %eax
+       pushl   %ecx
+       movl    5*4(%esp), %eax         # (modified) regs->sp
+       movl    4*4(%esp), %ecx         # flags
+       movl    %ecx, -4(%eax)
+       movl    3*4(%esp), %ecx         # cs
+       andl    $0x0000ffff, %ecx
+       movl    %ecx, -8(%eax)
+       movl    2*4(%esp), %ecx         # ip
+       movl    %ecx, -12(%eax)
+       movl    1*4(%esp), %ecx         # eax
+       movl    %ecx, -16(%eax)
+       popl    %ecx
+       lea     -16(%eax), %esp
+       popl    %eax
+ .Lfinished_frame_\@:
+ .endm
  .macro SAVE_ALL pt_regs_ax=%eax switch_stacks=0
        cld
        PUSH_GS
+       FIXUP_FRAME
        pushl   %fs
        pushl   %es
        pushl   %ds
  .Lend_\@:
  .endm
  
- /*
-  * This is a sneaky trick to help the unwinder find pt_regs on the stack.  The
-  * frame pointer is replaced with an encoded pointer to pt_regs.  The encoding
-  * is just clearing the MSB, which makes it an invalid stack address and is also
-  * a signal to the unwinder that it's a pt_regs pointer in disguise.
-  *
-  * NOTE: This macro must be used *after* SAVE_ALL because it corrupts the
-  * original rbp.
-  */
- .macro ENCODE_FRAME_POINTER
- #ifdef CONFIG_FRAME_POINTER
-       mov %esp, %ebp
-       andl $0x7fffffff, %ebp
- #endif
- .endm
  .macro RESTORE_INT_REGS
        popl    %ebx
        popl    %ecx
   * switch to it before we do any copying.
   */
  
- #define CS_FROM_ENTRY_STACK   (1 << 31)
- #define CS_FROM_USER_CR3      (1 << 30)
  .macro SWITCH_TO_KERNEL_STACK
  
        ALTERNATIVE     "", "jmp .Lend_\@", X86_FEATURE_XENPV
         * that register for the time this macro runs
         */
  
-       /*
-        * The high bits of the CS dword (__csh) are used for
-        * CS_FROM_ENTRY_STACK and CS_FROM_USER_CR3. Clear them in case
-        * hardware didn't do this for us.
-        */
-       andl    $(0x0000ffff), PT_CS(%esp)
        /* Are we on the entry stack? Bail out if not! */
        movl    PER_CPU_VAR(cpu_entry_area), %ecx
        addl    $CPU_ENTRY_AREA_entry_stack + SIZEOF_entry_stack, %ecx
@@@ -755,7 -821,7 +821,7 @@@ ret_from_intr
        andl    $SEGMENT_RPL_MASK, %eax
  #endif
        cmpl    $USER_RPL, %eax
-       jb      resume_kernel                   # not returning to v8086 or userspace
+       jb      restore_all_kernel              # not returning to v8086 or userspace
  
  ENTRY(resume_userspace)
        DISABLE_INTERRUPTS(CLBR_ANY)
        jmp     restore_all
  END(ret_from_exception)
  
- #ifdef CONFIG_PREEMPT
- ENTRY(resume_kernel)
-       DISABLE_INTERRUPTS(CLBR_ANY)
-       cmpl    $0, PER_CPU_VAR(__preempt_count)
-       jnz     restore_all_kernel
-       testl   $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ?
-       jz      restore_all_kernel
-       call    preempt_schedule_irq
-       jmp     restore_all_kernel
- END(resume_kernel)
- #endif
  GLOBAL(__begin_SYSENTER_singlestep_region)
  /*
   * All code from here through __end_SYSENTER_singlestep_region is subject
@@@ -1019,6 -1073,7 +1073,7 @@@ restore_all
        /* Restore user state */
        RESTORE_REGS pop=4                      # skip orig_eax/error_code
  .Lirq_return:
+       IRET_FRAME
        /*
         * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
         * when returning from IPI handler and when returning from
        INTERRUPT_RETURN
  
  restore_all_kernel:
+ #ifdef CONFIG_PREEMPT
+       DISABLE_INTERRUPTS(CLBR_ANY)
+       cmpl    $0, PER_CPU_VAR(__preempt_count)
+       jnz     .Lno_preempt
+       testl   $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ?
+       jz      .Lno_preempt
+       call    preempt_schedule_irq
+ .Lno_preempt:
+ #endif
        TRACE_IRQS_IRET
        PARANOID_EXIT_TO_KERNEL_MODE
        BUG_IF_WRONG_CR3
@@@ -1104,30 -1168,6 +1168,30 @@@ ENTRY(irq_entries_start
      .endr
  END(irq_entries_start)
  
 +#ifdef CONFIG_X86_LOCAL_APIC
 +      .align 8
 +ENTRY(spurious_entries_start)
 +    vector=FIRST_SYSTEM_VECTOR
 +    .rept (NR_VECTORS - FIRST_SYSTEM_VECTOR)
 +      pushl   $(~vector+0x80)                 /* Note: always in signed byte range */
 +    vector=vector+1
 +      jmp     common_spurious
 +      .align  8
 +    .endr
 +END(spurious_entries_start)
 +
 +common_spurious:
 +      ASM_CLAC
 +      addl    $-0x80, (%esp)                  /* Adjust vector into the [-256, -1] range */
 +      SAVE_ALL switch_stacks=1
 +      ENCODE_FRAME_POINTER
 +      TRACE_IRQS_OFF
 +      movl    %esp, %eax
 +      call    smp_spurious_interrupt
 +      jmp     ret_from_intr
 +ENDPROC(common_interrupt)
 +#endif
 +
  /*
   * the CPU automatically disables interrupts when executing an IRQ vector,
   * so IRQ-flags tracing has to follow that:
@@@ -1384,6 -1424,7 +1448,7 @@@ END(page_fault
  
  common_exception:
        /* the function address is in %gs's slot on the stack */
+       FIXUP_FRAME
        pushl   %fs
        pushl   %es
        pushl   %ds
index d83e9f771d863e3059d00da9168bae81a8b16c62,ebf185fa30bc730ef3eb64ebf12214e8bcaeee7f..70c09967a9996fb7186412d4ee66db0ed63a60da
@@@ -18,20 -18,6 +18,20 @@@ static inline void apply_paravirt(struc
  #define __parainstructions_end        NULL
  #endif
  
 +/*
 + * Currently, the max observed size in the kernel code is
 + * JUMP_LABEL_NOP_SIZE/RELATIVEJUMP_SIZE, which are 5.
 + * Raise it if needed.
 + */
 +#define POKE_MAX_OPCODE_SIZE  5
 +
 +struct text_poke_loc {
 +      void *detour;
 +      void *addr;
 +      size_t len;
 +      const char opcode[POKE_MAX_OPCODE_SIZE];
 +};
 +
  extern void text_poke_early(void *addr, const void *opcode, size_t len);
  
  /*
@@@ -52,7 -38,6 +52,7 @@@ extern void *text_poke(void *addr, cons
  extern void *text_poke_kgdb(void *addr, const void *opcode, size_t len);
  extern int poke_int3_handler(struct pt_regs *regs);
  extern void text_poke_bp(void *addr, const void *opcode, size_t len, void *handler);
 +extern void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries);
  extern int after_bootmem;
  extern __ro_after_init struct mm_struct *poking_mm;
  extern __ro_after_init unsigned long poking_addr;
@@@ -66,7 -51,6 +66,6 @@@ static inline void int3_emulate_jmp(str
  #define INT3_INSN_SIZE 1
  #define CALL_INSN_SIZE 5
  
- #ifdef CONFIG_X86_64
  static inline void int3_emulate_push(struct pt_regs *regs, unsigned long val)
  {
        /*
@@@ -84,7 -68,6 +83,6 @@@ static inline void int3_emulate_call(st
        int3_emulate_push(regs, regs->ip - INT3_INSN_SIZE + CALL_INSN_SIZE);
        int3_emulate_jmp(regs, func);
  }
- #endif /* CONFIG_X86_64 */
  #endif /* !CONFIG_UML_X86 */
  
  #endif /* _ASM_X86_TEXT_PATCHING_H */
index bd542f9b0953308b5ae7e76fd51b30cde02ab46e,65aa83d1b7d9a0dd6253137a6ff0be8206e9798f..c3468b5242fdeec3edb0f81704049ed1bc658fc7
@@@ -14,7 -14,6 +14,7 @@@
  #include <linux/kdebug.h>
  #include <linux/kprobes.h>
  #include <linux/mmu_context.h>
 +#include <linux/bsearch.h>
  #include <asm/text-patching.h>
  #include <asm/alternative.h>
  #include <asm/sections.h>
@@@ -616,11 -615,83 +616,83 @@@ extern struct paravirt_patch_site __sta
        __stop_parainstructions[];
  #endif        /* CONFIG_PARAVIRT */
  
+ /*
+  * Self-test for the INT3 based CALL emulation code.
+  *
+  * This exercises int3_emulate_call() to make sure INT3 pt_regs are set up
+  * properly and that there is a stack gap between the INT3 frame and the
+  * previous context. Without this gap doing a virtual PUSH on the interrupted
+  * stack would corrupt the INT3 IRET frame.
+  *
+  * See entry_{32,64}.S for more details.
+  */
+ static void __init int3_magic(unsigned int *ptr)
+ {
+       *ptr = 1;
+ }
+ extern __initdata unsigned long int3_selftest_ip; /* defined in asm below */
+ static int __init
+ int3_exception_notify(struct notifier_block *self, unsigned long val, void *data)
+ {
+       struct die_args *args = data;
+       struct pt_regs *regs = args->regs;
+       if (!regs || user_mode(regs))
+               return NOTIFY_DONE;
+       if (val != DIE_INT3)
+               return NOTIFY_DONE;
+       if (regs->ip - INT3_INSN_SIZE != int3_selftest_ip)
+               return NOTIFY_DONE;
+       int3_emulate_call(regs, (unsigned long)&int3_magic);
+       return NOTIFY_STOP;
+ }
+ static void __init int3_selftest(void)
+ {
+       static __initdata struct notifier_block int3_exception_nb = {
+               .notifier_call  = int3_exception_notify,
+               .priority       = INT_MAX-1, /* last */
+       };
+       unsigned int val = 0;
+       BUG_ON(register_die_notifier(&int3_exception_nb));
+       /*
+        * Basically: int3_magic(&val); but really complicated :-)
+        *
+        * Stick the address of the INT3 instruction into int3_selftest_ip,
+        * then trigger the INT3, padded with NOPs to match a CALL instruction
+        * length.
+        */
+       asm volatile ("1: int3; nop; nop; nop; nop\n\t"
+                     ".pushsection .init.data,\"aw\"\n\t"
+                     ".align " __ASM_SEL(4, 8) "\n\t"
+                     ".type int3_selftest_ip, @object\n\t"
+                     ".size int3_selftest_ip, " __ASM_SEL(4, 8) "\n\t"
+                     "int3_selftest_ip:\n\t"
+                     __ASM_SEL(.long, .quad) " 1b\n\t"
+                     ".popsection\n\t"
+                     : : __ASM_SEL_RAW(a, D) (&val) : "memory");
+       BUG_ON(val != 1);
+       unregister_die_notifier(&int3_exception_nb);
+ }
  void __init alternative_instructions(void)
  {
-       /* The patching is not fully atomic, so try to avoid local interruptions
-          that might execute the to be patched code.
-          Other CPUs are not running. */
+       int3_selftest();
+       /*
+        * The patching is not fully atomic, so try to avoid local
+        * interruptions that might execute the to be patched code.
+        * Other CPUs are not running.
+        */
        stop_nmi();
  
        /*
                                            _text, _etext);
        }
  
-       if (!uniproc_patched || num_possible_cpus() == 1)
+       if (!uniproc_patched || num_possible_cpus() == 1) {
                free_init_pages("SMP alternatives",
                                (unsigned long)__smp_locks,
                                (unsigned long)__smp_locks_end);
+       }
  #endif
  
        apply_paravirt(__parainstructions, __parainstructions_end);
@@@ -849,133 -921,81 +922,133 @@@ static void do_sync_core(void *info
        sync_core();
  }
  
 -static bool bp_patching_in_progress;
 -static void *bp_int3_handler, *bp_int3_addr;
 +static struct bp_patching_desc {
 +      struct text_poke_loc *vec;
 +      int nr_entries;
 +} bp_patching;
 +
 +static int patch_cmp(const void *key, const void *elt)
 +{
 +      struct text_poke_loc *tp = (struct text_poke_loc *) elt;
 +
 +      if (key < tp->addr)
 +              return -1;
 +      if (key > tp->addr)
 +              return 1;
 +      return 0;
 +}
 +NOKPROBE_SYMBOL(patch_cmp);
  
  int poke_int3_handler(struct pt_regs *regs)
  {
 +      struct text_poke_loc *tp;
 +      unsigned char int3 = 0xcc;
 +      void *ip;
 +
        /*
         * Having observed our INT3 instruction, we now must observe
 -       * bp_patching_in_progress.
 +       * bp_patching.nr_entries.
         *
 -       *      in_progress = TRUE              INT3
 +       *      nr_entries != 0                 INT3
         *      WMB                             RMB
 -       *      write INT3                      if (in_progress)
 +       *      write INT3                      if (nr_entries)
         *
 -       * Idem for bp_int3_handler.
 +       * Idem for other elements in bp_patching.
         */
        smp_rmb();
  
 -      if (likely(!bp_patching_in_progress))
 +      if (likely(!bp_patching.nr_entries))
                return 0;
  
 -      if (user_mode(regs) || regs->ip != (unsigned long)bp_int3_addr)
 +      if (user_mode(regs))
                return 0;
  
 -      /* set up the specified breakpoint handler */
 -      regs->ip = (unsigned long) bp_int3_handler;
 +      /*
 +       * Discount the sizeof(int3). See text_poke_bp_batch().
 +       */
 +      ip = (void *) regs->ip - sizeof(int3);
 +
 +      /*
 +       * Skip the binary search if there is a single member in the vector.
 +       */
 +      if (unlikely(bp_patching.nr_entries > 1)) {
 +              tp = bsearch(ip, bp_patching.vec, bp_patching.nr_entries,
 +                           sizeof(struct text_poke_loc),
 +                           patch_cmp);
 +              if (!tp)
 +                      return 0;
 +      } else {
 +              tp = bp_patching.vec;
 +              if (tp->addr != ip)
 +                      return 0;
 +      }
 +
 +      /* set up the specified breakpoint detour */
 +      regs->ip = (unsigned long) tp->detour;
  
        return 1;
  }
  NOKPROBE_SYMBOL(poke_int3_handler);
  
  /**
 - * text_poke_bp() -- update instructions on live kernel on SMP
 - * @addr:     address to patch
 - * @opcode:   opcode of new instruction
 - * @len:      length to copy
 - * @handler:  address to jump to when the temporary breakpoint is hit
 + * text_poke_bp_batch() -- update instructions on live kernel on SMP
 + * @tp:                       vector of instructions to patch
 + * @nr_entries:               number of entries in the vector
   *
   * Modify multi-byte instruction by using int3 breakpoint on SMP.
   * We completely avoid stop_machine() here, and achieve the
   * synchronization using int3 breakpoint.
   *
   * The way it is done:
 - *    - add a int3 trap to the address that will be patched
 + *    - For each entry in the vector:
 + *            - add a int3 trap to the address that will be patched
   *    - sync cores
 - *    - update all but the first byte of the patched range
 + *    - For each entry in the vector:
 + *            - update all but the first byte of the patched range
   *    - sync cores
 - *    - replace the first byte (int3) by the first byte of
 - *      replacing opcode
 + *    - For each entry in the vector:
 + *            - replace the first byte (int3) by the first byte of
 + *              replacing opcode
   *    - sync cores
   */
 -void text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
 +void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries)
  {
 +      int patched_all_but_first = 0;
        unsigned char int3 = 0xcc;
 -
 -      bp_int3_handler = handler;
 -      bp_int3_addr = (u8 *)addr + sizeof(int3);
 -      bp_patching_in_progress = true;
 +      unsigned int i;
  
        lockdep_assert_held(&text_mutex);
  
 +      bp_patching.vec = tp;
 +      bp_patching.nr_entries = nr_entries;
 +
        /*
         * Corresponding read barrier in int3 notifier for making sure the
 -       * in_progress and handler are correctly ordered wrt. patching.
 +       * nr_entries and handler are correctly ordered wrt. patching.
         */
        smp_wmb();
  
 -      text_poke(addr, &int3, sizeof(int3));
 +      /*
 +       * First step: add a int3 trap to the address that will be patched.
 +       */
 +      for (i = 0; i < nr_entries; i++)
 +              text_poke(tp[i].addr, &int3, sizeof(int3));
  
        on_each_cpu(do_sync_core, NULL, 1);
  
 -      if (len - sizeof(int3) > 0) {
 -              /* patch all but the first byte */
 -              text_poke((char *)addr + sizeof(int3),
 -                        (const char *) opcode + sizeof(int3),
 -                        len - sizeof(int3));
 +      /*
 +       * Second step: update all but the first byte of the patched range.
 +       */
 +      for (i = 0; i < nr_entries; i++) {
 +              if (tp[i].len - sizeof(int3) > 0) {
 +                      text_poke((char *)tp[i].addr + sizeof(int3),
 +                                (const char *)tp[i].opcode + sizeof(int3),
 +                                tp[i].len - sizeof(int3));
 +                      patched_all_but_first++;
 +              }
 +      }
 +
 +      if (patched_all_but_first) {
                /*
                 * According to Intel, this core syncing is very likely
                 * not necessary and we'd be safe even without it. But
                on_each_cpu(do_sync_core, NULL, 1);
        }
  
 -      /* patch the first byte */
 -      text_poke(addr, opcode, sizeof(int3));
 +      /*
 +       * Third step: replace the first byte (int3) by the first byte of
 +       * replacing opcode.
 +       */
 +      for (i = 0; i < nr_entries; i++)
 +              text_poke(tp[i].addr, tp[i].opcode, sizeof(int3));
  
        on_each_cpu(do_sync_core, NULL, 1);
        /*
         * sync_core() implies an smp_mb() and orders this store against
         * the writing of the new instruction.
         */
 -      bp_patching_in_progress = false;
 +      bp_patching.vec = NULL;
 +      bp_patching.nr_entries = 0;
  }
  
 +/**
 + * text_poke_bp() -- update instructions on live kernel on SMP
 + * @addr:     address to patch
 + * @opcode:   opcode of new instruction
 + * @len:      length to copy
 + * @handler:  address to jump to when the temporary breakpoint is hit
 + *
 + * Update a single instruction with the vector in the stack, avoiding
 + * dynamically allocated memory. This function should be used when it is
 + * not possible to allocate memory.
 + */
 +void text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
 +{
 +      struct text_poke_loc tp = {
 +              .detour = handler,
 +              .addr = addr,
 +              .len = len,
 +      };
 +
 +      if (len > POKE_MAX_OPCODE_SIZE) {
 +              WARN_ONCE(1, "len is larger than %d\n", POKE_MAX_OPCODE_SIZE);
 +              return;
 +      }
 +
 +      memcpy((void *)tp.opcode, opcode, len);
 +
 +      text_poke_bp_batch(&tp, 1);
 +}
index dad20bc891d500a22af3f447e49da9119630bbf8,c578addfcf8a2ea8ff670cde565bb65ef22f8ec6..8febe90470f47ecb9e078e5cca21fbf897cb8512
@@@ -366,6 -366,25 +366,25 @@@ out
        cr4_clear_bits(X86_CR4_UMIP);
  }
  
+ DEFINE_STATIC_KEY_FALSE_RO(cr_pinning);
+ EXPORT_SYMBOL(cr_pinning);
+ unsigned long cr4_pinned_bits __ro_after_init;
+ EXPORT_SYMBOL(cr4_pinned_bits);
+ /*
+  * Once CPU feature detection is finished (and boot params have been
+  * parsed), record any of the sensitive CR bits that are set, and
+  * enable CR pinning.
+  */
+ static void __init setup_cr_pinning(void)
+ {
+       unsigned long mask;
+       mask = (X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP);
+       cr4_pinned_bits = this_cpu_read(cpu_tlbstate.cr4) & mask;
+       static_key_enable(&cr_pinning.key);
+ }
  /*
   * Protection Keys are not available in 32-bit mode.
   */
@@@ -801,30 -820,6 +820,30 @@@ static void init_speculation_control(st
        }
  }
  
 +static void init_cqm(struct cpuinfo_x86 *c)
 +{
 +      if (!cpu_has(c, X86_FEATURE_CQM_LLC)) {
 +              c->x86_cache_max_rmid  = -1;
 +              c->x86_cache_occ_scale = -1;
 +              return;
 +      }
 +
 +      /* will be overridden if occupancy monitoring exists */
 +      c->x86_cache_max_rmid = cpuid_ebx(0xf);
 +
 +      if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC) ||
 +          cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL) ||
 +          cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)) {
 +              u32 eax, ebx, ecx, edx;
 +
 +              /* QoS sub-leaf, EAX=0Fh, ECX=1 */
 +              cpuid_count(0xf, 1, &eax, &ebx, &ecx, &edx);
 +
 +              c->x86_cache_max_rmid  = ecx;
 +              c->x86_cache_occ_scale = ebx;
 +      }
 +}
 +
  void get_cpu_cap(struct cpuinfo_x86 *c)
  {
        u32 eax, ebx, ecx, edx;
                c->x86_capability[CPUID_7_0_EBX] = ebx;
                c->x86_capability[CPUID_7_ECX] = ecx;
                c->x86_capability[CPUID_7_EDX] = edx;
 +
 +              /* Check valid sub-leaf index before accessing it */
 +              if (eax >= 1) {
 +                      cpuid_count(0x00000007, 1, &eax, &ebx, &ecx, &edx);
 +                      c->x86_capability[CPUID_7_1_EAX] = eax;
 +              }
        }
  
        /* Extended state features: level 0x0000000d */
                c->x86_capability[CPUID_D_1_EAX] = eax;
        }
  
 -      /* Additional Intel-defined flags: level 0x0000000F */
 -      if (c->cpuid_level >= 0x0000000F) {
 -
 -              /* QoS sub-leaf, EAX=0Fh, ECX=0 */
 -              cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx);
 -              c->x86_capability[CPUID_F_0_EDX] = edx;
 -
 -              if (cpu_has(c, X86_FEATURE_CQM_LLC)) {
 -                      /* will be overridden if occupancy monitoring exists */
 -                      c->x86_cache_max_rmid = ebx;
 -
 -                      /* QoS sub-leaf, EAX=0Fh, ECX=1 */
 -                      cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx);
 -                      c->x86_capability[CPUID_F_1_EDX] = edx;
 -
 -                      if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) ||
 -                            ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) ||
 -                             (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) {
 -                              c->x86_cache_max_rmid = ecx;
 -                              c->x86_cache_occ_scale = ebx;
 -                      }
 -              } else {
 -                      c->x86_cache_max_rmid = -1;
 -                      c->x86_cache_occ_scale = -1;
 -              }
 -      }
 -
        /* AMD-defined flags: level 0x80000001 */
        eax = cpuid_eax(0x80000000);
        c->extended_cpuid_level = eax;
  
        init_scattered_cpuid_features(c);
        init_speculation_control(c);
 +      init_cqm(c);
  
        /*
         * Clear/Set all flags overridden by options, after probe.
@@@ -1468,6 -1483,7 +1487,7 @@@ void __init identify_boot_cpu(void
        enable_sep_cpu();
  #endif
        cpu_detect_tlb(&boot_cpu_data);
+       setup_cr_pinning();
  }
  
  void identify_secondary_cpu(struct cpuinfo_x86 *c)
diff --combined arch/x86/kernel/ftrace.c
index 76228525acd001819a71af803ba567f4f69cfda9,a4eea7bad4a1cb245815ec1daf5ca9391f813950..4b73f5937f41dc2f021f29af9eb58ce694fc28cd
@@@ -22,7 -22,6 +22,7 @@@
  #include <linux/init.h>
  #include <linux/list.h>
  #include <linux/module.h>
 +#include <linux/memory.h>
  
  #include <trace/syscall.h>
  
  #ifdef CONFIG_DYNAMIC_FTRACE
  
  int ftrace_arch_code_modify_prepare(void)
 +    __acquires(&text_mutex)
  {
 +      /*
 +       * Need to grab text_mutex to prevent a race from module loading
 +       * and live kernel patching from changing the text permissions while
 +       * ftrace has it set to "read/write".
 +       */
 +      mutex_lock(&text_mutex);
        set_kernel_text_rw();
        set_all_modules_text_rw();
        return 0;
  }
  
  int ftrace_arch_code_modify_post_process(void)
 +    __releases(&text_mutex)
  {
        set_all_modules_text_ro();
        set_kernel_text_ro();
 +      mutex_unlock(&text_mutex);
        return 0;
  }
  
@@@ -310,7 -300,6 +310,6 @@@ int ftrace_int3_handler(struct pt_regs 
  
        ip = regs->ip - INT3_INSN_SIZE;
  
- #ifdef CONFIG_X86_64
        if (ftrace_location(ip)) {
                int3_emulate_call(regs, (unsigned long)ftrace_regs_caller);
                return 1;
                int3_emulate_call(regs, ftrace_update_func_call);
                return 1;
        }
- #else
-       if (ftrace_location(ip) || is_ftrace_caller(ip)) {
-               int3_emulate_jmp(regs, ip + CALL_INSN_SIZE);
-               return 1;
-       }
- #endif
  
        return 0;
  }
diff --combined arch/x86/kernel/ptrace.c
index ee9099061d0190e93c5ec012fb0aec5259da1e19,1f92958d81658558723b0e99c4cc5e507e5e83b4..8eb1e58de043176759f544ba4425b2e86df5aee4
@@@ -25,7 -25,6 +25,7 @@@
  #include <linux/rcupdate.h>
  #include <linux/export.h>
  #include <linux/context_tracking.h>
 +#include <linux/nospec.h>
  
  #include <linux/uaccess.h>
  #include <asm/pgtable.h>
@@@ -155,35 -154,6 +155,6 @@@ static inline bool invalid_selector(u1
  
  #define FLAG_MASK             FLAG_MASK_32
  
- /*
-  * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
-  * when it traps.  The previous stack will be directly underneath the saved
-  * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
-  *
-  * Now, if the stack is empty, '&regs->sp' is out of range. In this
-  * case we try to take the previous stack. To always return a non-null
-  * stack pointer we fall back to regs as stack if no previous stack
-  * exists.
-  *
-  * This is valid only for kernel mode traps.
-  */
- unsigned long kernel_stack_pointer(struct pt_regs *regs)
- {
-       unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1);
-       unsigned long sp = (unsigned long)&regs->sp;
-       u32 *prev_esp;
-       if (context == (sp & ~(THREAD_SIZE - 1)))
-               return sp;
-       prev_esp = (u32 *)(context);
-       if (*prev_esp)
-               return (unsigned long)*prev_esp;
-       return (unsigned long)regs;
- }
- EXPORT_SYMBOL_GPL(kernel_stack_pointer);
  static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
  {
        BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
@@@ -398,12 -368,22 +369,12 @@@ static int putreg(struct task_struct *c
        case offsetof(struct user_regs_struct,fs_base):
                if (value >= TASK_SIZE_MAX)
                        return -EIO;
 -              /*
 -               * When changing the FS base, use do_arch_prctl_64()
 -               * to set the index to zero and to set the base
 -               * as requested.
 -               */
 -              if (child->thread.fsbase != value)
 -                      return do_arch_prctl_64(child, ARCH_SET_FS, value);
 +              x86_fsbase_write_task(child, value);
                return 0;
        case offsetof(struct user_regs_struct,gs_base):
 -              /*
 -               * Exactly the same here as the %fs handling above.
 -               */
                if (value >= TASK_SIZE_MAX)
                        return -EIO;
 -              if (child->thread.gsbase != value)
 -                      return do_arch_prctl_64(child, ARCH_SET_GS, value);
 +              x86_gsbase_write_task(child, value);
                return 0;
  #endif
        }
@@@ -636,8 -616,7 +607,8 @@@ static unsigned long ptrace_get_debugre
        unsigned long val = 0;
  
        if (n < HBP_NUM) {
 -              struct perf_event *bp = thread->ptrace_bps[n];
 +              int index = array_index_nospec(n, HBP_NUM);
 +              struct perf_event *bp = thread->ptrace_bps[index];
  
                if (bp)
                        val = bp->hw.info.address;
@@@ -739,6 -718,9 +710,6 @@@ static int ioperm_get(struct task_struc
  void ptrace_disable(struct task_struct *child)
  {
        user_disable_single_step(child);
 -#ifdef TIF_SYSCALL_EMU
 -      clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
 -#endif
  }
  
  #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
diff --combined arch/x86/kernel/time.c
index 07c0e960b3f3b2d4ba84aa37c80a20ddf0288050,2acbab329754eba2811eb959df727928c944370f..7ce29cee9f9e624d7589b88834f764e5576a87e3
@@@ -37,8 -37,7 +37,7 @@@ unsigned long profile_pc(struct pt_reg
  #ifdef CONFIG_FRAME_POINTER
                return *(unsigned long *)(regs->bp + sizeof(long));
  #else
-               unsigned long *sp =
-                       (unsigned long *)kernel_stack_pointer(regs);
+               unsigned long *sp = (unsigned long *)regs->sp;
                /*
                 * Return address is either directly at stack pointer
                 * or above a saved flags. Eflags has bits 22-31 zero,
@@@ -82,11 -81,8 +81,11 @@@ static void __init setup_default_timer_
  /* Default timer init function */
  void __init hpet_time_init(void)
  {
 -      if (!hpet_enable())
 -              setup_pit_timer();
 +      if (!hpet_enable()) {
 +              if (!pit_timer_init())
 +                      return;
 +      }
 +
        setup_default_timer_irq();
  }
  
index 72b997eaa1fc6efd1ff1d214934d9ee452f2f0c1,7f79aeebe3ee00482e274544d57db77b8a3df930..332ae6530fa8813e5c6dda09f6457e1ded0eb436
@@@ -82,9 -82,9 +82,9 @@@ static struct orc_entry *orc_find(unsig
   * But they are copies of the ftrace entries that are static and
   * defined in ftrace_*.S, which do have orc entries.
   *
 - * If the undwinder comes across a ftrace trampoline, then find the
 + * If the unwinder comes across a ftrace trampoline, then find the
   * ftrace function that was used to create it, and use that ftrace
 - * function's orc entrie, as the placement of the return code in
 + * function's orc entry, as the placement of the return code in
   * the stack will be identical.
   */
  static struct orc_entry *orc_ftrace_find(unsigned long ip)
@@@ -128,16 -128,6 +128,16 @@@ static struct orc_entry null_orc_entry 
        .type = ORC_TYPE_CALL
  };
  
 +/* Fake frame pointer entry -- used as a fallback for generated code */
 +static struct orc_entry orc_fp_entry = {
 +      .type           = ORC_TYPE_CALL,
 +      .sp_reg         = ORC_REG_BP,
 +      .sp_offset      = 16,
 +      .bp_reg         = ORC_REG_PREV_SP,
 +      .bp_offset      = -16,
 +      .end            = 0,
 +};
 +
  static struct orc_entry *orc_find(unsigned long ip)
  {
        static struct orc_entry *orc;
@@@ -402,16 -392,8 +402,16 @@@ bool unwind_next_frame(struct unwind_st
         * calls and calls to noreturn functions.
         */
        orc = orc_find(state->signal ? state->ip : state->ip - 1);
 -      if (!orc)
 -              goto err;
 +      if (!orc) {
 +              /*
 +               * As a fallback, try to assume this code uses a frame pointer.
 +               * This is useful for generated code, like BPF, which ORC
 +               * doesn't know about.  This is just a guess, so the rest of
 +               * the unwind is no longer considered reliable.
 +               */
 +              orc = &orc_fp_entry;
 +              state->error = true;
 +      }
  
        /* End-of-stack check for kernel threads: */
        if (orc->sp_reg == ORC_REG_UNDEFINED) {
@@@ -598,7 -580,7 +598,7 @@@ void __unwind_start(struct unwind_stat
                        goto done;
  
                state->ip = regs->ip;
-               state->sp = kernel_stack_pointer(regs);
+               state->sp = regs->sp;
                state->bp = regs->bp;
                state->regs = regs;
                state->full_regs = true;