aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/include/asm/assembler.h22
-rw-r--r--arch/arm/kernel/entry-armv.S4
-rw-r--r--arch/arm/kernel/head.S13
4 files changed, 32 insertions, 9 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db524e75c4a2..290a4b57617f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1229,7 +1229,7 @@ config SMP
1229config SMP_ON_UP 1229config SMP_ON_UP
1230 bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)" 1230 bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
1231 depends on EXPERIMENTAL 1231 depends on EXPERIMENTAL
1232 depends on SMP && !XIP && !THUMB2_KERNEL 1232 depends on SMP && !XIP
1233 default y 1233 default y
1234 help 1234 help
1235 SMP kernels contain instructions which fail on non-SMP processors. 1235 SMP kernels contain instructions which fail on non-SMP processors.
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 749bb6622404..72d3389e9c12 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -157,16 +157,24 @@
157#ifdef CONFIG_SMP 157#ifdef CONFIG_SMP
158#define ALT_SMP(instr...) \ 158#define ALT_SMP(instr...) \
1599998: instr 1599998: instr
160/*
161 * Note: if you get assembler errors from ALT_UP() when building with
162 * CONFIG_THUMB2_KERNEL, you almost certainly need to use
163 * ALT_SMP( W(instr) ... )
164 */
160#define ALT_UP(instr...) \ 165#define ALT_UP(instr...) \
161 .pushsection ".alt.smp.init", "a" ;\ 166 .pushsection ".alt.smp.init", "a" ;\
162 .long 9998b ;\ 167 .long 9998b ;\
163 instr ;\ 1689997: instr ;\
169 .if . - 9997b != 4 ;\
170 .error "ALT_UP() content must assemble to exactly 4 bytes";\
171 .endif ;\
164 .popsection 172 .popsection
165#define ALT_UP_B(label) \ 173#define ALT_UP_B(label) \
166 .equ up_b_offset, label - 9998b ;\ 174 .equ up_b_offset, label - 9998b ;\
167 .pushsection ".alt.smp.init", "a" ;\ 175 .pushsection ".alt.smp.init", "a" ;\
168 .long 9998b ;\ 176 .long 9998b ;\
169 b . + up_b_offset ;\ 177 W(b) . + up_b_offset ;\
170 .popsection 178 .popsection
171#else 179#else
172#define ALT_SMP(instr...) 180#define ALT_SMP(instr...)
@@ -177,16 +185,24 @@
177/* 185/*
178 * SMP data memory barrier 186 * SMP data memory barrier
179 */ 187 */
180 .macro smp_dmb 188 .macro smp_dmb mode
181#ifdef CONFIG_SMP 189#ifdef CONFIG_SMP
182#if __LINUX_ARM_ARCH__ >= 7 190#if __LINUX_ARM_ARCH__ >= 7
191 .ifeqs "\mode","arm"
183 ALT_SMP(dmb) 192 ALT_SMP(dmb)
193 .else
194 ALT_SMP(W(dmb))
195 .endif
184#elif __LINUX_ARM_ARCH__ == 6 196#elif __LINUX_ARM_ARCH__ == 6
185 ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb 197 ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
186#else 198#else
187#error Incompatible SMP platform 199#error Incompatible SMP platform
188#endif 200#endif
201 .ifeqs "\mode","arm"
189 ALT_UP(nop) 202 ALT_UP(nop)
203 .else
204 ALT_UP(W(nop))
205 .endif
190#endif 206#endif
191 .endm 207 .endm
192 208
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 955cf5f539ed..7f22a11a5105 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -842,7 +842,7 @@ __kuser_helper_start:
842 */ 842 */
843 843
844__kuser_memory_barrier: @ 0xffff0fa0 844__kuser_memory_barrier: @ 0xffff0fa0
845 smp_dmb 845 smp_dmb arm
846 usr_ret lr 846 usr_ret lr
847 847
848 .align 5 848 .align 5
@@ -959,7 +959,7 @@ kuser_cmpxchg_fixup:
959 959
960#else 960#else
961 961
962 smp_dmb 962 smp_dmb arm
9631: ldrex r3, [r2] 9631: ldrex r3, [r2]
964 subs r3, r3, r0 964 subs r3, r3, r0
965 strexeq r3, r1, [r2] 965 strexeq r3, r1, [r2]
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index fd94e4e82fc9..359e54e83bd5 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -412,10 +412,17 @@ __fixup_smp_on_up:
412 add r4, r4, r3 412 add r4, r4, r3
413 add r5, r5, r3 413 add r5, r5, r3
4142: cmp r4, r5 4142: cmp r4, r5
415 movhs pc, lr
415 ldmia r4!, {r0, r6} 416 ldmia r4!, {r0, r6}
416 strlo r6, [r0, r3] 417 ARM( str r6, [r0, r3] )
417 blo 2b 418 THUMB( add r0, r0, r3 )
418 mov pc, lr 419#ifdef __ARMEB__
420 THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian.
421#endif
422 THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords
423 THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3.
424 THUMB( strh r6, [r0] )
425 b 2b
419ENDPROC(__fixup_smp) 426ENDPROC(__fixup_smp)
420 427
4211: .word . 4281: .word .