ARM: 6655/1: Correct WFE() in asm/spinlock.h for Thumb-2
authorDave Martin <dave.martin@linaro.org>
Wed, 9 Feb 2011 11:06:59 +0000 (12:06 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 10 Feb 2011 15:30:51 +0000 (15:30 +0000)
The content for ALT_SMP() in the definition of WFE() expands to 6
bytes (IT cc ; WFEcc.W), which breaks the assumptions of the fixup
code, leading to lockups when the affected code gets run.

This patch works around the problem by explicitly using an
IT + WFEcc.N pair.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/spinlock.h

index da1af524015902ecc5d7446093da5137809f807b..fdd3820edff86ed900147d00436df2b6c2afd08f 100644 (file)
 
 #ifdef CONFIG_THUMB2_KERNEL
 #define SEV            ALT_SMP("sev.w", "nop.w")
-#define WFE(cond)      ALT_SMP("wfe" cond ".w", "nop.w")
+/*
+ * For Thumb-2, special care is needed to ensure that the conditional WFE
+ * instruction really does assemble to exactly 4 bytes (as required by
+ * the SMP_ON_UP fixup code).   By itself "wfene" might cause the
+ * assembler to insert a extra (16-bit) IT instruction, depending on the
+ * presence or absence of neighbouring conditional instructions.
+ *
+ * To avoid this unpredictableness, an approprite IT is inserted explicitly:
+ * the assembler won't change IT instructions which are explicitly present
+ * in the input.
+ */
+#define WFE(cond)      ALT_SMP(                \
+       "it " cond "\n\t"                       \
+       "wfe" cond ".n",                        \
+                                               \
+       "nop.w"                                 \
+)
 #else
 #define SEV            ALT_SMP("sev", "nop")
 #define WFE(cond)      ALT_SMP("wfe" cond, "nop")