config SMP_ON_UP
        bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
        depends on EXPERIMENTAL
-       depends on SMP && !XIP && !THUMB2_KERNEL
+       depends on SMP && !XIP
        default y
        help
          SMP kernels contain instructions which fail on non-SMP processors.
 
 #ifdef CONFIG_SMP
 #define ALT_SMP(instr...)                                      \
 9998:  instr
+/*
+ * Note: if you get assembler errors from ALT_UP() when building with
+ * CONFIG_THUMB2_KERNEL, you almost certainly need to use
+ * ALT_SMP( W(instr) ... )
+ */
 #define ALT_UP(instr...)                                       \
        .pushsection ".alt.smp.init", "a"                       ;\
        .long   9998b                                           ;\
-       instr                                                   ;\
+9997:  instr                                                   ;\
+       .if . - 9997b != 4                                      ;\
+               .error "ALT_UP() content must assemble to exactly 4 bytes";\
+       .endif                                                  ;\
        .popsection
 #define ALT_UP_B(label)                                        \
        .equ    up_b_offset, label - 9998b                      ;\
        .pushsection ".alt.smp.init", "a"                       ;\
        .long   9998b                                           ;\
-       b       . + up_b_offset                                 ;\
+       W(b)    . + up_b_offset                                 ;\
        .popsection
 #else
 #define ALT_SMP(instr...)
 /*
  * SMP data memory barrier
  */
-       .macro  smp_dmb
+       .macro  smp_dmb mode
 #ifdef CONFIG_SMP
 #if __LINUX_ARM_ARCH__ >= 7
+       .ifeqs "\mode","arm"
        ALT_SMP(dmb)
+       .else
+       ALT_SMP(W(dmb))
+       .endif
 #elif __LINUX_ARM_ARCH__ == 6
        ALT_SMP(mcr     p15, 0, r0, c7, c10, 5) @ dmb
 #else
 #error Incompatible SMP platform
 #endif
+       .ifeqs "\mode","arm"
        ALT_UP(nop)
+       .else
+       ALT_UP(W(nop))
+       .endif
 #endif
        .endm
 
 
        add     r4, r4, r3
        add     r5, r5, r3
 2:     cmp     r4, r5
+       movhs   pc, lr
        ldmia   r4!, {r0, r6}
-       strlo   r6, [r0, r3]
-       blo     2b
-       mov     pc, lr
+ ARM(  str     r6, [r0, r3]    )
+ THUMB(        add     r0, r0, r3      )
+#ifdef __ARMEB__
+ THUMB(        mov     r6, r6, ror #16 )       @ Convert word order for big-endian.
+#endif
+ THUMB(        strh    r6, [r0], #2    )       @ For Thumb-2, store as two halfwords
+ THUMB(        mov     r6, r6, lsr #16 )       @ to be robust against misaligned r3.
+ THUMB(        strh    r6, [r0]        )
+       b       2b
 ENDPROC(__fixup_smp)
 
 1:     .word   .