Commit ed8780e3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86-urgent-2020-10-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

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
parents 8c2ab803 abee7c49
...@@ -364,10 +364,10 @@ ...@@ -364,10 +364,10 @@
440 common process_madvise sys_process_madvise 440 common process_madvise sys_process_madvise
# #
# x32-specific system call numbers start at 512 to avoid cache impact # Due to a historical design error, certain syscalls are numbered differently
# for native 64-bit operation. The __x32_compat_sys stubs are created # in x32 as compared to native x86_64. These syscalls have numbers 512-547.
# on-the-fly for compat_sys_*() compatibility system calls if X86_X32 # Do not add new syscalls to this range. Numbers 548 and above are available
# is defined. # for non-x32 use.
# #
512 x32 rt_sigaction compat_sys_rt_sigaction 512 x32 rt_sigaction compat_sys_rt_sigaction
513 x32 rt_sigreturn compat_sys_x32_rt_sigreturn 513 x32 rt_sigreturn compat_sys_x32_rt_sigreturn
...@@ -405,3 +405,5 @@ ...@@ -405,3 +405,5 @@
545 x32 execveat compat_sys_execveat 545 x32 execveat compat_sys_execveat
546 x32 preadv2 compat_sys_preadv64v2 546 x32 preadv2 compat_sys_preadv64v2
547 x32 pwritev2 compat_sys_pwritev64v2 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.
...@@ -807,6 +807,15 @@ static inline temp_mm_state_t use_temporary_mm(struct mm_struct *mm) ...@@ -807,6 +807,15 @@ static inline temp_mm_state_t use_temporary_mm(struct mm_struct *mm)
temp_mm_state_t temp_state; temp_mm_state_t temp_state;
lockdep_assert_irqs_disabled(); 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); temp_state.mm = this_cpu_read(cpu_tlbstate.loaded_mm);
switch_mm_irqs_off(NULL, mm, current); switch_mm_irqs_off(NULL, mm, current);
......
...@@ -200,8 +200,7 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params, ...@@ -200,8 +200,7 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
params->hdr.hardware_subarch = boot_params.hdr.hardware_subarch; params->hdr.hardware_subarch = boot_params.hdr.hardware_subarch;
/* Copying screen_info will do? */ /* Copying screen_info will do? */
memcpy(&params->screen_info, &boot_params.screen_info, memcpy(&params->screen_info, &screen_info, sizeof(struct screen_info));
sizeof(struct screen_info));
/* Fill in memsize later */ /* Fill in memsize later */
params->screen_info.ext_mem_k = 0; params->screen_info.ext_mem_k = 0;
......
...@@ -321,19 +321,12 @@ EXPORT_SYMBOL_GPL(unwind_get_return_address); ...@@ -321,19 +321,12 @@ EXPORT_SYMBOL_GPL(unwind_get_return_address);
unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
{ {
struct task_struct *task = state->task;
if (unwind_done(state)) if (unwind_done(state))
return NULL; return NULL;
if (state->regs) if (state->regs)
return &state->regs->ip; 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) if (state->sp)
return (unsigned long *)state->sp - 1; return (unsigned long *)state->sp - 1;
...@@ -663,7 +656,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, ...@@ -663,7 +656,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
} else { } else {
struct inactive_task_frame *frame = (void *)task->thread.sp; 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->bp = READ_ONCE_NOCHECK(frame->bp);
state->ip = READ_ONCE_NOCHECK(frame->ret_addr); state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
state->signal = (void *)state->ip == ret_from_fork; state->signal = (void *)state->ip == ret_from_fork;
......
...@@ -1114,8 +1114,15 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) ...@@ -1114,8 +1114,15 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
getmem_done: getmem_done:
remove_conflicting_framebuffers(info->apertures, remove_conflicting_framebuffers(info->apertures,
KBUILD_MODNAME, false); KBUILD_MODNAME, false);
if (!gen2vm)
if (gen2vm) {
/* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */
screen_info.lfb_size = 0;
screen_info.lfb_base = 0;
screen_info.orig_video_isVGA = 0;
} else {
pci_dev_put(pdev); pci_dev_put(pdev);
}
kfree(info->apertures); kfree(info->apertures);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment