Merge tag 'powerpc-5.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Apr 2021 19:22:28 +0000 (12:22 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Apr 2021 19:22:28 +0000 (12:22 -0700)
Pull powerpc updates from Michael Ellerman:

 - Enable KFENCE for 32-bit.

 - Implement EBPF for 32-bit.

 - Convert 32-bit to do interrupt entry/exit in C.

 - Convert 64-bit BookE to do interrupt entry/exit in C.

 - Changes to our signal handling code to use user_access_begin/end()
   more extensively.

 - Add support for time namespaces (CONFIG_TIME_NS)

 - A series of fixes that allow us to reenable STRICT_KERNEL_RWX.

 - Other smaller features, fixes & cleanups.

Thanks to Alexey Kardashevskiy, Andreas Schwab, Andrew Donnellan, Aneesh
Kumar K.V, Athira Rajeev, Bhaskar Chowdhury, Bixuan Cui, Cédric Le
Goater, Chen Huang, Chris Packham, Christophe Leroy, Christopher M.
Riedl, Colin Ian King, Dan Carpenter, Daniel Axtens, Daniel Henrique
Barboza, David Gibson, Davidlohr Bueso, Denis Efremov, dingsenjie,
Dmitry Safonov, Dominic DeMarco, Fabiano Rosas, Ganesh Goudar, Geert
Uytterhoeven, Geetika Moolchandani, Greg Kurz, Guenter Roeck, Haren
Myneni, He Ying, Jiapeng Chong, Jordan Niethe, Laurent Dufour, Lee
Jones, Leonardo Bras, Li Huafei, Madhavan Srinivasan, Mahesh Salgaonkar,
Masahiro Yamada, Nathan Chancellor, Nathan Lynch, Nicholas Piggin,
Oliver O'Halloran, Paul Menzel, Pu Lehui, Randy Dunlap, Ravi Bangoria,
Rosen Penev, Russell Currey, Santosh Sivaraj, Sebastian Andrzej Siewior,
Segher Boessenkool, Shivaprasad G Bhat, Srikar Dronamraju, Stephen
Rothwell, Thadeu Lima de Souza Cascardo, Thomas Gleixner, Tony Ambardar,
Tyrel Datwyler, Vaibhav Jain, Vincenzo Frascino, Xiongwei Song, Yang Li,
Yu Kuai, and Zhang Yunkai.

* tag 'powerpc-5.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (302 commits)
  powerpc/signal32: Fix erroneous SIGSEGV on RT signal return
  powerpc: Avoid clang uninitialized warning in __get_user_size_allowed
  powerpc/papr_scm: Mark nvdimm as unarmed if needed during probe
  powerpc/kvm: Fix build error when PPC_MEM_KEYS/PPC_PSERIES=n
  powerpc/kasan: Fix shadow start address with modules
  powerpc/kernel/iommu: Use largepool as a last resort when !largealloc
  powerpc/kernel/iommu: Align size for IOMMU_PAGE_SIZE() to save TCEs
  powerpc/44x: fix spelling mistake in Kconfig "varients" -> "variants"
  powerpc/iommu: Annotate nested lock for lockdep
  powerpc/iommu: Do not immediately panic when failed IOMMU table allocation
  powerpc/iommu: Allocate it_map by vmalloc
  selftests/powerpc: remove unneeded semicolon
  powerpc/64s: remove unneeded semicolon
  powerpc/eeh: remove unneeded semicolon
  powerpc/selftests: Add selftest to test concurrent perf/ptrace events
  powerpc/selftests/perf-hwbreak: Add testcases for 2nd DAWR
  powerpc/selftests/perf-hwbreak: Coalesce event creation code
  powerpc/selftests/ptrace-hwbreak: Add testcases for 2nd DAWR
  powerpc/configs: Add IBMVNIC to some 64-bit configs
  selftests/powerpc: Add uaccess flush test
  ...

1  2 
Documentation/admin-guide/sysctl/net.rst
Documentation/powerpc/papr_hcalls.rst
arch/arm64/include/asm/vdso/gettimeofday.h
arch/powerpc/Kconfig
arch/powerpc/kernel/ptrace/ptrace-view.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/xmon/xmon.c
drivers/i2c/busses/Kconfig
include/linux/compat.h

@@@ -64,6 -64,7 +64,7 @@@ two flavors of JITs, the newer eBPF JI
    - arm64
    - arm32
    - ppc64
+   - ppc32
    - sparc64
    - mips64
    - s390x
@@@ -73,7 -74,6 +74,6 @@@
  And the older cBPF JIT supported on the following archs:
  
    - mips
-   - ppc
    - sparc
  
  eBPF JITs are a superset of cBPF JITs, meaning the kernel will
@@@ -311,17 -311,6 +311,17 @@@ permit to distribute the load on severa
  If set to 1 (default), timestamps are sampled as soon as possible, before
  queueing.
  
 +netdev_unregister_timeout_secs
 +------------------------------
 +
 +Unregister network device timeout in seconds.
 +This option controls the timeout (in seconds) used to issue a warning while
 +waiting for a network device refcount to drop to 0 during device
 +unregistration. A lower value may be useful during bisection to detect
 +a leaked reference faster. A larger value may be useful to prevent false
 +warnings on slow/loaded systems.
 +Default value is 10, minimum 1, maximum 3600.
 +
  optmem_max
  ----------
  
@@@ -40,7 -40,7 +40,7 @@@ and any in-arguments for the hcall are 
  have to be passed through a memory buffer, the data stored in that buffer should be
  in Big-endian byte order.
  
 -Once control is returns back to the guest after hypervisor has serviced the
 +Once control returns back to the guest after hypervisor has serviced the
  'HVCS' instruction the return value of the hcall is available in *r3* and any
  out values are returned in registers *r4-r12*. Again like in case of in-arguments,
  any out values stored in a memory buffer will be in Big-endian byte order.
@@@ -147,7 -147,7 +147,7 @@@ corresponding opcode values please loo
  | Out: *numBytesRead*
  | Return Value: *H_Success, H_Parameter, H_P2, H_P3, H_Hardware*
  
 -Given a DRC Index of an NVDIMM, read N-bytes from the the metadata area
 +Given a DRC Index of an NVDIMM, read N-bytes from the metadata area
  associated with it, at a specified offset and copy it to provided buffer.
  The metadata area stores configuration information such as label information,
  bad-blocks etc. The metadata area is located out-of-band of NVDIMM storage
@@@ -275,6 -275,20 +275,20 @@@ Health Bitmap Flags
  Given a DRC Index collect the performance statistics for NVDIMM and copy them
  to the resultBuffer.
  
+ **H_SCM_FLUSH**
+ | Input: *drcIndex, continue-token*
+ | Out: *continue-token*
+ | Return Value: *H_SUCCESS, H_Parameter, H_P2, H_BUSY*
+ Given a DRC Index Flush the data to backend NVDIMM device.
+ The hcall returns H_BUSY when the flush takes longer time and the hcall needs
+ to be issued multiple times in order to be completely serviced. The
+ *continue-token* from the output to be passed in the argument list of
+ subsequent hcalls to the hypervisor until the hcall is completely serviced
+ at which point H_SUCCESS or other error is returned by the hypervisor.
  References
  ==========
  .. [1] "Power Architecture Platform Reference"
@@@ -83,7 -83,11 +83,7 @@@ static __always_inline u64 __arch_get_h
         */
        isb();
        asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
 -      /*
 -       * This isb() is required to prevent that the seq lock is
 -       * speculated.#
 -       */
 -      isb();
 +      arch_counter_enforce_ordering(res);
  
        return res;
  }
@@@ -96,7 -100,7 +96,7 @@@ const struct vdso_data *__arch_get_vdso
  
  #ifdef CONFIG_TIME_NS
  static __always_inline
- const struct vdso_data *__arch_get_timens_vdso_data(void)
+ const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
  {
        return _timens_data;
  }
diff --combined arch/powerpc/Kconfig
@@@ -119,6 -119,7 +119,7 @@@ config PP
        #
        select ARCH_32BIT_OFF_T if PPC32
        select ARCH_HAS_DEBUG_VIRTUAL
+       select ARCH_HAS_DEBUG_VM_PGTABLE
        select ARCH_HAS_DEVMEM_IS_ALLOWED
        select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_MEMBARRIER_CALLBACKS
        select ARCH_HAS_MEMBARRIER_SYNC_CORE
        select ARCH_HAS_SCALED_CPUTIME          if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
-       select ARCH_HAS_STRICT_KERNEL_RWX       if (PPC32 && !HIBERNATION)
+       select ARCH_HAS_STRICT_KERNEL_RWX       if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION)
        select ARCH_HAS_TICK_BROADCAST          if GENERIC_CLOCKEVENTS_BROADCAST
        select ARCH_HAS_UACCESS_FLUSHCACHE
        select ARCH_HAS_COPY_MC                 if PPC64
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_MIGHT_HAVE_PC_SERIO
        select ARCH_OPTIONAL_KERNEL_RWX         if ARCH_HAS_STRICT_KERNEL_RWX
+       select ARCH_STACKWALK
        select ARCH_SUPPORTS_ATOMIC_RMW
        select ARCH_SUPPORTS_DEBUG_PAGEALLOC    if PPC32 || PPC_BOOK3S_64
        select ARCH_USE_BUILTIN_BSWAP
        select GENERIC_CPU_AUTOPROBE
        select GENERIC_CPU_VULNERABILITIES      if PPC_BARRIER_NOSPEC
        select GENERIC_EARLY_IOREMAP
+       select GENERIC_GETTIMEOFDAY
        select GENERIC_IRQ_SHOW
        select GENERIC_IRQ_SHOW_LEVEL
        select GENERIC_PCI_IOMAP                if PCI
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
-       select GENERIC_GETTIMEOFDAY
+       select GENERIC_VDSO_TIME_NS
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_HUGE_VMAP              if PPC_BOOK3S_64 && PPC_RADIX_MMU
        select HAVE_ARCH_JUMP_LABEL
+       select HAVE_ARCH_JUMP_LABEL_RELATIVE
        select HAVE_ARCH_KASAN                  if PPC32 && PPC_PAGE_SHIFT <= 14
        select HAVE_ARCH_KASAN_VMALLOC          if PPC32 && PPC_PAGE_SHIFT <= 14
        select HAVE_ARCH_KGDB
+       select HAVE_ARCH_KFENCE                 if PPC32
        select HAVE_ARCH_MMAP_RND_BITS
        select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
        select HAVE_ARCH_NVRAM_OPS
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ASM_MODVERSIONS
        select HAVE_C_RECORDMCOUNT
-       select HAVE_CBPF_JIT                    if !PPC64
        select HAVE_STACKPROTECTOR              if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13)
        select HAVE_STACKPROTECTOR              if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2)
        select HAVE_CONTEXT_TRACKING            if PPC64
        select HAVE_DEBUG_STACKOVERFLOW
        select HAVE_DYNAMIC_FTRACE
        select HAVE_DYNAMIC_FTRACE_WITH_REGS    if MPROFILE_KERNEL
-       select HAVE_EBPF_JIT                    if PPC64
+       select HAVE_EBPF_JIT
        select HAVE_EFFICIENT_UNALIGNED_ACCESS  if !(CPU_LITTLE_ENDIAN && POWER7_CPU)
        select HAVE_FAST_GUP
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_LIVEPATCH                   if HAVE_DYNAMIC_FTRACE_WITH_REGS
        select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_NMI                         if PERF_EVENTS || (PPC64 && PPC_BOOK3S)
-       select HAVE_HARDLOCKUP_DETECTOR_ARCH    if (PPC64 && PPC_BOOK3S)
-       select HAVE_OPTPROBES                   if PPC64
+       select HAVE_HARDLOCKUP_DETECTOR_ARCH    if PPC64 && PPC_BOOK3S && SMP
+       select HAVE_OPTPROBES
        select HAVE_PERF_EVENTS
        select HAVE_PERF_EVENTS_NMI             if PPC64
        select HAVE_HARDLOCKUP_DETECTOR_PERF    if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH
        select MMU_GATHER_RCU_TABLE_FREE
        select MMU_GATHER_PAGE_SIZE
        select HAVE_REGS_AND_STACK_ACCESS_API
-       select HAVE_RELIABLE_STACKTRACE         if PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN
+       select HAVE_RELIABLE_STACKTRACE
        select HAVE_SOFTIRQ_ON_OWN_STACK
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_VIRT_CPU_ACCOUNTING
@@@ -548,7 -552,7 +552,7 @@@ config KEXE
  config KEXEC_FILE
        bool "kexec file based system call"
        select KEXEC_CORE
 -      select HAVE_IMA_KEXEC
 +      select HAVE_IMA_KEXEC if IMA
        select BUILD_BIN2C
        select KEXEC_ELF
        depends on PPC64
@@@ -786,7 -790,7 +790,7 @@@ config THREAD_SHIF
  config DATA_SHIFT_BOOL
        bool "Set custom data alignment"
        depends on ADVANCED_OPTIONS
-       depends on STRICT_KERNEL_RWX || DEBUG_PAGEALLOC
+       depends on STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE
        depends on PPC_BOOK3S_32 || (PPC_8xx && !PIN_TLB_DATA && !STRICT_KERNEL_RWX)
        help
          This option allows you to set the kernel data alignment. When
  config DATA_SHIFT
        int "Data shift" if DATA_SHIFT_BOOL
        default 24 if STRICT_KERNEL_RWX && PPC64
-       range 17 28 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC) && PPC_BOOK3S_32
-       range 19 23 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC) && PPC_8xx
+       range 17 28 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_BOOK3S_32
+       range 19 23 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_8xx
        default 22 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
-       default 18 if DEBUG_PAGEALLOC && PPC_BOOK3S_32
+       default 18 if (DEBUG_PAGEALLOC || KFENCE) && PPC_BOOK3S_32
        default 23 if STRICT_KERNEL_RWX && PPC_8xx
-       default 23 if DEBUG_PAGEALLOC && PPC_8xx && PIN_TLB_DATA
-       default 19 if DEBUG_PAGEALLOC && PPC_8xx
+       default 23 if (DEBUG_PAGEALLOC || KFENCE) && PPC_8xx && PIN_TLB_DATA
+       default 19 if (DEBUG_PAGEALLOC || KFENCE) && PPC_8xx
        default PPC_PAGE_SHIFT
        help
          On Book3S 32 (603+), DBATs are used to map kernel text and rodata RO.
@@@ -1217,7 -1221,7 +1221,7 @@@ config TASK_SIZE_BOO
  config TASK_SIZE
        hex "Size of user task space" if TASK_SIZE_BOOL
        default "0x80000000" if PPC_8xx
-       default "0xb0000000" if PPC_BOOK3S_32 && STRICT_KERNEL_RWX
+       default "0xb0000000" if PPC_BOOK3S_32
        default "0xc0000000"
  endmenu
  
@@@ -111,7 -111,7 +111,7 @@@ static unsigned long get_user_msr(struc
        return task->thread.regs->msr | task->thread.fpexc_mode;
  }
  
- static int set_user_msr(struct task_struct *task, unsigned long msr)
+ static __always_inline int set_user_msr(struct task_struct *task, unsigned long msr)
  {
        task->thread.regs->msr &= ~MSR_DEBUGCHANGE;
        task->thread.regs->msr |= msr & MSR_DEBUGCHANGE;
@@@ -147,7 -147,7 +147,7 @@@ static int set_user_dscr(struct task_st
   * We prevent mucking around with the reserved area of trap
   * which are used internally by the kernel.
   */
- static int set_user_trap(struct task_struct *task, unsigned long trap)
+ static __always_inline int set_user_trap(struct task_struct *task, unsigned long trap)
  {
        set_trap(task->thread.regs, trap);
        return 0;
@@@ -221,17 -221,9 +221,9 @@@ static int gpr_get(struct task_struct *
  #ifdef CONFIG_PPC64
        struct membuf to_softe = membuf_at(&to, offsetof(struct pt_regs, softe));
  #endif
-       int i;
        if (target->thread.regs == NULL)
                return -EIO;
  
-       if (!FULL_REGS(target->thread.regs)) {
-               /* We have a partial register set.  Fill 14-31 with bogus values */
-               for (i = 14; i < 32; i++)
-                       target->thread.regs->gpr[i] = NV_REG_POISON;
-       }
        membuf_write(&to, target->thread.regs, sizeof(struct user_pt_regs));
  
        membuf_store(&to_msr, get_user_msr(target));
@@@ -252,8 -244,6 +244,6 @@@ static int gpr_set(struct task_struct *
        if (target->thread.regs == NULL)
                return -EIO;
  
-       CHECK_FULL_REGS(target->thread.regs);
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 target->thread.regs,
                                 0, PT_MSR * sizeof(reg));
@@@ -522,11 -512,13 +512,11 @@@ static const struct user_regset native_
                .size = sizeof(long), .align = sizeof(long),
                .regset_get = gpr_get, .set = gpr_set
        },
 -#ifdef CONFIG_PPC_FPU_REGS
        [REGSET_FPR] = {
                .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
                .size = sizeof(double), .align = sizeof(double),
                .regset_get = fpr_get, .set = fpr_set
        },
 -#endif
  #ifdef CONFIG_ALTIVEC
        [REGSET_VMX] = {
                .core_note_type = NT_PPC_VMX, .n = 34,
@@@ -659,6 -651,9 +649,9 @@@ int gpr32_set_common(struct task_struc
        const compat_ulong_t __user *u = ubuf;
        compat_ulong_t reg;
  
+       if (!kbuf && !user_read_access_begin(u, count))
+               return -EFAULT;
        pos /= sizeof(reg);
        count /= sizeof(reg);
  
                        regs[pos++] = *k++;
        else
                for (; count > 0 && pos < PT_MSR; --count) {
-                       if (__get_user(reg, u++))
-                               return -EFAULT;
+                       unsafe_get_user(reg, u++, Efault);
                        regs[pos++] = reg;
                }
  
        if (count > 0 && pos == PT_MSR) {
                if (kbuf)
                        reg = *k++;
-               else if (__get_user(reg, u++))
-                       return -EFAULT;
+               else
+                       unsafe_get_user(reg, u++, Efault);
                set_user_msr(target, reg);
                ++pos;
                --count;
                        ++k;
        } else {
                for (; count > 0 && pos <= PT_MAX_PUT_REG; --count) {
-                       if (__get_user(reg, u++))
-                               return -EFAULT;
+                       unsafe_get_user(reg, u++, Efault);
                        regs[pos++] = reg;
                }
                for (; count > 0 && pos < PT_TRAP; --count, ++pos)
-                       if (__get_user(reg, u++))
-                               return -EFAULT;
+                       unsafe_get_user(reg, u++, Efault);
        }
  
        if (count > 0 && pos == PT_TRAP) {
                if (kbuf)
                        reg = *k++;
-               else if (__get_user(reg, u++))
-                       return -EFAULT;
+               else
+                       unsafe_get_user(reg, u++, Efault);
                set_user_trap(target, reg);
                ++pos;
                --count;
        }
+       if (!kbuf)
+               user_read_access_end();
  
        kbuf = k;
        ubuf = u;
        count *= sizeof(reg);
        return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
                                         (PT_TRAP + 1) * sizeof(reg), -1);
+ Efault:
+       user_read_access_end();
+       return -EFAULT;
  }
  
  static int gpr32_get(struct task_struct *target,
                     const struct user_regset *regset,
                     struct membuf to)
  {
-       int i;
        if (target->thread.regs == NULL)
                return -EIO;
  
-       if (!FULL_REGS(target->thread.regs)) {
-               /*
-                * We have a partial register set.
-                * Fill 14-31 with bogus values.
-                */
-               for (i = 14; i < 32; i++)
-                       target->thread.regs->gpr[i] = NV_REG_POISON;
-       }
        return gpr32_get_common(target, regset, to,
                        &target->thread.regs->gpr[0]);
  }
@@@ -746,7 -734,6 +732,6 @@@ static int gpr32_set(struct task_struc
        if (target->thread.regs == NULL)
                return -EIO;
  
-       CHECK_FULL_REGS(target->thread.regs);
        return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
                        &target->thread.regs->gpr[0]);
  }
   * implementation that makes things simple for little endian only)
   */
  #define unsafe_put_sigset_t   unsafe_put_compat_sigset
- static inline int get_sigset_t(sigset_t *set,
-                              const compat_sigset_t __user *uset)
- {
-       return get_compat_sigset(set, uset);
- }
+ #define unsafe_get_sigset_t   unsafe_get_compat_sigset
  
  #define to_user_ptr(p)                ptr_to_compat(p)
  #define from_user_ptr(p)      compat_ptr(p)
  
  static __always_inline int
save_general_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame)
__unsafe_save_general_regs(struct pt_regs *regs, struct mcontext __user *frame)
  {
        elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
        int val, i;
  
-       WARN_ON(!FULL_REGS(regs));
        for (i = 0; i <= PT_RESULT; i ++) {
                /* Force usr to alway see softe as 1 (interrupts enabled) */
                if (i == PT_SOFTE)
@@@ -116,8 -109,8 +109,8 @@@ failed
        return 1;
  }
  
- static inline int restore_general_regs(struct pt_regs *regs,
              struct mcontext __user *sr)
+ static __always_inline int
__unsafe_restore_general_regs(struct pt_regs *regs, struct mcontext __user *sr)
  {
        elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
        int i;
        for (i = 0; i <= PT_RESULT; i++) {
                if ((i == PT_MSR) || (i == PT_SOFTE))
                        continue;
-               if (__get_user(gregs[i], &sr->mc_gregs[i]))
-                       return -EFAULT;
+               unsafe_get_user(gregs[i], &sr->mc_gregs[i], failed);
        }
        return 0;
+ failed:
+       return 1;
  }
  
  #else /* CONFIG_PPC64 */
        unsafe_copy_to_user(__us, __s, sizeof(*__us), label);           \
  } while (0)
  
- static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset)
- {
-       return copy_from_user(set, uset, sizeof(*uset));
- }
+ #define unsafe_get_sigset_t   unsafe_get_user_sigset
  
  #define to_user_ptr(p)                ((unsigned long)(p))
  #define from_user_ptr(p)      ((void __user *)(p))
  
  static __always_inline int
save_general_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame)
__unsafe_save_general_regs(struct pt_regs *regs, struct mcontext __user *frame)
  {
-       WARN_ON(!FULL_REGS(regs));
        unsafe_copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE, failed);
        return 0;
  
@@@ -161,23 -152,30 +152,30 @@@ failed
        return 1;
  }
  
- static inline int restore_general_regs(struct pt_regs *regs,
              struct mcontext __user *sr)
+ static __always_inline
int __unsafe_restore_general_regs(struct pt_regs *regs, struct mcontext __user *sr)
  {
        /* copy up to but not including MSR */
-       if (__copy_from_user(regs, &sr->mc_gregs,
-                               PT_MSR * sizeof(elf_greg_t)))
-               return -EFAULT;
+       unsafe_copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t), failed);
        /* copy from orig_r3 (the word after the MSR) up to the end */
-       if (__copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
-                               GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t)))
-               return -EFAULT;
+       unsafe_copy_from_user(&regs->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3],
+                             GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t), failed);
        return 0;
+ failed:
+       return 1;
  }
  #endif
  
  #define unsafe_save_general_regs(regs, frame, label) do {     \
-       if (save_general_regs_unsafe(regs, frame))      \
+       if (__unsafe_save_general_regs(regs, frame))            \
+               goto label;                                     \
+ } while (0)
+ #define unsafe_restore_general_regs(regs, frame, label) do {  \
+       if (__unsafe_restore_general_regs(regs, frame))         \
                goto label;                                     \
  } while (0)
  
@@@ -260,8 -258,8 +258,8 @@@ static void prepare_save_user_regs(int 
  #endif
  }
  
- static int save_user_regs_unsafe(struct pt_regs *regs, struct mcontext __user *frame,
-                                struct mcontext __user *tm_frame, int ctx_has_vsx_region)
+ static int __unsafe_save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
+                                  struct mcontext __user *tm_frame, int ctx_has_vsx_region)
  {
        unsigned long msr = regs->msr;
  
@@@ -338,7 -336,7 +336,7 @@@ failed
  }
  
  #define unsafe_save_user_regs(regs, frame, tm_frame, has_vsx, label) do { \
-       if (save_user_regs_unsafe(regs, frame, tm_frame, has_vsx))      \
+       if (__unsafe_save_user_regs(regs, frame, tm_frame, has_vsx))    \
                goto label;                                             \
  } while (0)
  
   * We also save the transactional registers to a second ucontext in the
   * frame.
   *
-  * See save_user_regs_unsafe() and signal_64.c:setup_tm_sigcontexts().
+  * See __unsafe_save_user_regs() and signal_64.c:setup_tm_sigcontexts().
   */
  static void prepare_save_tm_user_regs(void)
  {
@@@ -441,7 -439,7 +439,7 @@@ static int save_tm_user_regs_unsafe(str
  #endif /* CONFIG_VSX */
  #ifdef CONFIG_SPE
        /* SPE regs are not checkpointed with TM, so this section is
-        * simply the same as in save_user_regs_unsafe().
+        * simply the same as in __unsafe_save_user_regs().
         */
        if (current->thread.used_spe) {
                unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr,
@@@ -485,26 -483,25 +483,25 @@@ static int save_tm_user_regs_unsafe(str
  static long restore_user_regs(struct pt_regs *regs,
                              struct mcontext __user *sr, int sig)
  {
-       long err;
        unsigned int save_r2 = 0;
        unsigned long msr;
  #ifdef CONFIG_VSX
        int i;
  #endif
  
+       if (!user_read_access_begin(sr, sizeof(*sr)))
+               return 1;
        /*
         * restore general registers but not including MSR or SOFTE. Also
         * take care of keeping r2 (TLS) intact if not a signal
         */
        if (!sig)
                save_r2 = (unsigned int)regs->gpr[2];
-       err = restore_general_regs(regs, sr);
+       unsafe_restore_general_regs(regs, sr, failed);
        set_trap_norestart(regs);
-       err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
+       unsafe_get_user(msr, &sr->mc_gregs[PT_MSR], failed);
        if (!sig)
                regs->gpr[2] = (unsigned long) save_r2;
-       if (err)
-               return 1;
  
        /* if doing signal return, restore the previous little-endian mode */
        if (sig)
        regs->msr &= ~MSR_VEC;
        if (msr & MSR_VEC) {
                /* restore altivec registers from the stack */
-               if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
-                                    sizeof(sr->mc_vregs)))
-                       return 1;
+               unsafe_copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
+                                     sizeof(sr->mc_vregs), failed);
                current->thread.used_vr = true;
        } else if (current->thread.used_vr)
                memset(&current->thread.vr_state, 0,
                       ELF_NVRREG * sizeof(vector128));
  
        /* Always get VRSAVE back */
-       if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
-               return 1;
+       unsafe_get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32], failed);
        if (cpu_has_feature(CPU_FTR_ALTIVEC))
                mtspr(SPRN_VRSAVE, current->thread.vrsave);
  #endif /* CONFIG_ALTIVEC */
-       if (copy_fpr_from_user(current, &sr->mc_fregs))
-               return 1;
+       unsafe_copy_fpr_from_user(current, &sr->mc_fregs, failed);
  
  #ifdef CONFIG_VSX
        /*
                 * Restore altivec registers from the stack to a local
                 * buffer, then write this out to the thread_struct
                 */
-               if (copy_vsx_from_user(current, &sr->mc_vsregs))
-                       return 1;
+               unsafe_copy_vsx_from_user(current, &sr->mc_vsregs, failed);
                current->thread.used_vsr = true;
        } else if (current->thread.used_vsr)
                for (i = 0; i < 32 ; i++)
        regs->msr &= ~MSR_SPE;
        if (msr & MSR_SPE) {
                /* restore spe registers from the stack */
-               if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
-                                    ELF_NEVRREG * sizeof(u32)))
-                       return 1;
+               unsafe_copy_from_user(current->thread.evr, &sr->mc_vregs,
+                                     ELF_NEVRREG * sizeof(u32), failed);
                current->thread.used_spe = true;
        } else if (current->thread.used_spe)
                memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
  
        /* Always get SPEFSCR back */
-       if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs + ELF_NEVRREG))
-               return 1;
+       unsafe_get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs + ELF_NEVRREG, failed);
  #endif /* CONFIG_SPE */
  
+       user_read_access_end();
        return 0;
+ failed:
+       user_read_access_end();
+       return 1;
  }
  
  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
@@@ -590,7 -586,6 +586,6 @@@ static long restore_tm_user_regs(struc
                                 struct mcontext __user *sr,
                                 struct mcontext __user *tm_sr)
  {
-       long err;
        unsigned long msr, msr_hi;
  #ifdef CONFIG_VSX
        int i;
         * TFHAR is restored from the checkpointed NIP; TEXASR and TFIAR
         * were set by the signal delivery.
         */
-       err = restore_general_regs(regs, tm_sr);
-       err |= restore_general_regs(&current->thread.ckpt_regs, sr);
-       err |= __get_user(current->thread.tm_tfhar, &sr->mc_gregs[PT_NIP]);
-       err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
-       if (err)
+       if (!user_read_access_begin(sr, sizeof(*sr)))
                return 1;
  
+       unsafe_restore_general_regs(&current->thread.ckpt_regs, sr, failed);
+       unsafe_get_user(current->thread.tm_tfhar, &sr->mc_gregs[PT_NIP], failed);
+       unsafe_get_user(msr, &sr->mc_gregs[PT_MSR], failed);
        /* Restore the previous little-endian mode */
        regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
  
        regs->msr &= ~MSR_VEC;
        if (msr & MSR_VEC) {
                /* restore altivec registers from the stack */
-               if (__copy_from_user(&current->thread.ckvr_state, &sr->mc_vregs,
-                                    sizeof(sr->mc_vregs)) ||
-                   __copy_from_user(&current->thread.vr_state,
-                                    &tm_sr->mc_vregs,
-                                    sizeof(sr->mc_vregs)))
-                       return 1;
+               unsafe_copy_from_user(&current->thread.ckvr_state, &sr->mc_vregs,
+                                     sizeof(sr->mc_vregs), failed);
                current->thread.used_vr = true;
        } else if (current->thread.used_vr) {
                memset(&current->thread.vr_state, 0,
        }
  
        /* Always get VRSAVE back */
-       if (__get_user(current->thread.ckvrsave,
-                      (u32 __user *)&sr->mc_vregs[32]) ||
-           __get_user(current->thread.vrsave,
-                      (u32 __user *)&tm_sr->mc_vregs[32]))
-               return 1;
+       unsafe_get_user(current->thread.ckvrsave,
+                       (u32 __user *)&sr->mc_vregs[32], failed);
        if (cpu_has_feature(CPU_FTR_ALTIVEC))
                mtspr(SPRN_VRSAVE, current->thread.ckvrsave);
  #endif /* CONFIG_ALTIVEC */
  
        regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
  
-       if (copy_fpr_from_user(current, &sr->mc_fregs) ||
-           copy_ckfpr_from_user(current, &tm_sr->mc_fregs))
-               return 1;
+       unsafe_copy_fpr_from_user(current, &sr->mc_fregs, failed);
  
  #ifdef CONFIG_VSX
        regs->msr &= ~MSR_VSX;
                 * Restore altivec registers from the stack to a local
                 * buffer, then write this out to the thread_struct
                 */
-               if (copy_vsx_from_user(current, &tm_sr->mc_vsregs) ||
-                   copy_ckvsx_from_user(current, &sr->mc_vsregs))
-                       return 1;
+               unsafe_copy_ckvsx_from_user(current, &sr->mc_vsregs, failed);
                current->thread.used_vsr = true;
        } else if (current->thread.used_vsr)
                for (i = 0; i < 32 ; i++) {
         */
        regs->msr &= ~MSR_SPE;
        if (msr & MSR_SPE) {
-               if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
-                                    ELF_NEVRREG * sizeof(u32)))
-                       return 1;
+               unsafe_copy_from_user(current->thread.evr, &sr->mc_vregs,
+                                     ELF_NEVRREG * sizeof(u32), failed);
                current->thread.used_spe = true;
        } else if (current->thread.used_spe)
                memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
  
        /* Always get SPEFSCR back */
-       if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs
-                      + ELF_NEVRREG))
-               return 1;
+       unsafe_get_user(current->thread.spefscr,
+                       (u32 __user *)&sr->mc_vregs + ELF_NEVRREG, failed);
  #endif /* CONFIG_SPE */
  
-       /* Get the top half of the MSR from the user context */
-       if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
+       user_read_access_end();
+       if (!user_read_access_begin(tm_sr, sizeof(*tm_sr)))
                return 1;
+       unsafe_restore_general_regs(regs, tm_sr, failed);
+ #ifdef CONFIG_ALTIVEC
+       /* restore altivec registers from the stack */
+       if (msr & MSR_VEC)
+               unsafe_copy_from_user(&current->thread.vr_state, &tm_sr->mc_vregs,
+                                     sizeof(sr->mc_vregs), failed);
+       /* Always get VRSAVE back */
+       unsafe_get_user(current->thread.vrsave,
+                       (u32 __user *)&tm_sr->mc_vregs[32], failed);
+ #endif /* CONFIG_ALTIVEC */
+       unsafe_copy_ckfpr_from_user(current, &tm_sr->mc_fregs, failed);
+ #ifdef CONFIG_VSX
+       if (msr & MSR_VSX) {
+               /*
+                * Restore altivec registers from the stack to a local
+                * buffer, then write this out to the thread_struct
+                */
+               unsafe_copy_vsx_from_user(current, &tm_sr->mc_vsregs, failed);
+               current->thread.used_vsr = true;
+       }
+ #endif /* CONFIG_VSX */
+       /* Get the top half of the MSR from the user context */
+       unsafe_get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR], failed);
        msr_hi <<= 32;
+       user_read_access_end();
        /* If TM bits are set to the reserved value, it's an invalid context */
        if (MSR_TM_RESV(msr_hi))
                return 1;
        preempt_enable();
  
        return 0;
+ failed:
+       user_read_access_end();
+       return 1;
+ }
+ #else
+ static long restore_tm_user_regs(struct pt_regs *regs, struct mcontext __user *sr,
+                                struct mcontext __user *tm_sr)
+ {
+       return 0;
  }
  #endif
  
@@@ -775,7 -798,7 +798,7 @@@ int handle_rt_signal32(struct ksignal *
        else
                prepare_save_user_regs(1);
  
 -      if (!user_write_access_begin(frame, sizeof(*frame)))
 +      if (!user_access_begin(frame, sizeof(*frame)))
                goto badframe;
  
        /* Put the siginfo & fill in most of the ucontext */
                unsafe_put_user(PPC_INST_ADDI + __NR_rt_sigreturn, &mctx->mc_pad[0],
                                failed);
                unsafe_put_user(PPC_INST_SC, &mctx->mc_pad[1], failed);
 +              asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0]));
        }
        unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, failed);
  
 -      user_write_access_end();
 +      user_access_end();
  
        if (copy_siginfo_to_user(&frame->info, &ksig->info))
                goto badframe;
  
 -      if (tramp == (unsigned long)mctx->mc_pad)
 -              flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
 -
        regs->link = tramp;
  
  #ifdef CONFIG_PPC_FPU_REGS
        return 0;
  
  failed:
 -      user_write_access_end();
 +      user_access_end();
  
  badframe:
        signal_fault(tsk, regs, "handle_rt_signal32", frame);
@@@ -877,7 -902,7 +900,7 @@@ int handle_signal32(struct ksignal *ksi
        else
                prepare_save_user_regs(1);
  
 -      if (!user_write_access_begin(frame, sizeof(*frame)))
 +      if (!user_access_begin(frame, sizeof(*frame)))
                goto badframe;
        sc = (struct sigcontext __user *) &frame->sctx;
  
                /* Set up the sigreturn trampoline: li r0,sigret; sc */
                unsafe_put_user(PPC_INST_ADDI + __NR_sigreturn, &mctx->mc_pad[0], failed);
                unsafe_put_user(PPC_INST_SC, &mctx->mc_pad[1], failed);
 +              asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0]));
        }
 -      user_write_access_end();
 -
 -      if (tramp == (unsigned long)mctx->mc_pad)
 -              flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
 +      user_access_end();
  
        regs->link = tramp;
  
        return 0;
  
  failed:
 -      user_write_access_end();
 +      user_access_end();
  
  badframe:
        signal_fault(tsk, regs, "handle_signal32", frame);
@@@ -944,28 -971,31 +967,31 @@@ static int do_setcontext(struct ucontex
        sigset_t set;
        struct mcontext __user *mcp;
  
-       if (get_sigset_t(&set, &ucp->uc_sigmask))
+       if (!user_read_access_begin(ucp, sizeof(*ucp)))
                return -EFAULT;
+       unsafe_get_sigset_t(&set, &ucp->uc_sigmask, failed);
  #ifdef CONFIG_PPC64
        {
                u32 cmcp;
  
-               if (__get_user(cmcp, &ucp->uc_regs))
-                       return -EFAULT;
+               unsafe_get_user(cmcp, &ucp->uc_regs, failed);
                mcp = (struct mcontext __user *)(u64)cmcp;
-               /* no need to check access_ok(mcp), since mcp < 4GB */
        }
  #else
-       if (__get_user(mcp, &ucp->uc_regs))
-               return -EFAULT;
-       if (!access_ok(mcp, sizeof(*mcp)))
-               return -EFAULT;
+       unsafe_get_user(mcp, &ucp->uc_regs, failed);
  #endif
+       user_read_access_end();
        set_current_blocked(&set);
        if (restore_user_regs(regs, mcp, sig))
                return -EFAULT;
  
        return 0;
+ failed:
+       user_read_access_end();
+       return -EFAULT;
  }
  
  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
@@@ -979,11 -1009,15 +1005,15 @@@ static int do_setcontext_tm(struct ucon
        u32 cmcp;
        u32 tm_cmcp;
  
-       if (get_sigset_t(&set, &ucp->uc_sigmask))
+       if (!user_read_access_begin(ucp, sizeof(*ucp)))
                return -EFAULT;
  
-       if (__get_user(cmcp, &ucp->uc_regs) ||
-           __get_user(tm_cmcp, &tm_ucp->uc_regs))
+       unsafe_get_sigset_t(&set, &ucp->uc_sigmask, failed);
+       unsafe_get_user(cmcp, &ucp->uc_regs, failed);
+       user_read_access_end();
+       if (__get_user(tm_cmcp, &tm_ucp->uc_regs))
                return -EFAULT;
        mcp = (struct mcontext __user *)(u64)cmcp;
        tm_mcp = (struct mcontext __user *)(u64)tm_cmcp;
                return -EFAULT;
  
        return 0;
+ failed:
+       user_read_access_end();
+       return -EFAULT;
  }
  #endif
  
@@@ -1311,19 -1349,16 +1345,16 @@@ SYSCALL_DEFINE0(sigreturn
        struct sigcontext __user *sc;
        struct sigcontext sigctx;
        struct mcontext __user *sr;
-       void __user *addr;
        sigset_t set;
- #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-       struct mcontext __user *mcp, *tm_mcp;
-       unsigned long msr_hi;
- #endif
+       struct mcontext __user *mcp;
+       struct mcontext __user *tm_mcp = NULL;
+       unsigned long long msr_hi = 0;
  
        /* Always make any pending restarted system calls return -EINTR */
        current->restart_block.fn = do_no_restart_syscall;
  
        sf = (struct sigframe __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
        sc = &sf->sctx;
-       addr = sc;
        if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
                goto badframe;
  
  #endif
        set_current_blocked(&set);
  
- #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        mcp = (struct mcontext __user *)&sf->mctx;
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        tm_mcp = (struct mcontext __user *)&sf->mctx_transact;
        if (__get_user(msr_hi, &tm_mcp->mc_gregs[PT_MSR]))
                goto badframe;
+ #endif
        if (MSR_TM_ACTIVE(msr_hi<<32)) {
                if (!cpu_has_feature(CPU_FTR_TM))
                        goto badframe;
                if (restore_tm_user_regs(regs, mcp, tm_mcp))
                        goto badframe;
-       } else
- #endif
-       {
+       } else {
                sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
-               addr = sr;
-               if (!access_ok(sr, sizeof(*sr))
-                   || restore_user_regs(regs, sr, 1))
-                       goto badframe;
+               if (restore_user_regs(regs, sr, 1)) {
+                       signal_fault(current, regs, "sys_sigreturn", sr);
+                       force_sig(SIGSEGV);
+                       return 0;
+               }
        }
  
        set_thread_flag(TIF_RESTOREALL);
        return 0;
  
  badframe:
-       signal_fault(current, regs, "sys_sigreturn", addr);
+       signal_fault(current, regs, "sys_sigreturn", sc);
  
        force_sig(SIGSEGV);
        return 0;
@@@ -887,8 -887,7 +887,8 @@@ static long pSeries_lpar_hpte_updatepp(
  
        want_v = hpte_encode_avpn(vpn, psize, ssize);
  
 -      flags = (newpp & 7) | H_AVPN;
 +      flags = (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO)) | H_AVPN;
 +      flags |= (newpp & HPTE_R_KEY_HI) >> 48;
        if (mmu_has_feature(MMU_FTR_KERNEL_RO))
                /* Move pp0 into bit 8 (IBM 55) */
                flags |= (newpp & HPTE_R_PP0) >> 55;
@@@ -977,11 -976,13 +977,13 @@@ static void pSeries_lpar_hpte_updatebol
        slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
        BUG_ON(slot == -1);
  
-       flags = newpp & 7;
+       flags = newpp & (HPTE_R_PP | HPTE_R_N);
        if (mmu_has_feature(MMU_FTR_KERNEL_RO))
                /* Move pp0 into bit 8 (IBM 55) */
                flags |= (newpp & HPTE_R_PP0) >> 55;
  
+       flags |= ((newpp & HPTE_R_KEY_HI) >> 48) | (newpp & HPTE_R_KEY_LO);
        lpar_rc = plpar_pte_protect(flags, slot, 0);
  
        BUG_ON(lpar_rc != H_SUCCESS);
@@@ -1630,7 -1631,7 +1632,7 @@@ static int pseries_lpar_resize_hpt(unsi
                }
                msleep(delay);
                rc = plpar_resize_hpt_prepare(0, shift);
-       };
+       }
  
        switch (rc) {
        case H_SUCCESS:
diff --combined arch/powerpc/xmon/xmon.c
@@@ -54,6 -54,7 +54,7 @@@
  #include <asm/code-patching.h>
  #include <asm/sections.h>
  #include <asm/inst.h>
+ #include <asm/interrupt.h>
  
  #ifdef CONFIG_PPC64
  #include <asm/hvcall.h>
@@@ -605,7 -606,7 +606,7 @@@ static int xmon_core(struct pt_regs *re
                         * debugger break (IPI). This is similar to
                         * crash_kexec_secondary().
                         */
-                       if (TRAP(regs) != 0x100 || !wait_for_other_cpus(ncpus))
+                       if (TRAP(regs) !=  INTERRUPT_SYSTEM_RESET || !wait_for_other_cpus(ncpus))
                                smp_send_debugger_break();
  
                        wait_for_other_cpus(ncpus);
  
                if (!locked_down) {
                        /* for breakpoint or single step, print curr insn */
-                       if (bp || TRAP(regs) == 0xd00)
+                       if (bp || TRAP(regs) == INTERRUPT_TRACE)
                                ppc_inst_dump(regs->nip, 1, 0);
                        printf("enter ? for help\n");
                }
                disable_surveillance();
                if (!locked_down) {
                        /* for breakpoint or single step, print current insn */
-                       if (bp || TRAP(regs) == 0xd00)
+                       if (bp || TRAP(regs) == INTERRUPT_TRACE)
                                ppc_inst_dump(regs->nip, 1, 0);
                        printf("enter ? for help\n");
                }
@@@ -1769,9 -1770,12 +1770,12 @@@ static void excprint(struct pt_regs *fp
        printf("    sp: %lx\n", fp->gpr[1]);
        printf("   msr: %lx\n", fp->msr);
  
-       if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
+       if (trap == INTERRUPT_DATA_STORAGE ||
+           trap == INTERRUPT_DATA_SEGMENT ||
+           trap == INTERRUPT_ALIGNMENT ||
+           trap == INTERRUPT_MACHINE_CHECK) {
                printf("   dar: %lx\n", fp->dar);
-               if (trap != 0x380)
+               if (trap != INTERRUPT_DATA_SEGMENT)
                        printf(" dsisr: %lx\n", fp->dsisr);
        }
  
                       current->pid, current->comm);
        }
  
-       if (trap == 0x700)
+       if (trap == INTERRUPT_PROGRAM)
                print_bug_trap(fp);
  
        printf(linux_banner);
@@@ -1815,25 -1819,16 +1819,16 @@@ static void prregs(struct pt_regs *fp
        }
  
  #ifdef CONFIG_PPC64
-       if (FULL_REGS(fp)) {
-               for (n = 0; n < 16; ++n)
-                       printf("R%.2d = "REG"   R%.2d = "REG"\n",
-                              n, fp->gpr[n], n+16, fp->gpr[n+16]);
-       } else {
-               for (n = 0; n < 7; ++n)
-                       printf("R%.2d = "REG"   R%.2d = "REG"\n",
-                              n, fp->gpr[n], n+7, fp->gpr[n+7]);
-       }
+ #define R_PER_LINE 2
  #else
+ #define R_PER_LINE 4
+ #endif
        for (n = 0; n < 32; ++n) {
-               printf("R%.2d = %.8lx%s", n, fp->gpr[n],
-                      (n & 3) == 3? "\n": "   ");
-               if (n == 12 && !FULL_REGS(fp)) {
-                       printf("\n");
-                       break;
-               }
+               printf("R%.2d = "REG"%s", n, fp->gpr[n],
+                       (n % R_PER_LINE) == R_PER_LINE - 1 ? "\n" : "   ");
        }
- #endif
        printf("pc  = ");
        xmon_print_symbol(fp->nip, " ", "\n");
        if (!trap_is_syscall(fp) && cpu_has_feature(CPU_FTR_CFAR)) {
        printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
               fp->ctr, fp->xer, fp->trap);
        trap = TRAP(fp);
-       if (trap == 0x300 || trap == 0x380 || trap == 0x600)
+       if (trap == INTERRUPT_DATA_STORAGE ||
+           trap == INTERRUPT_DATA_SEGMENT ||
+           trap == INTERRUPT_ALIGNMENT)
                printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
  }
  
@@@ -2727,30 -2724,6 +2724,6 @@@ static void dump_all_xives(void
                dump_one_xive(cpu);
  }
  
- static void dump_one_xive_irq(u32 num, struct irq_data *d)
- {
-       xmon_xive_get_irq_config(num, d);
- }
- static void dump_all_xive_irq(void)
- {
-       unsigned int i;
-       struct irq_desc *desc;
-       for_each_irq_desc(i, desc) {
-               struct irq_data *d = irq_desc_get_irq_data(desc);
-               unsigned int hwirq;
-               if (!d)
-                       continue;
-               hwirq = (unsigned int)irqd_to_hwirq(d);
-               /* IPIs are special (HW number 0) */
-               if (hwirq)
-                       dump_one_xive_irq(hwirq, d);
-       }
- }
  static void dump_xives(void)
  {
        unsigned long num;
                return;
        } else if (c == 'i') {
                if (scanhex(&num))
-                       dump_one_xive_irq(num, NULL);
+                       xmon_xive_get_irq_config(num, NULL);
                else
-                       dump_all_xive_irq();
+                       xmon_xive_get_irq_all();
                return;
        }
  
@@@ -2980,7 -2953,7 +2953,7 @@@ generic_inst_dump(unsigned long adr, lo
                if (!ppc_inst_prefixed(inst))
                        dump_func(ppc_inst_val(inst), adr);
                else
-                       dump_func(ppc_inst_as_u64(inst), adr);
+                       dump_func(ppc_inst_as_ulong(inst), adr);
                printf("\n");
        }
        return adr - first_adr;
@@@ -3001,7 -2974,7 +2974,7 @@@ print_address(unsigned long addr
  static void
  dump_log_buf(void)
  {
 -      struct kmsg_dumper dumper = { .active = 1 };
 +      struct kmsg_dump_iter iter;
        unsigned char buf[128];
        size_t len;
  
        catch_memory_errors = 1;
        sync();
  
 -      kmsg_dump_rewind_nolock(&dumper);
 +      kmsg_dump_rewind(&iter);
        xmon_start_pagination();
 -      while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
 +      while (kmsg_dump_get_line(&iter, false, buf, sizeof(buf), &len)) {
                buf[len] = '\0';
                printf("%s", buf);
        }
@@@ -4212,8 -4185,7 +4185,7 @@@ static void dump_spu_fields(struct spu 
        DUMP_FIELD(spu, "0x%p", pdata);
  }
  
- int
- spu_inst_dump(unsigned long adr, long count, int praddr)
+ static int spu_inst_dump(unsigned long adr, long count, int praddr)
  {
        return generic_inst_dump(adr, count, praddr, print_insn_spu);
  }
@@@ -369,7 -369,7 +369,7 @@@ comment "I2C system bus drivers (mostl
  
  config I2C_ALTERA
        tristate "Altera Soft IP I2C"
 -      depends on ARCH_SOCFPGA || NIOS2 || COMPILE_TEST
 +      depends on ARCH_INTEL_SOCFPGA || NIOS2 || COMPILE_TEST
        depends on OF
        help
          If you say yes to this option, support will be included for the
@@@ -776,7 -776,7 +776,7 @@@ config I2C_MT762
  
  config I2C_MV64XXX
        tristate "Marvell mv64xxx I2C Controller"
-       depends on MV64X60 || PLAT_ORION || ARCH_SUNXI || ARCH_MVEBU || COMPILE_TEST
+       depends on PLAT_ORION || ARCH_SUNXI || ARCH_MVEBU || COMPILE_TEST
        help
          If you say yes to this option, support will be included for the
          built-in I2C interface on the Marvell 64xxx line of host bridges.
diff --combined include/linux/compat.h
@@@ -236,8 -236,6 +236,8 @@@ typedef struct compat_siginfo 
                                        char _dummy_pkey[__COMPAT_ADDR_BND_PKEY_PAD];
                                        u32 _pkey;
                                } _addr_pkey;
 +                              /* used when si_code=TRAP_PERF */
 +                              compat_ulong_t _perf;
                        };
                } _sigfault;
  
@@@ -467,6 -465,34 +467,34 @@@ put_compat_sigset(compat_sigset_t __use
                unsafe_put_user(__s->sig[0], &__c->sig[0], label);      \
        }                                                               \
  } while (0)
+ #define unsafe_get_compat_sigset(set, compat, label) do {             \
+       const compat_sigset_t __user *__c = compat;                     \
+       compat_sigset_word hi, lo;                                      \
+       sigset_t *__s = set;                                            \
+                                                                       \
+       switch (_NSIG_WORDS) {                                          \
+       case 4:                                                         \
+               unsafe_get_user(lo, &__c->sig[7], label);               \
+               unsafe_get_user(hi, &__c->sig[6], label);               \
+               __s->sig[3] = hi | (((long)lo) << 32);                  \
+               fallthrough;                                            \
+       case 3:                                                         \
+               unsafe_get_user(lo, &__c->sig[5], label);               \
+               unsafe_get_user(hi, &__c->sig[4], label);               \
+               __s->sig[2] = hi | (((long)lo) << 32);                  \
+               fallthrough;                                            \
+       case 2:                                                         \
+               unsafe_get_user(lo, &__c->sig[3], label);               \
+               unsafe_get_user(hi, &__c->sig[2], label);               \
+               __s->sig[1] = hi | (((long)lo) << 32);                  \
+               fallthrough;                                            \
+       case 1:                                                         \
+               unsafe_get_user(lo, &__c->sig[1], label);               \
+               unsafe_get_user(hi, &__c->sig[0], label);               \
+               __s->sig[0] = hi | (((long)lo) << 32);                  \
+       }                                                               \
+ } while (0)
  #else
  #define unsafe_put_compat_sigset(compat, set, label) do {             \
        compat_sigset_t __user *__c = compat;                           \
                                                                        \
        unsafe_copy_to_user(__c, __s, sizeof(*__c), label);             \
  } while (0)
+ #define unsafe_get_compat_sigset(set, compat, label) do {             \
+       const compat_sigset_t __user *__c = compat;                     \
+       sigset_t *__s = set;                                            \
+                                                                       \
+       unsafe_copy_from_user(__s, __c, sizeof(*__c), label);           \
+ } while (0)
  #endif
  
  extern int compat_ptrace_request(struct task_struct *child,