]> Git Repo - linux.git/commitdiff
Merge tag 'x86-urgent-2020-10-27' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Tue, 27 Oct 2020 21:39:29 +0000 (14:39 -0700)
committerLinus Torvalds <[email protected]>
Tue, 27 Oct 2020 21:39:29 +0000 (14:39 -0700)
Pull x86 fixes from Thomas Gleixner:
 "A couple of x86 fixes which missed rc1 due to my stupidity:

   - Drop lazy TLB mode before switching to the temporary address space
     for text patching.

     text_poke() switches to the temporary mm which clears the lazy mode
     and restores the original mm afterwards. Due to clearing lazy mode
     this might restore a already dead mm if exit_mmap() runs in
     parallel on another CPU.

   - Document the x32 syscall design fail vs. syscall numbers 512-547
     properly.

   - Fix the ORC unwinder to handle the inactive task frame correctly.

     This was unearthed due to the slightly different code generation of
     gcc-10.

   - Use an up to date screen_info for the boot params of kexec instead
     of the possibly stale and invalid version which happened to be
     valid when the kexec kernel was loaded"

* tag 'x86-urgent-2020-10-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/alternative: Don't call text_poke() in lazy TLB mode
  x86/syscalls: Document the fact that syscalls 512-547 are a legacy mistake
  x86/unwind/orc: Fix inactive tasks with stack pointer in %sp on GCC 10 compiled kernels
  hyperv_fb: Update screen_info after removing old framebuffer
  x86/kexec: Use up-to-dated screen_info copy to fill boot params

1  2 
arch/x86/entry/syscalls/syscall_64.tbl
arch/x86/kernel/alternative.c
arch/x86/kernel/unwind_orc.c

index 1f47e24fb65cf8a7525be8a53934eb4fa63da7d1,4adb5d2a3319e66f0e5ea7fe32b307a9ead3d97d..379819244b91d275b2c98f7ff38a59049c24b42a
  437   common  openat2                 sys_openat2
  438   common  pidfd_getfd             sys_pidfd_getfd
  439   common  faccessat2              sys_faccessat2
 +440   common  process_madvise         sys_process_madvise
  
  #
- # x32-specific system call numbers start at 512 to avoid cache impact
- # for native 64-bit operation. The __x32_compat_sys stubs are created
- # on-the-fly for compat_sys_*() compatibility system calls if X86_X32
- # is defined.
+ # Due to a historical design error, certain syscalls are numbered differently
+ # in x32 as compared to native x86_64.  These syscalls have numbers 512-547.
+ # Do not add new syscalls to this range.  Numbers 548 and above are available
+ # for non-x32 use.
  #
  512   x32     rt_sigaction            compat_sys_rt_sigaction
  513   x32     rt_sigreturn            compat_sys_x32_rt_sigreturn
  514   x32     ioctl                   compat_sys_ioctl
 -515   x32     readv                   compat_sys_readv
 -516   x32     writev                  compat_sys_writev
 +515   x32     readv                   sys_readv
 +516   x32     writev                  sys_writev
  517   x32     recvfrom                compat_sys_recvfrom
  518   x32     sendmsg                 compat_sys_sendmsg
  519   x32     recvmsg                 compat_sys_recvmsg
  529   x32     waitid                  compat_sys_waitid
  530   x32     set_robust_list         compat_sys_set_robust_list
  531   x32     get_robust_list         compat_sys_get_robust_list
 -532   x32     vmsplice                compat_sys_vmsplice
 +532   x32     vmsplice                sys_vmsplice
  533   x32     move_pages              compat_sys_move_pages
  534   x32     preadv                  compat_sys_preadv64
  535   x32     pwritev                 compat_sys_pwritev64
  536   x32     rt_tgsigqueueinfo       compat_sys_rt_tgsigqueueinfo
  537   x32     recvmmsg                compat_sys_recvmmsg_time64
  538   x32     sendmmsg                compat_sys_sendmmsg
 -539   x32     process_vm_readv        compat_sys_process_vm_readv
 -540   x32     process_vm_writev       compat_sys_process_vm_writev
 +539   x32     process_vm_readv        sys_process_vm_readv
 +540   x32     process_vm_writev       sys_process_vm_writev
  541   x32     setsockopt              sys_setsockopt
  542   x32     getsockopt              sys_getsockopt
  543   x32     io_setup                compat_sys_io_setup
  545   x32     execveat                compat_sys_execveat
  546   x32     preadv2                 compat_sys_preadv64v2
  547   x32     pwritev2                compat_sys_pwritev64v2
+ # This is the end of the legacy x32 range.  Numbers 548 and above are
+ # not special and are not to be used for x32-specific syscalls.
index 4adbe65afe235f9a71f290e874486d4a1dbfa3cf,cd6be6f143e85540399d106465c28e0657237f52..2400ad62f330b9f518b3bcfa3462f5fd2e659e78
@@@ -807,6 -807,15 +807,15 @@@ static inline temp_mm_state_t use_tempo
        temp_mm_state_t temp_state;
  
        lockdep_assert_irqs_disabled();
+       /*
+        * Make sure not to be in TLB lazy mode, as otherwise we'll end up
+        * with a stale address space WITHOUT being in lazy mode after
+        * restoring the previous mm.
+        */
+       if (this_cpu_read(cpu_tlbstate.is_lazy))
+               leave_mm(smp_processor_id());
        temp_state.mm = this_cpu_read(cpu_tlbstate.loaded_mm);
        switch_mm_irqs_off(NULL, mm, current);
  
@@@ -1103,10 -1112,6 +1112,10 @@@ noinstr int poke_int3_handler(struct pt
                 */
                goto out_put;
  
 +      case RET_INSN_OPCODE:
 +              int3_emulate_ret(regs);
 +              break;
 +
        case CALL_INSN_OPCODE:
                int3_emulate_call(regs, (long)ip + tp->rel32);
                break;
@@@ -1281,7 -1286,6 +1290,7 @@@ static void text_poke_loc_init(struct t
  
        switch (tp->opcode) {
        case INT3_INSN_OPCODE:
 +      case RET_INSN_OPCODE:
                break;
  
        case CALL_INSN_OPCODE:
index 6a339ce328e0a7eb2546ae1f5f8517b293100226,4a96aa3de7d8acf38cf302b2ee09d89f91584df8..73f8001000669e2595fe8a4a9eeb7bf9108e9c62
@@@ -1,5 -1,4 +1,5 @@@
  // SPDX-License-Identifier: GPL-2.0-only
 +#include <linux/objtool.h>
  #include <linux/module.h>
  #include <linux/sort.h>
  #include <asm/ptrace.h>
@@@ -128,12 -127,12 +128,12 @@@ static struct orc_entry null_orc_entry 
        .sp_offset = sizeof(long),
        .sp_reg = ORC_REG_SP,
        .bp_reg = ORC_REG_UNDEFINED,
 -      .type = ORC_TYPE_CALL
 +      .type = UNWIND_HINT_TYPE_CALL
  };
  
  /* Fake frame pointer entry -- used as a fallback for generated code */
  static struct orc_entry orc_fp_entry = {
 -      .type           = ORC_TYPE_CALL,
 +      .type           = UNWIND_HINT_TYPE_CALL,
        .sp_reg         = ORC_REG_BP,
        .sp_offset      = 16,
        .bp_reg         = ORC_REG_PREV_SP,
@@@ -321,19 -320,12 +321,12 @@@ EXPORT_SYMBOL_GPL(unwind_get_return_add
  
  unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
  {
-       struct task_struct *task = state->task;
        if (unwind_done(state))
                return NULL;
  
        if (state->regs)
                return &state->regs->ip;
  
-       if (task != current && state->sp == task->thread.sp) {
-               struct inactive_task_frame *frame = (void *)task->thread.sp;
-               return &frame->ret_addr;
-       }
        if (state->sp)
                return (unsigned long *)state->sp - 1;
  
@@@ -532,7 -524,7 +525,7 @@@ bool unwind_next_frame(struct unwind_st
  
        /* Find IP, SP and possibly regs: */
        switch (orc->type) {
 -      case ORC_TYPE_CALL:
 +      case UNWIND_HINT_TYPE_CALL:
                ip_p = sp - sizeof(long);
  
                if (!deref_stack_reg(state, ip_p, &state->ip))
                state->signal = false;
                break;
  
 -      case ORC_TYPE_REGS:
 +      case UNWIND_HINT_TYPE_REGS:
                if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) {
                        orc_warn_current("can't access registers at %pB\n",
                                         (void *)orig_ip);
                state->signal = true;
                break;
  
 -      case ORC_TYPE_REGS_IRET:
 +      case UNWIND_HINT_TYPE_REGS_PARTIAL:
                if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) {
                        orc_warn_current("can't access iret registers at %pB\n",
                                         (void *)orig_ip);
@@@ -663,7 -655,7 +656,7 @@@ void __unwind_start(struct unwind_stat
        } else {
                struct inactive_task_frame *frame = (void *)task->thread.sp;
  
-               state->sp = task->thread.sp;
+               state->sp = task->thread.sp + sizeof(*frame);
                state->bp = READ_ONCE_NOCHECK(frame->bp);
                state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
                state->signal = (void *)state->ip == ret_from_fork;
This page took 0.078275 seconds and 4 git commands to generate.