From: Russell King Date: Fri, 22 Jul 2011 22:09:07 +0000 (+0100) Subject: Merge branch 'devel-stable' into for-next X-Git-Tag: firefly_0821_release~3680^2~4950^2 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3ad55155b222f2a901405dea20ff7c68828ecd92;p=firefly-linux-kernel-4.4.55.git Merge branch 'devel-stable' into for-next Conflicts: arch/arm/kernel/entry-armv.S --- 3ad55155b222f2a901405dea20ff7c68828ecd92 diff --cc arch/arm/kernel/entry-armv.S index fa02a22a4c4b,8f9ab5c9015b..a87cbf889ff4 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@@ -385,8 -391,8 +385,8 @@@ ENDPROC(__pabt_svc @ if it was interrupted in a critical region. Here we @ perform a quick test inline since it should be false @ 99.9999% of the time. The rest is done out of line. - cmp r2, #TASK_SIZE + cmp r4, #TASK_SIZE - blhs kuser_cmpxchg_fixup + blhs kuser_cmpxchg64_fixup #endif #endif .endm @@@ -742,40 -780,95 +723,95 @@@ ENDPROC(__switch_to __kuser_helper_start: /* - * Reference prototype: - * - * void __kernel_memory_barrier(void) - * - * Input: - * - * lr = return address - * - * Output: - * - * none - * - * Clobbered: - * - * none - * - * Definition and user space usage example: - * - * typedef void (__kernel_dmb_t)(void); - * #define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0) - * - * Apply any needed memory barrier to preserve consistency with data modified - * manually and __kuser_cmpxchg usage. - * - * This could be used as follows: - * - * #define __kernel_dmb() \ - * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ - * : : : "r0", "lr","cc" ) + * Due to the length of some sequences, __kuser_cmpxchg64 spans 2 regular + * kuser "slots", therefore 0xffff0f80 is not used as a valid entry point. */ - __kuser_memory_barrier: @ 0xffff0fa0 + __kuser_cmpxchg64: @ 0xffff0f60 + + #if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) + + /* + * Poor you. No fast solution possible... + * The kernel itself must perform the operation. + * A special ghost syscall is used for that (see traps.c). + */ + stmfd sp!, {r7, lr} + ldr r7, 1f @ it's 20 bits + swi __ARM_NR_cmpxchg64 + ldmfd sp!, {r7, pc} + 1: .word __ARM_NR_cmpxchg64 + + #elif defined(CONFIG_CPU_32v6K) + + stmfd sp!, {r4, r5, r6, r7} + ldrd r4, r5, [r0] @ load old val + ldrd r6, r7, [r1] @ load new val + smp_dmb arm + 1: ldrexd r0, r1, [r2] @ load current val + eors r3, r0, r4 @ compare with oldval (1) + eoreqs r3, r1, r5 @ compare with oldval (2) + strexdeq r3, r6, r7, [r2] @ store newval if eq + teqeq r3, #1 @ success? + beq 1b @ if no then retry smp_dmb arm + rsbs r0, r3, #0 @ set returned val and C flag + ldmfd sp!, {r4, r5, r6, r7} + bx lr + + #elif !defined(CONFIG_SMP) + + #ifdef CONFIG_MMU + + /* + * The only thing that can break atomicity in this cmpxchg64 + * implementation is either an IRQ or a data abort exception + * causing another process/thread to be scheduled in the middle of + * the critical sequence. The same strategy as for cmpxchg is used. + */ + stmfd sp!, {r4, r5, r6, lr} + ldmia r0, {r4, r5} @ load old val + ldmia r1, {r6, lr} @ load new val + 1: ldmia r2, {r0, r1} @ load current val + eors r3, r0, r4 @ compare with oldval (1) + eoreqs r3, r1, r5 @ compare with oldval (2) + 2: stmeqia r2, {r6, lr} @ store newval if eq + rsbs r0, r3, #0 @ set return val and C flag + ldmfd sp!, {r4, r5, r6, pc} + + .text + kuser_cmpxchg64_fixup: + @ Called from kuser_cmpxchg_fixup. - @ r2 = address of interrupted insn (must be preserved). ++ @ r4 = address of interrupted insn (must be preserved). + @ sp = saved regs. r7 and r8 are clobbered. + @ 1b = first critical insn, 2b = last critical insn. - @ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b. ++ @ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b. + mov r7, #0xffff0fff + sub r7, r7, #(0xffff0fff - (0xffff0f60 + (1b - __kuser_cmpxchg64))) - subs r8, r2, r7 ++ subs r8, r4, r7 + rsbcss r8, r8, #(2b - 1b) + strcs r7, [sp, #S_PC] + #if __LINUX_ARM_ARCH__ < 6 + bcc kuser_cmpxchg32_fixup + #endif + mov pc, lr + .previous + + #else + #warning "NPTL on non MMU needs fixing" + mov r0, #-1 + adds r0, r0, #0 usr_ret lr + #endif + + #else + #error "incoherent kernel configuration" + #endif + + /* pad to next slot */ + .rept (16 - (. - __kuser_cmpxchg64)/4) + .word 0 + .endr .align 5 @@@ -868,15 -913,15 +856,15 @@@ __kuser_cmpxchg: @ 0xffff0fc usr_ret lr .text - kuser_cmpxchg_fixup: + kuser_cmpxchg32_fixup: @ Called from kuser_cmpxchg_check macro. - @ r2 = address of interrupted insn (must be preserved). + @ r4 = address of interrupted insn (must be preserved). @ sp = saved regs. r7 and r8 are clobbered. @ 1b = first critical insn, 2b = last critical insn. - @ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b. + @ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b. mov r7, #0xffff0fff sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg))) - subs r8, r2, r7 + subs r8, r4, r7 rsbcss r8, r8, #(2b - 1b) strcs r7, [sp, #S_PC] mov pc, lr diff --cc arch/arm/kernel/setup.c index 9c3278f37796,f59653d67652..70bca649e925 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@@ -917,8 -915,15 +917,14 @@@ void __init setup_arch(char **cmdline_p #endif reserve_crashkernel(); - cpu_init(); tcm_init(); + #ifdef CONFIG_ZONE_DMA + if (mdesc->dma_zone_size) { + extern unsigned long arm_dma_zone_size; + arm_dma_zone_size = mdesc->dma_zone_size; + } + #endif #ifdef CONFIG_MULTI_IRQ_HANDLER handle_arch_irq = mdesc->handle_irq; #endif