Merge branch 'parisc-5.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 21 Feb 2021 21:20:41 +0000 (13:20 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 21 Feb 2021 21:20:41 +0000 (13:20 -0800)
Pull parisc updates from Helge Deller:

 - Optimize parisc page table locks by using the existing
   page_table_lock

 - Export argv0-preserve flag in binfmt_misc for usage in qemu-user

 - Fix interrupt table (IVT) checksum so firmware will call crash
   handler (HPMC)

 - Increase IRQ stack to 64kb on 64-bit kernel

 - Switch to common devmem_is_allowed() implementation

 - Minor fix to get_whan()

* 'parisc-5.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  binfmt_misc: pass binfmt_misc flags to the interpreter
  parisc: Optimize per-pagetable spinlocks
  parisc: Replace test_ti_thread_flag() with test_tsk_thread_flag()
  parisc: Bump 64-bit IRQ stack size to 64 KB
  parisc: Fix IVT checksum calculation wrt HPMC
  parisc: Use the generic devmem_is_allowed()
  parisc: Drop out of get_whan() if task is running again

1  2 
arch/parisc/Kconfig
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c

diff --combined arch/parisc/Kconfig
@@@ -4,6 -4,7 +4,6 @@@ config PARIS
        select ARCH_32BIT_OFF_T if !64BIT
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select HAVE_IDE
 -      select HAVE_OPROFILE
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_SYSCALL_TRACEPOINTS
@@@ -34,6 -35,7 +34,7 @@@
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_CPU_DEVICES
        select GENERIC_STRNCPY_FROM_USER
+       select GENERIC_LIB_DEVMEM_IS_ALLOWED
        select SYSCTL_ARCH_UNALIGN_ALLOW
        select SYSCTL_EXCEPTION_TRACE
        select HAVE_MOD_ARCH_SPECIFIC
@@@ -310,6 -312,16 +311,16 @@@ config IRQSTACK
          for handling hard and soft interrupts.  This can help avoid
          overflowing the process kernel stacks.
  
+ config TLB_PTLOCK
+       bool "Use page table locks in TLB fault handler"
+       depends on SMP
+       default n
+       help
+         Select this option to enable page table locking in the TLB
+         fault handler. This ensures that page table entries are
+         updated consistently on SMP machines at the expense of some
+         loss in performance.
  config HOTPLUG_CPU
        bool
        default y if SMP
@@@ -334,6 -346,7 +345,6 @@@ source "kernel/Kconfig.hz
  config COMPAT
        def_bool y
        depends on 64BIT
 -      select COMPAT_BINFMT_ELF if BINFMT_ELF
  
  config SYSVIPC_COMPAT
        def_bool y
diff --combined fs/binfmt_elf.c
@@@ -186,6 -186,7 +186,7 @@@ create_elf_tables(struct linux_binprm *
        unsigned char k_rand_bytes[16];
        int items;
        elf_addr_t *elf_info;
+       elf_addr_t flags = 0;
        int ei_index;
        const struct cred *cred = current_cred();
        struct vm_area_struct *vma;
        NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
        NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
        NEW_AUX_ENT(AT_BASE, interp_load_addr);
-       NEW_AUX_ENT(AT_FLAGS, 0);
+       if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
+               flags |= AT_FLAGS_PRESERVE_ARGV0;
+       NEW_AUX_ENT(AT_FLAGS, flags);
        NEW_AUX_ENT(AT_ENTRY, e_entry);
        NEW_AUX_ENT(AT_UID, from_kuid_munged(cred->user_ns, cred->uid));
        NEW_AUX_ENT(AT_EUID, from_kuid_munged(cred->user_ns, cred->euid));
@@@ -1495,7 -1498,7 +1498,7 @@@ static void fill_note(struct memelfnot
   * fill up all the fields in prstatus from the given task struct, except
   * registers which need to be filled up separately.
   */
 -static void fill_prstatus(struct elf_prstatus *prstatus,
 +static void fill_prstatus(struct elf_prstatus_common *prstatus,
                struct task_struct *p, long signr)
  {
        prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
@@@ -1717,11 -1720,11 +1720,11 @@@ static void do_thread_regset_writeback(
  }
  
  #ifndef PRSTATUS_SIZE
 -#define PRSTATUS_SIZE(S, R) sizeof(S)
 +#define PRSTATUS_SIZE sizeof(struct elf_prstatus)
  #endif
  
  #ifndef SET_PR_FPVALID
 -#define SET_PR_FPVALID(S, V, R) ((S)->pr_fpvalid = (V))
 +#define SET_PR_FPVALID(S) ((S)->pr_fpvalid = 1)
  #endif
  
  static int fill_thread_core_info(struct elf_thread_core_info *t,
                                 long signr, size_t *total)
  {
        unsigned int i;
 -      int regset0_size;
  
        /*
         * NT_PRSTATUS is the one special case, because the regset data
         * than being the whole note contents.  We fill the reset in here.
         * We assume that regset 0 is NT_PRSTATUS.
         */
 -      fill_prstatus(&t->prstatus, t->task, signr);
 -      regset0_size = regset_get(t->task, &view->regsets[0],
 +      fill_prstatus(&t->prstatus.common, t->task, signr);
 +      regset_get(t->task, &view->regsets[0],
                   sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);
 -      if (regset0_size < 0)
 -              return 0;
  
        fill_note(&t->notes[0], "CORE", NT_PRSTATUS,
 -                PRSTATUS_SIZE(t->prstatus, regset0_size), &t->prstatus);
 +                PRSTATUS_SIZE, &t->prstatus);
        *total += notesize(&t->notes[0]);
  
        do_thread_regset_writeback(t->task, &view->regsets[0]);
                        continue;
  
                if (is_fpreg)
 -                      SET_PR_FPVALID(&t->prstatus, 1, regset0_size);
 +                      SET_PR_FPVALID(&t->prstatus);
  
                fill_note(&t->notes[i], is_fpreg ? "CORE" : "LINUX",
                          note_type, ret, data);
@@@ -1958,7 -1964,7 +1961,7 @@@ static int elf_dump_thread_status(long 
        struct task_struct *p = t->thread;
        t->num_notes = 0;
  
 -      fill_prstatus(&t->prstatus, p, signr);
 +      fill_prstatus(&t->prstatus.common, p, signr);
        elf_core_copy_task_regs(p, &t->prstatus.pr_reg);        
        
        fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
@@@ -2037,7 -2043,7 +2040,7 @@@ static int fill_note_info(struct elfhd
        }
        /* now collect the dump for the current */
        memset(info->prstatus, 0, sizeof(*info->prstatus));
 -      fill_prstatus(info->prstatus, current, siginfo->si_signo);
 +      fill_prstatus(&info->prstatus->common, current, siginfo->si_signo);
        elf_core_copy_regs(&info->prstatus->pr_reg, regs);
  
        /* Set up header */
diff --combined fs/binfmt_elf_fdpic.c
@@@ -506,6 -506,7 +506,7 @@@ static int create_elf_fdpic_tables(stru
        char __user *u_platform, *u_base_platform, *p;
        int loop;
        int nr; /* reset for each csp adjustment */
+       unsigned long flags = 0;
  
  #ifdef CONFIG_MMU
        /* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
        NEW_AUX_ENT(AT_PHENT,   sizeof(struct elf_phdr));
        NEW_AUX_ENT(AT_PHNUM,   exec_params->hdr.e_phnum);
        NEW_AUX_ENT(AT_BASE,    interp_params->elfhdr_addr);
-       NEW_AUX_ENT(AT_FLAGS,   0);
+       if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
+               flags |= AT_FLAGS_PRESERVE_ARGV0;
+       NEW_AUX_ENT(AT_FLAGS,   flags);
        NEW_AUX_ENT(AT_ENTRY,   exec_params->entry_addr);
        NEW_AUX_ENT(AT_UID,     (elf_addr_t) from_kuid_munged(cred->user_ns, cred->uid));
        NEW_AUX_ENT(AT_EUID,    (elf_addr_t) from_kuid_munged(cred->user_ns, cred->euid));
@@@ -1191,7 -1194,18 +1194,7 @@@ static int elf_fdpic_map_file_by_direct
  
  struct elf_prstatus_fdpic
  {
 -      struct elf_siginfo pr_info;     /* Info associated with signal */
 -      short   pr_cursig;              /* Current signal */
 -      unsigned long pr_sigpend;       /* Set of pending signals */
 -      unsigned long pr_sighold;       /* Set of held signals */
 -      pid_t   pr_pid;
 -      pid_t   pr_ppid;
 -      pid_t   pr_pgrp;
 -      pid_t   pr_sid;
 -      struct __kernel_old_timeval pr_utime;   /* User time */
 -      struct __kernel_old_timeval pr_stime;   /* System time */
 -      struct __kernel_old_timeval pr_cutime;  /* Cumulative user time */
 -      struct __kernel_old_timeval pr_cstime;  /* Cumulative system time */
 +      struct elf_prstatus_common      common;
        elf_gregset_t pr_reg;   /* GP registers */
        /* When using FDPIC, the loadmap addresses need to be communicated
         * to GDB in order for GDB to do the necessary relocations.  The
@@@ -1290,7 -1304,7 +1293,7 @@@ static inline void fill_note(struct mem
   * fill up all the fields in prstatus from the given task struct, except
   * registers which need to be filled up separately.
   */
 -static void fill_prstatus(struct elf_prstatus_fdpic *prstatus,
 +static void fill_prstatus(struct elf_prstatus_common *prstatus,
                          struct task_struct *p, long signr)
  {
        prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
        }
        prstatus->pr_cutime = ns_to_kernel_old_timeval(p->signal->cutime);
        prstatus->pr_cstime = ns_to_kernel_old_timeval(p->signal->cstime);
 -
 -      prstatus->pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
 -      prstatus->pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
  }
  
  static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
@@@ -1391,9 -1408,7 +1394,9 @@@ static struct elf_thread_status *elf_du
        if (!t)
                return t;
  
 -      fill_prstatus(&t->prstatus, p, signr);
 +      fill_prstatus(&t->prstatus.common, p, signr);
 +      t->prstatus.pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
 +      t->prstatus.pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
        regset_get(p, &view->regsets[0],
                   sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);