From 7c612bfd4ed3064fd48a4877a114c8186547367b Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 19 Dec 2005 22:20:51 +0000 Subject: [PATCH] [ARM] 3210/1: add missing memory barrier helper for NPTL support Patch from Nicolas Pitre Strictly speaking, the NPTL kernel helpers are required for pre ARMv6 only. They are available on ARMv6+ as well for obvious compatibility reasons. However there are cases where extra memory barriers are needed when using an SMP ARMv6 machine but not on pre-ARMv6. This patch adds a memory barrier kernel helper that glibc can use as needed for pre-ARMv6 binaries to be forward compatible with an SMP kernel on ARMv6, as well as the necessary dmb instructions to the cmpxchg helper. Signed-off-by: Nicolas Pitre Acked-by: Daniel Jacobowitz Signed-off-by: Russell King --- arch/arm/kernel/entry-armv.S | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d9fb819bf7cc..2a8d27e18fa7 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -611,6 +611,47 @@ ENTRY(__switch_to) .globl __kuser_helper_start __kuser_helper_start: +/* + * Reference prototype: + * + * void __kernel_memory_barrier(void) + * + * Input: + * + * lr = return address + * + * Output: + * + * none + * + * Clobbered: + * + * the Z flag might be lost + * + * 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" \ + * : : : "lr","cc" ) + */ + +__kuser_memory_barrier: @ 0xffff0fa0 + +#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP) + mcr p15, 0, r0, c7, c10, 5 @ dmb +#endif + mov pc, lr + + .align 5 + /* * Reference prototype: * @@ -642,6 +683,8 @@ __kuser_helper_start: * The C flag is also set if *ptr was changed to allow for assembly * optimization in the calling code. * + * Note: this routine already includes memory barriers as needed. + * * For example, a user space atomic_add implementation could look like this: * * #define atomic_add(ptr, val) \ @@ -698,10 +741,16 @@ __kuser_cmpxchg: @ 0xffff0fc0 #else +#ifdef CONFIG_SMP + mcr p15, 0, r0, c7, c10, 5 @ dmb +#endif ldrex r3, [r2] subs r3, r3, r0 strexeq r3, r1, [r2] rsbs r0, r3, #0 +#ifdef CONFIG_SMP + mcr p15, 0, r0, c7, c10, 5 @ dmb +#endif mov pc, lr #endif -- 2.20.1