diff options
| author | Will Deacon <will.deacon@arm.com> | 2013-05-10 13:07:19 -0400 |
|---|---|---|
| committer | Will Deacon <will.deacon@arm.com> | 2013-08-12 07:25:44 -0400 |
| commit | 3ea128065ed20d33bd02ff6dab689f88e38000be (patch) | |
| tree | c32b9ec35578f84705af2339941f41ecdfd4d4e0 | |
| parent | 2c813980c6113ac2c407fbed99f53242088c3038 (diff) | |
ARM: barrier: allow options to be passed to memory barrier instructions
On ARMv7, the memory barrier instructions take an optional `option'
field which can be used to constrain the effects of a memory barrier
based on shareability and access type.
This patch allows the caller to pass these options if required, and
updates the smp_*() barriers to request inner-shareable barriers,
affecting only stores for the _wmb variant. wmb() is also changed to
use the -st version of dsb.
Reported-by: Albin Tonnerre <albin.tonnerre@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
| -rw-r--r-- | arch/arm/include/asm/assembler.h | 4 | ||||
| -rw-r--r-- | arch/arm/include/asm/barrier.h | 32 |
2 files changed, 18 insertions, 18 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index a5fef710af32..fcc1b5bf6979 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
| @@ -220,9 +220,9 @@ | |||
| 220 | #ifdef CONFIG_SMP | 220 | #ifdef CONFIG_SMP |
| 221 | #if __LINUX_ARM_ARCH__ >= 7 | 221 | #if __LINUX_ARM_ARCH__ >= 7 |
| 222 | .ifeqs "\mode","arm" | 222 | .ifeqs "\mode","arm" |
| 223 | ALT_SMP(dmb) | 223 | ALT_SMP(dmb ish) |
| 224 | .else | 224 | .else |
| 225 | ALT_SMP(W(dmb)) | 225 | ALT_SMP(W(dmb) ish) |
| 226 | .endif | 226 | .endif |
| 227 | #elif __LINUX_ARM_ARCH__ == 6 | 227 | #elif __LINUX_ARM_ARCH__ == 6 |
| 228 | ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb | 228 | ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb |
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h index 8dcd9c702d90..60f15e274e6d 100644 --- a/arch/arm/include/asm/barrier.h +++ b/arch/arm/include/asm/barrier.h | |||
| @@ -14,27 +14,27 @@ | |||
| 14 | #endif | 14 | #endif |
| 15 | 15 | ||
| 16 | #if __LINUX_ARM_ARCH__ >= 7 | 16 | #if __LINUX_ARM_ARCH__ >= 7 |
| 17 | #define isb() __asm__ __volatile__ ("isb" : : : "memory") | 17 | #define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory") |
| 18 | #define dsb() __asm__ __volatile__ ("dsb" : : : "memory") | 18 | #define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory") |
| 19 | #define dmb() __asm__ __volatile__ ("dmb" : : : "memory") | 19 | #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory") |
| 20 | #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 | 20 | #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 |
| 21 | #define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ | 21 | #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ |
| 22 | : : "r" (0) : "memory") | 22 | : : "r" (0) : "memory") |
| 23 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | 23 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ |
| 24 | : : "r" (0) : "memory") | 24 | : : "r" (0) : "memory") |
| 25 | #define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ | 25 | #define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ |
| 26 | : : "r" (0) : "memory") | 26 | : : "r" (0) : "memory") |
| 27 | #elif defined(CONFIG_CPU_FA526) | 27 | #elif defined(CONFIG_CPU_FA526) |
| 28 | #define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ | 28 | #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ |
| 29 | : : "r" (0) : "memory") | 29 | : : "r" (0) : "memory") |
| 30 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | 30 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ |
| 31 | : : "r" (0) : "memory") | 31 | : : "r" (0) : "memory") |
| 32 | #define dmb() __asm__ __volatile__ ("" : : : "memory") | 32 | #define dmb(x) __asm__ __volatile__ ("" : : : "memory") |
| 33 | #else | 33 | #else |
| 34 | #define isb() __asm__ __volatile__ ("" : : : "memory") | 34 | #define isb(x) __asm__ __volatile__ ("" : : : "memory") |
| 35 | #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ | 35 | #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ |
| 36 | : : "r" (0) : "memory") | 36 | : : "r" (0) : "memory") |
| 37 | #define dmb() __asm__ __volatile__ ("" : : : "memory") | 37 | #define dmb(x) __asm__ __volatile__ ("" : : : "memory") |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | #ifdef CONFIG_ARCH_HAS_BARRIERS | 40 | #ifdef CONFIG_ARCH_HAS_BARRIERS |
| @@ -42,7 +42,7 @@ | |||
| 42 | #elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) | 42 | #elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) |
| 43 | #define mb() do { dsb(); outer_sync(); } while (0) | 43 | #define mb() do { dsb(); outer_sync(); } while (0) |
| 44 | #define rmb() dsb() | 44 | #define rmb() dsb() |
| 45 | #define wmb() mb() | 45 | #define wmb() do { dsb(st); outer_sync(); } while (0) |
| 46 | #else | 46 | #else |
| 47 | #define mb() barrier() | 47 | #define mb() barrier() |
| 48 | #define rmb() barrier() | 48 | #define rmb() barrier() |
| @@ -54,9 +54,9 @@ | |||
| 54 | #define smp_rmb() barrier() | 54 | #define smp_rmb() barrier() |
| 55 | #define smp_wmb() barrier() | 55 | #define smp_wmb() barrier() |
| 56 | #else | 56 | #else |
| 57 | #define smp_mb() dmb() | 57 | #define smp_mb() dmb(ish) |
| 58 | #define smp_rmb() dmb() | 58 | #define smp_rmb() smp_mb() |
| 59 | #define smp_wmb() dmb() | 59 | #define smp_wmb() dmb(ishst) |
| 60 | #endif | 60 | #endif |
| 61 | 61 | ||
| 62 | #define read_barrier_depends() do { } while(0) | 62 | #define read_barrier_depends() do { } while(0) |
