Merge branches 'fixes', 'misc' and 'spectre' into for-linus
authorRussell King <rmk+kernel@armlinux.org.uk>
Mon, 13 Aug 2018 15:28:50 +0000 (16:28 +0100)
committerRussell King <rmk+kernel@armlinux.org.uk>
Mon, 13 Aug 2018 15:28:50 +0000 (16:28 +0100)
Conflicts:
arch/arm/include/asm/uaccess.h

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
1  2  3 
arch/arm/include/asm/assembler.h
arch/arm/include/asm/uaccess.h
arch/arm/kernel/head-nommu.S
arch/arm/kernel/signal.c
arch/arm/kernel/sys_oabi-compat.c
arch/arm/vfp/vfpmodule.c

index 0cd4dccbae788626ddd277376d1dc78c719a9ff2,0cd4dccbae788626ddd277376d1dc78c719a9ff2,f0515f60cff51f11cceb937c10986788649ab446..b17ee03d280b6ff9ff706f04ab4d3be57f20bfe8
@@@@ -460,6 -460,6 -460,10 +460,10 @@@@ THUMB(  orr     \reg , \reg , #PSR_T_BIT        
        adds    \tmp, \addr, #\size - 1
        sbcccs  \tmp, \tmp, \limit
        bcs     \bad
++ #ifdef CONFIG_CPU_SPECTRE
++      movcs   \addr, #0
++      csdb
++ #endif
   #endif
        .endm
   
   #endif
        .endm
   
  +#ifdef CONFIG_KPROBES
  +#define _ASM_NOKPROBE(entry)                         \
  +     .pushsection "_kprobe_blacklist", "aw" ;        \
  +     .balign 4 ;                                     \
  +     .long entry;                                    \
  +     .popsection
  +#else
  +#define _ASM_NOKPROBE(entry)
  +#endif
  +
   #endif /* __ASM_ASSEMBLER_H__ */
index 3d614e90c19f307ac04b3e625c52b6bc80b66da7,3d614e90c19f307ac04b3e625c52b6bc80b66da7,4140be43108731ba89894bd20e1e6551e350f488..5451e1f05a193c002f3b30af921975a28c232833
@@@@ -84,6 -84,6 -84,13 +84,13 @@@@ static inline void set_fs(mm_segment_t 
                : "cc"); \
        flag; })
   
++ /*
++  * This is a type: either unsigned long, if the argument fits into
++  * that type, or otherwise unsigned long long.
++  */
++ #define __inttype(x) \
++      __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
++ 
   /*
    * Single-value transfer routines.  They automatically use the right
    * size if we just have the right pointer type.  Note that the functions
@@@@ -152,8 -152,8 -159,8 +159,8 @@@@ extern int __get_user_64t_4(void *)
   #define __get_user_check(x, p)                                               \
        ({                                                              \
                unsigned long __limit = current_thread_info()->addr_limit - 1; \
  -             register const typeof(*(p)) __user *__p asm("r0") = (p);\
  +             register typeof(*(p)) __user *__p asm("r0") = (p);      \
--              register typeof(x) __r2 asm("r2");                      \
++              register __inttype(x) __r2 asm("r2");                   \
                register unsigned long __l asm("r1") = __limit;         \
                register int __e asm("r0");                             \
                unsigned int __ua_flags = uaccess_save_and_enable();    \
@@@@ -243,6 -243,6 -250,16 +250,16 @@@@ static inline void set_fs(mm_segment_t 
   #define user_addr_max() \
        (uaccess_kernel() ? ~0UL : get_fs())
   
++ #ifdef CONFIG_CPU_SPECTRE
++ /*
++  * When mitigating Spectre variant 1, it is not worth fixing the non-
++  * verifying accessors, because we need to add verification of the
++  * address space there.  Force these to use the standard get_user()
++  * version instead.
++  */
++ #define __get_user(x, ptr) get_user(x, ptr)
++ #else
++ 
   /*
    * The "__xxx" versions of the user access functions do not verify the
    * address space - it must have been done previously with a separate
        __gu_err;                                                       \
   })
   
-- #define __get_user_error(x, ptr, err)                                        \
-- ({                                                                   \
--      __get_user_err((x), (ptr), err);                                \
--      (void) 0;                                                       \
-- })
-- 
   #define __get_user_err(x, ptr, err)                                  \
   do {                                                                 \
        unsigned long __gu_addr = (unsigned long)(ptr);                 \
   
   #define __get_user_asm_word(x, addr, err)                    \
        __get_user_asm(x, addr, err, ldr)
++ #endif
   
   
   #define __put_user_switch(x, ptr, __err, __fn)                               \
index 7a9b86978ee1e2b917d1104138d3aa468a88bb53,724734039492c753f61cf9430065ae18fd5b2b18,2e38f85b757afa377ee3571639c99d4ebbac04a8..ec29de2500764e11ad839bda165c135f12b6a6e5
@@@@ -53,7 -53,11 -53,7 +53,11 @@@@ ENTRY(stext
    THUMB(1:                    )
   #endif
   
- -     setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
+ +#ifdef CONFIG_ARM_VIRT_EXT
+ +     bl      __hyp_stub_install
+ +#endif
+ +     @ ensure svc mode and all interrupts masked
+ +     safe_svcmode_maskall r9
                                                @ and irqs disabled
   #if defined(CONFIG_CPU_CP15)
        mrc     p15, 0, r9, c0, c0              @ get processor id
        beq     __error_p                               @ yes, error 'p'
   
   #ifdef CONFIG_ARM_MPU
  -     /* Calculate the size of a region covering just the kernel */
  -     ldr     r5, =PLAT_PHYS_OFFSET           @ Region start: PHYS_OFFSET
  -     ldr     r6, =(_end)                     @ Cover whole kernel
  -     sub     r6, r6, r5                      @ Minimum size of region to map
  -     clz     r6, r6                          @ Region size must be 2^N...
  -     rsb     r6, r6, #31                     @ ...so round up region size
  -     lsl     r6, r6, #MPU_RSR_SZ             @ Put size in right field
  -     orr     r6, r6, #(1 << MPU_RSR_EN)      @ Set region enabled bit
        bl      __setup_mpu
   #endif
   
        ldr     r12, [r10, #PROCINFO_INITFUNC]
        add     r12, r12, r10
        ret     r12
  -1:   bl      __after_proc_init
  -     b       __mmap_switched
  +1:   ldr     lr, =__mmap_switched
  +     b       __after_proc_init
   ENDPROC(stext)
   
   #ifdef CONFIG_SMP
@@@@ -89,7 -93,11 -97,7 +93,11 @@@@ ENTRY(secondary_startup
         * the processor type - there is no need to check the machine type
         * as it has already been validated by the primary processor.
         */
- -     setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
+ +#ifdef CONFIG_ARM_VIRT_EXT
+ +     bl      __hyp_stub_install_secondary
+ +#endif
+ +     safe_svcmode_maskall r9
+ +
   #ifndef CONFIG_CPU_CP15
        ldr     r9, =CONFIG_PROCESSOR_ID
   #else
        ldr     r7, __secondary_data
   
   #ifdef CONFIG_ARM_MPU
  -     /* Use MPU region info supplied by __cpu_up */
  -     ldr     r6, [r7]                        @ get secondary_data.mpu_rgn_info
        bl      __secondary_setup_mpu           @ Initialize the MPU
   #endif
   
@@@@ -123,45 -131,45 -133,12 +131,45 @@@@ __secondary_data
   /*
    * Set the Control Register and Read the process ID.
    */
  +     .text
   __after_proc_init:
  +#ifdef CONFIG_ARM_MPU
  +M_CLASS(movw r12, #:lower16:BASEADDR_V7M_SCB)
  +M_CLASS(movt r12, #:upper16:BASEADDR_V7M_SCB)
  +M_CLASS(ldr  r3, [r12, 0x50])
  +AR_CLASS(mrc p15, 0, r3, c0, c1, 4)          @ Read ID_MMFR0
  +     and     r3, r3, #(MMFR0_PMSA)           @ PMSA field
  +     teq     r3, #(MMFR0_PMSAv7)             @ PMSA v7
  +     beq     1f
  +     teq     r3, #(MMFR0_PMSAv8)             @ PMSA v8
  +     /*
  +      * Memory region attributes for PMSAv8:
  +      *
  +      *   n = AttrIndx[2:0]
  +      *                      n       MAIR
  +      *   DEVICE_nGnRnE      000     00000000
  +      *   NORMAL             001     11111111
  +      */
  +     ldreq   r3, =PMSAv8_MAIR(0x00, PMSAv8_RGN_DEVICE_nGnRnE) | \
  +                  PMSAv8_MAIR(0xff, PMSAv8_RGN_NORMAL)
  +AR_CLASS(mcreq       p15, 0, r3, c10, c2, 0)         @ MAIR 0
  +M_CLASS(streq        r3, [r12, #PMSAv8_MAIR0])
  +     moveq   r3, #0
  +AR_CLASS(mcreq       p15, 0, r3, c10, c2, 1)         @ MAIR 1
  +M_CLASS(streq        r3, [r12, #PMSAv8_MAIR1])
  +
  +1:
  +#endif
   #ifdef CONFIG_CPU_CP15
        /*
         * CP15 system control register value returned in r0 from
         * the CPU init function.
         */
  +
  +#ifdef CONFIG_ARM_MPU
  +     biceq   r0, r0, #CR_BR                  @ Disable the 'default mem-map'
  +     orreq   r0, r0, #CR_M                   @ Set SCTRL.M (MPU on)
  +#endif
   #if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
        orr     r0, r0, #CR_A
   #else
        bic     r0, r0, #CR_I
   #endif
        mcr     p15, 0, r0, c1, c0, 0           @ write control reg
 -      isb
 ++     instr_sync
   #elif defined (CONFIG_CPU_V7M)
  +#ifdef CONFIG_ARM_MPU
  +     ldreq   r3, [r12, MPU_CTRL]
  +     biceq   r3, #MPU_CTRL_PRIVDEFENA
  +     orreq   r3, #MPU_CTRL_ENABLE
  +     streq   r3, [r12, MPU_CTRL]
  +     isb
  +#endif
        /* For V7M systems we want to modify the CCR similarly to the SCTLR */
   #ifdef CONFIG_CPU_DCACHE_DISABLE
        bic     r0, r0, #V7M_SCB_CCR_DC
   #ifdef CONFIG_CPU_ICACHE_DISABLE
        bic     r0, r0, #V7M_SCB_CCR_IC
   #endif
  -     movw    r3, #:lower16:(BASEADDR_V7M_SCB + V7M_SCB_CCR)
  -     movt    r3, #:upper16:(BASEADDR_V7M_SCB + V7M_SCB_CCR)
  -     str     r0, [r3]
  +     str     r0, [r12, V7M_SCB_CCR]
   #endif /* CONFIG_CPU_CP15 elif CONFIG_CPU_V7M */
        ret     lr
   ENDPROC(__after_proc_init)
   .endm
   
   /* Setup a single MPU region, either D or I side (D-side for unified) */
  -.macro setup_region bar, acr, sr, side = MPU_DATA_SIDE, unused
  +.macro setup_region bar, acr, sr, side = PMSAv7_DATA_SIDE, unused
        mcr     p15, 0, \bar, c6, c1, (0 + \side)       @ I/DRBAR
        mcr     p15, 0, \acr, c6, c1, (4 + \side)       @ I/DRACR
        mcr     p15, 0, \sr, c6, c1, (2 + \side)                @ I/DRSR
   #else
   .macro set_region_nr tmp, rgnr, base
        mov     \tmp, \rgnr
  -     str     \tmp, [\base, #MPU_RNR]
  +     str     \tmp, [\base, #PMSAv7_RNR]
   .endm
   
   .macro setup_region bar, acr, sr, unused, base
        lsl     \acr, \acr, #16
        orr     \acr, \acr, \sr
  -     str     \bar, [\base, #MPU_RBAR]
  -     str     \acr, [\base, #MPU_RASR]
  +     str     \bar, [\base, #PMSAv7_RBAR]
  +     str     \acr, [\base, #PMSAv7_RASR]
   .endm
   
   #endif
    * Region 2: Normal, Shared, cacheable for RAM. From PHYS_OFFSET, size from r6
    * Region 3: Normal, shared, inaccessible from PL0 to protect the vectors page
    *
  - * r6: Value to be written to DRSR (and IRSR if required) for MPU_RAM_REGION
  + * r6: Value to be written to DRSR (and IRSR if required) for PMSAv7_RAM_REGION
   */
  +     __HEAD
   
   ENTRY(__setup_mpu)
   
@@@@ -253,22 -261,22 -223,7 +261,22 @@@@ AR_CLASS(mrc   p15, 0, r0, c0, c1, 4)          @ 
   M_CLASS(ldr  r0, [r12, 0x50])
        and     r0, r0, #(MMFR0_PMSA)           @ PMSA field
        teq     r0, #(MMFR0_PMSAv7)             @ PMSA v7
  -     bxne    lr
  +     beq     __setup_pmsa_v7
  +     teq     r0, #(MMFR0_PMSAv8)             @ PMSA v8
  +     beq     __setup_pmsa_v8
  +
  +     ret     lr
  +ENDPROC(__setup_mpu)
  +
  +ENTRY(__setup_pmsa_v7)
  +     /* Calculate the size of a region covering just the kernel */
  +     ldr     r5, =PLAT_PHYS_OFFSET           @ Region start: PHYS_OFFSET
  +     ldr     r6, =(_end)                     @ Cover whole kernel
  +     sub     r6, r6, r5                      @ Minimum size of region to map
  +     clz     r6, r6                          @ Region size must be 2^N...
  +     rsb     r6, r6, #31                     @ ...so round up region size
  +     lsl     r6, r6, #PMSAv7_RSR_SZ          @ Put size in right field
  +     orr     r6, r6, #(1 << PMSAv7_RSR_EN)   @ Set region enabled bit
   
        /* Determine whether the D/I-side memory map is unified. We set the
         * flags here and continue to use them for the rest of this function */
@@@@ -279,189 -287,189 -234,77 +287,189 @@@@ M_CLASS(ldr    r0, [r12, #MPU_TYPE]
        tst     r0, #MPUIR_nU                   @ MPUIR_nU = 0 for unified
   
        /* Setup second region first to free up r6 */
  -     set_region_nr r0, #MPU_RAM_REGION, r12
  +     set_region_nr r0, #PMSAv7_RAM_REGION, r12
        isb
        /* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */
        ldr     r0, =PLAT_PHYS_OFFSET           @ RAM starts at PHYS_OFFSET
  -     ldr     r5,=(MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL)
  +     ldr     r5,=(PMSAv7_AP_PL1RW_PL0RW | PMSAv7_RGN_NORMAL)
   
  -     setup_region r0, r5, r6, MPU_DATA_SIDE, r12     @ PHYS_OFFSET, shared, enabled
  +     setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12  @ PHYS_OFFSET, shared, enabled
        beq     1f                                      @ Memory-map not unified
  -     setup_region r0, r5, r6, MPU_INSTR_SIDE, r12    @ PHYS_OFFSET, shared, enabled
  +     setup_region r0, r5, r6, PMSAv7_INSTR_SIDE, r12 @ PHYS_OFFSET, shared, enabled
   1:   isb
   
        /* First/background region */
  -     set_region_nr r0, #MPU_BG_REGION, r12
  +     set_region_nr r0, #PMSAv7_BG_REGION, r12
        isb
        /* Execute Never,  strongly ordered, inaccessible to PL0, rw PL1  */
        mov     r0, #0                          @ BG region starts at 0x0
  -     ldr     r5,=(MPU_ACR_XN | MPU_RGN_STRONGLY_ORDERED | MPU_AP_PL1RW_PL0NA)
  -     mov     r6, #MPU_RSR_ALL_MEM            @ 4GB region, enabled
  +     ldr     r5,=(PMSAv7_ACR_XN | PMSAv7_RGN_STRONGLY_ORDERED | PMSAv7_AP_PL1RW_PL0NA)
  +     mov     r6, #PMSAv7_RSR_ALL_MEM         @ 4GB region, enabled
   
  -     setup_region r0, r5, r6, MPU_DATA_SIDE, r12     @ 0x0, BG region, enabled
  +     setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12  @ 0x0, BG region, enabled
        beq     2f                                      @ Memory-map not unified
  -     setup_region r0, r5, r6, MPU_INSTR_SIDE r12     @ 0x0, BG region, enabled
  +     setup_region r0, r5, r6, PMSAv7_INSTR_SIDE r12  @ 0x0, BG region, enabled
   2:   isb
   
   #ifdef CONFIG_XIP_KERNEL
  -     set_region_nr r0, #MPU_ROM_REGION, r12
  +     set_region_nr r0, #PMSAv7_ROM_REGION, r12
        isb
   
  -     ldr     r5,=(MPU_AP_PL1RO_PL0NA | MPU_RGN_NORMAL)
  +     ldr     r5,=(PMSAv7_AP_PL1RO_PL0NA | PMSAv7_RGN_NORMAL)
   
        ldr     r0, =CONFIG_XIP_PHYS_ADDR               @ ROM start
        ldr     r6, =(_exiprom)                         @ ROM end
        sub     r6, r6, r0                              @ Minimum size of region to map
        clz     r6, r6                                  @ Region size must be 2^N...
        rsb     r6, r6, #31                             @ ...so round up region size
  -     lsl     r6, r6, #MPU_RSR_SZ                     @ Put size in right field
  -     orr     r6, r6, #(1 << MPU_RSR_EN)              @ Set region enabled bit
  +     lsl     r6, r6, #PMSAv7_RSR_SZ                  @ Put size in right field
  +     orr     r6, r6, #(1 << PMSAv7_RSR_EN)           @ Set region enabled bit
   
  -     setup_region r0, r5, r6, MPU_DATA_SIDE, r12     @ XIP_PHYS_ADDR, shared, enabled
  +     setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12  @ XIP_PHYS_ADDR, shared, enabled
        beq     3f                                      @ Memory-map not unified
  -     setup_region r0, r5, r6, MPU_INSTR_SIDE, r12    @ XIP_PHYS_ADDR, shared, enabled
  +     setup_region r0, r5, r6, PMSAv7_INSTR_SIDE, r12 @ XIP_PHYS_ADDR, shared, enabled
   3:   isb
  +#endif
  +     ret     lr
  +ENDPROC(__setup_pmsa_v7)
  +
  +ENTRY(__setup_pmsa_v8)
  +     mov     r0, #0
  +AR_CLASS(mcr p15, 0, r0, c6, c2, 1)          @ PRSEL
  +M_CLASS(str  r0, [r12, #PMSAv8_RNR])
  +     isb
  +
  +#ifdef CONFIG_XIP_KERNEL
  +     ldr     r5, =CONFIG_XIP_PHYS_ADDR               @ ROM start
  +     ldr     r6, =(_exiprom)                         @ ROM end
  +     sub     r6, r6, #1
  +     bic     r6, r6, #(PMSAv8_MINALIGN - 1)
  +
  +     orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED)
  +     orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_NORMAL) | PMSAv8_LAR_EN)
  +
  +AR_CLASS(mcr p15, 0, r5, c6, c8, 0)                  @ PRBAR0
  +AR_CLASS(mcr p15, 0, r6, c6, c8, 1)                  @ PRLAR0
  +M_CLASS(str  r5, [r12, #PMSAv8_RBAR_A(0)])
  +M_CLASS(str  r6, [r12, #PMSAv8_RLAR_A(0)])
   #endif
   
  -     /* Enable the MPU */
  -AR_CLASS(mrc p15, 0, r0, c1, c0, 0)          @ Read SCTLR
  -AR_CLASS(bic r0, r0, #CR_BR)                 @ Disable the 'default mem-map'
  -AR_CLASS(orr r0, r0, #CR_M)                  @ Set SCTRL.M (MPU on)
  -AR_CLASS(mcr p15, 0, r0, c1, c0, 0)          @ Enable MPU
  +     ldr     r5, =KERNEL_START
  +     ldr     r6, =KERNEL_END
  +     sub     r6, r6, #1
  +     bic     r6, r6, #(PMSAv8_MINALIGN - 1)
   
  -M_CLASS(ldr  r0, [r12, #MPU_CTRL])
  -M_CLASS(bic  r0, #MPU_CTRL_PRIVDEFENA)
  -M_CLASS(orr  r0, #MPU_CTRL_ENABLE)
  -M_CLASS(str  r0, [r12, #MPU_CTRL])
  +     orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED)
  +     orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_NORMAL) | PMSAv8_LAR_EN)
  +
  +AR_CLASS(mcr p15, 0, r5, c6, c8, 4)                  @ PRBAR1
  +AR_CLASS(mcr p15, 0, r6, c6, c8, 5)                  @ PRLAR1
  +M_CLASS(str  r5, [r12, #PMSAv8_RBAR_A(1)])
  +M_CLASS(str  r6, [r12, #PMSAv8_RLAR_A(1)])
  +
  +     /* Setup Background: 0x0 - min(KERNEL_START, XIP_PHYS_ADDR) */
  +#ifdef CONFIG_XIP_KERNEL
  +     ldr     r6, =KERNEL_START
  +     ldr     r5, =CONFIG_XIP_PHYS_ADDR
  +     cmp     r6, r5
  +     movcs   r6, r5
  +#else
  +     ldr     r6, =KERNEL_START
  +#endif
  +     cmp     r6, #0
  +     beq     1f
  +
  +     mov     r5, #0
  +     sub     r6, r6, #1
  +     bic     r6, r6, #(PMSAv8_MINALIGN - 1)
  +
  +     orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN)
  +     orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN)
  +
  +AR_CLASS(mcr p15, 0, r5, c6, c9, 0)                  @ PRBAR2
  +AR_CLASS(mcr p15, 0, r6, c6, c9, 1)                  @ PRLAR2
  +M_CLASS(str  r5, [r12, #PMSAv8_RBAR_A(2)])
  +M_CLASS(str  r6, [r12, #PMSAv8_RLAR_A(2)])
  +
  +1:
  +     /* Setup Background: max(KERNEL_END, _exiprom) - 0xffffffff */
  +#ifdef CONFIG_XIP_KERNEL
  +     ldr     r5, =KERNEL_END
  +     ldr     r6, =(_exiprom)
  +     cmp     r5, r6
  +     movcc   r5, r6
  +#else
  +     ldr     r5, =KERNEL_END
  +#endif
  +     mov     r6, #0xffffffff
  +     bic     r6, r6, #(PMSAv8_MINALIGN - 1)
  +
  +     orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN)
  +     orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN)
  +
  +AR_CLASS(mcr p15, 0, r5, c6, c9, 4)                  @ PRBAR3
  +AR_CLASS(mcr p15, 0, r6, c6, c9, 5)                  @ PRLAR3
  +M_CLASS(str  r5, [r12, #PMSAv8_RBAR_A(3)])
  +M_CLASS(str  r6, [r12, #PMSAv8_RLAR_A(3)])
  +
  +#ifdef CONFIG_XIP_KERNEL
  +     /* Setup Background: min(_exiprom, KERNEL_END) - max(KERNEL_START, XIP_PHYS_ADDR) */
  +     ldr     r5, =(_exiprom)
  +     ldr     r6, =KERNEL_END
  +     cmp     r5, r6
  +     movcs   r5, r6
  +
  +     ldr     r6, =KERNEL_START
  +     ldr     r0, =CONFIG_XIP_PHYS_ADDR
  +     cmp     r6, r0
  +     movcc   r6, r0
  +
  +     sub     r6, r6, #1
  +     bic     r6, r6, #(PMSAv8_MINALIGN - 1)
  +
  +     orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN)
  +     orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN)
  +
  +#ifdef CONFIG_CPU_V7M
  +     /* There is no alias for n == 4 */
  +     mov     r0, #4
  +     str     r0, [r12, #PMSAv8_RNR]                  @ PRSEL
        isb
   
  +     str     r5, [r12, #PMSAv8_RBAR_A(0)]
  +     str     r6, [r12, #PMSAv8_RLAR_A(0)]
  +#else
  +     mcr     p15, 0, r5, c6, c10, 1                  @ PRBAR4
  +     mcr     p15, 0, r6, c6, c10, 2                  @ PRLAR4
  +#endif
  +#endif
        ret     lr
  -ENDPROC(__setup_mpu)
  +ENDPROC(__setup_pmsa_v8)
   
   #ifdef CONFIG_SMP
   /*
    * r6: pointer at mpu_rgn_info
    */
   
  +     .text
   ENTRY(__secondary_setup_mpu)
  +     /* Use MPU region info supplied by __cpu_up */
  +     ldr     r6, [r7]                        @ get secondary_data.mpu_rgn_info
  +
        /* Probe for v7 PMSA compliance */
        mrc     p15, 0, r0, c0, c1, 4           @ Read ID_MMFR0
        and     r0, r0, #(MMFR0_PMSA)           @ PMSA field
        teq     r0, #(MMFR0_PMSAv7)             @ PMSA v7
  -     bne     __error_p
  +     beq     __secondary_setup_pmsa_v7
  +     teq     r0, #(MMFR0_PMSAv8)             @ PMSA v8
  +     beq     __secondary_setup_pmsa_v8
  +     b       __error_p
  +ENDPROC(__secondary_setup_mpu)
   
  +/*
  + * r6: pointer at mpu_rgn_info
  + */
  +ENTRY(__secondary_setup_pmsa_v7)
        /* Determine whether the D/I-side memory map is unified. We set the
         * flags here and continue to use them for the rest of this function */
        mrc     p15, 0, r0, c0, c0, 4           @ MPUIR
        ldr     r6, [r3, #MPU_RGN_DRSR]
        ldr     r5, [r3, #MPU_RGN_DRACR]
   
  -     setup_region r0, r5, r6, MPU_DATA_SIDE
  +     setup_region r0, r5, r6, PMSAv7_DATA_SIDE
        beq     2f
  -     setup_region r0, r5, r6, MPU_INSTR_SIDE
  +     setup_region r0, r5, r6, PMSAv7_INSTR_SIDE
   2:   isb
   
        mrc     p15, 0, r0, c0, c0, 4           @ Reevaluate the MPUIR
        cmp     r4, #0
        bgt     1b
   
  -     /* Enable the MPU */
  -     mrc     p15, 0, r0, c1, c0, 0           @ Read SCTLR
  -     bic     r0, r0, #CR_BR                  @ Disable the 'default mem-map'
  -     orr     r0, r0, #CR_M                   @ Set SCTRL.M (MPU on)
  -     mcr     p15, 0, r0, c1, c0, 0           @ Enable MPU
  +     ret     lr
  +ENDPROC(__secondary_setup_pmsa_v7)
  +
  +ENTRY(__secondary_setup_pmsa_v8)
  +     ldr     r4, [r6, #MPU_RNG_INFO_USED]
  +#ifndef CONFIG_XIP_KERNEL
  +     add     r4, r4, #1
  +#endif
  +     mov     r5, #MPU_RNG_SIZE
  +     add     r3, r6, #MPU_RNG_INFO_RNGS
  +     mla     r3, r4, r5, r3
  +
  +1:
  +     sub     r3, r3, #MPU_RNG_SIZE
  +     sub     r4, r4, #1
  +
  +     mcr     p15, 0, r4, c6, c2, 1           @ PRSEL
        isb
   
  -     ret     lr
  -ENDPROC(__secondary_setup_mpu)
  +     ldr     r5, [r3, #MPU_RGN_PRBAR]
  +     ldr     r6, [r3, #MPU_RGN_PRLAR]
  +
  +     mcr     p15, 0, r5, c6, c3, 0           @ PRBAR
  +     mcr     p15, 0, r6, c6, c3, 1           @ PRLAR
  +
  +     cmp     r4, #0
  +     bgt     1b
   
  +     ret     lr
  +ENDPROC(__secondary_setup_pmsa_v8)
   #endif /* CONFIG_SMP */
   #endif /* CONFIG_ARM_MPU */
   #include "head-common.S"
diff --combined arch/arm/kernel/signal.c
index f09e9d66d605f4159990ad044cfd29486d621d20,f09e9d66d605f4159990ad044cfd29486d621d20,db62c51250ad2d80b6ae0246da6dce2d63314ce1..5cc5a4259d03ca16079c4ff29463267b553c2c92
@@@@ -150,22 -150,22 -150,18 +150,18 @@@@ static int preserve_vfp_context(struct 
   
   static int restore_vfp_context(char __user **auxp)
   {
--      struct vfp_sigframe __user *frame =
--              (struct vfp_sigframe __user *)*auxp;
--      unsigned long magic;
--      unsigned long size;
--      int err = 0;
-- 
--      __get_user_error(magic, &frame->magic, err);
--      __get_user_error(size, &frame->size, err);
++      struct vfp_sigframe frame;
++      int err;
   
++      err = __copy_from_user(&frame, *auxp, sizeof(frame));
        if (err)
--              return -EFAULT;
--      if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
++              return err;
++ 
++      if (frame.magic != VFP_MAGIC || frame.size != VFP_STORAGE_SIZE)
                return -EINVAL;
   
--      *auxp += size;
--      return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);
++      *auxp += sizeof(frame);
++      return vfp_restore_user_hwstate(&frame.ufp, &frame.ufp_exc);
   }
   
   #endif
   
   static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
   {
++      struct sigcontext context;
        char __user *aux;
        sigset_t set;
        int err;
        if (err == 0)
                set_current_blocked(&set);
   
--      __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
--      __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err);
--      __get_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err);
--      __get_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err);
--      __get_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err);
--      __get_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err);
--      __get_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err);
--      __get_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err);
--      __get_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err);
--      __get_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err);
--      __get_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err);
--      __get_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err);
--      __get_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err);
--      __get_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err);
--      __get_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err);
--      __get_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err);
--      __get_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err);
++      err |= __copy_from_user(&context, &sf->uc.uc_mcontext, sizeof(context));
++      if (err == 0) {
++              regs->ARM_r0 = context.arm_r0;
++              regs->ARM_r1 = context.arm_r1;
++              regs->ARM_r2 = context.arm_r2;
++              regs->ARM_r3 = context.arm_r3;
++              regs->ARM_r4 = context.arm_r4;
++              regs->ARM_r5 = context.arm_r5;
++              regs->ARM_r6 = context.arm_r6;
++              regs->ARM_r7 = context.arm_r7;
++              regs->ARM_r8 = context.arm_r8;
++              regs->ARM_r9 = context.arm_r9;
++              regs->ARM_r10 = context.arm_r10;
++              regs->ARM_fp = context.arm_fp;
++              regs->ARM_ip = context.arm_ip;
++              regs->ARM_sp = context.arm_sp;
++              regs->ARM_lr = context.arm_lr;
++              regs->ARM_pc = context.arm_pc;
++              regs->ARM_cpsr = context.arm_cpsr;
++      }
   
        err |= !valid_user_regs(regs);
   
@@@@ -540,12 -540,12 -540,6 +540,12 @@@@ static void handle_signal(struct ksigna
        sigset_t *oldset = sigmask_to_save();
        int ret;
   
  +     /*
  +      * Increment event counter and perform fixup for the pre-signal
  +      * frame.
  +      */
  +     rseq_signal_deliver(regs);
  +
        /*
         * Set up the stack frame
         */
@@@@ -666,7 -666,7 -660,6 +666,7 @@@@ do_work_pending(struct pt_regs *regs, u
                        } else {
                                clear_thread_flag(TIF_NOTIFY_RESUME);
                                tracehook_notify_resume(regs);
  +                             rseq_handle_notify_resume(regs);
                        }
                }
                local_irq_disable();
@@@@ -710,10 -710,10 -703,3 +710,10 @@@@ asmlinkage void addr_limit_check_failed
   {
        addr_limit_user_check();
   }
  +
  +#ifdef CONFIG_DEBUG_RSEQ
  +asmlinkage void do_rseq_syscall(struct pt_regs *regs)
  +{
  +     rseq_syscall(regs);
  +}
  +#endif
index 1df21a61e379e1a0fe66e784c7a1212814b100da,1df21a61e379e1a0fe66e784c7a1212814b100da,4abe4909417fd311c9e3b035248ecdcb69a4d0f1..f0dd4b6ebb6330e5007e883d2ba2d099a4e1df94
@@@@ -286,7 -286,7 -286,7 +286,7 @@@@ asmlinkage long sys_oabi_epoll_wait(in
                return -EINVAL;
        if (!access_ok(VERIFY_WRITE, events, sizeof(*events) * maxevents))
                return -EFAULT;
  -     kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
  +     kbuf = kmalloc_array(maxevents, sizeof(*kbuf), GFP_KERNEL);
        if (!kbuf)
                return -ENOMEM;
        fs = get_fs();
@@@@ -324,14 -324,14 -324,16 +324,16 @@@@ asmlinkage long sys_oabi_semtimedop(in
                return -EINVAL;
        if (!access_ok(VERIFY_READ, tsops, sizeof(*tsops) * nsops))
                return -EFAULT;
  -     sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
  +     sops = kmalloc_array(nsops, sizeof(*sops), GFP_KERNEL);
        if (!sops)
                return -ENOMEM;
        err = 0;
        for (i = 0; i < nsops; i++) {
--              __get_user_error(sops[i].sem_num, &tsops->sem_num, err);
--              __get_user_error(sops[i].sem_op,  &tsops->sem_op,  err);
--              __get_user_error(sops[i].sem_flg, &tsops->sem_flg, err);
++              struct oabi_sembuf osb;
++              err |= __copy_from_user(&osb, tsops, sizeof(osb));
++              sops[i].sem_num = osb.sem_num;
++              sops[i].sem_op = osb.sem_op;
++              sops[i].sem_flg = osb.sem_flg;
                tsops++;
        }
        if (timeout) {
diff --combined arch/arm/vfp/vfpmodule.c
index 35d0f823e8239f99f29596bc9805c9ab0bae467f,35d0f823e8239f99f29596bc9805c9ab0bae467f,859d50ea17d3d0a74e5b956cb67c23eb0ebbcde0..dc7e6b50ef674839a21480c69e12bec144d19194
@@@@ -218,7 -218,7 -218,8 +218,7 @@@@ static void vfp_raise_sigfpe(unsigned i
   {
        siginfo_t info;
   
  -     memset(&info, 0, sizeof(info));
  -
  +     clear_siginfo(&info);
        info.si_signo = SIGFPE;
        info.si_code = sicode;
        info.si_addr = (void __user *)(instruction_pointer(regs) - 4);
@@@@ -256,7 -256,7 -257,7 +256,7 @@@@ static void vfp_raise_exceptions(u32 ex
   
        if (exceptions == VFP_EXCEPTION_ERROR) {
                vfp_panic("unhandled bounce", inst);
  -             vfp_raise_sigfpe(FPE_FIXME, regs);
  +             vfp_raise_sigfpe(FPE_FLTINV, regs);
                return;
        }
   
@@@@ -596,13 -596,13 -597,11 +596,11 @@@@ int vfp_preserve_user_clear_hwstate(str
   }
   
   /* Sanitise and restore the current VFP state from the provided structures. */
-- int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
--                           struct user_vfp_exc __user *ufp_exc)
++ int vfp_restore_user_hwstate(struct user_vfp *ufp, struct user_vfp_exc *ufp_exc)
   {
        struct thread_info *thread = current_thread_info();
        struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
        unsigned long fpexc;
--      int err = 0;
   
        /* Disable VFP to avoid corrupting the new thread state. */
        vfp_flush_hwstate(thread);
         * Copy the floating point registers. There can be unused
         * registers see asm/hwcap.h for details.
         */
--      err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs,
--                              sizeof(hwstate->fpregs));
++      memcpy(&hwstate->fpregs, &ufp->fpregs, sizeof(hwstate->fpregs));
        /*
         * Copy the status and control register.
         */
--      __get_user_error(hwstate->fpscr, &ufp->fpscr, err);
++      hwstate->fpscr = ufp->fpscr;
   
        /*
         * Sanitise and restore the exception registers.
         */
--      __get_user_error(fpexc, &ufp_exc->fpexc, err);
++      fpexc = ufp_exc->fpexc;
   
        /* Ensure the VFP is enabled. */
        fpexc |= FPEXC_EN;
        fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
        hwstate->fpexc = fpexc;
   
--      __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
--      __get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err);
++      hwstate->fpinst = ufp_exc->fpinst;
++      hwstate->fpinst2 = ufp_exc->fpinst2;
   
--      return err ? -EFAULT : 0;
++      return 0;
   }
   
   /*