refactor(cpufeat): use alternative encoding for "SB" barrier
The "sb" barrier instruction is a rather new addition to the AArch64
instruction set, so it is not recognised by all toolchains. On top of
that, the GNU assembler denies this instruction, unless a compatible
processor is selected:
asm_macros.S:223: Error: selected processor does not support `sb'
Provide an alternative encoding of the "sb" instruction, by using a
system register write, as this is the group where the barrier
instructions borrow their encoding space from.
This results in the exact same opcode to be generated, and any
disassembler will decode this instruction as "sb".
Change-Id: I5f44c8321e0cc04c784e02bd838e964602a96a8e
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 85546ec..58abd44 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1335,4 +1335,7 @@
#define CPUMPMMCR_EL3_MPMM_EN_SHIFT UINT64_C(0)
#define CPUMPMMCR_EL3_MPMM_EN_MASK UINT64_C(0x1)
+/* alternative system register encoding for the "sb" speculation barrier */
+#define SYSREG_SB S0_3_C3_C0_7
+
#endif /* ARCH_H */
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index 66c39e5..b4dab08 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -215,12 +215,24 @@
.endm
/*
+ * The "sb" instruction was introduced later into the architecture,
+ * so not all toolchains understand it. Some deny its usage unless
+ * a supported processor is specified on the build command line.
+ * Use sb's system register encoding to work around this, we already
+ * guard the sb execution with a feature flag.
+ */
+
+ .macro sb_barrier_insn
+ msr SYSREG_SB, xzr
+ .endm
+
+ /*
* Macro for using speculation barrier instruction introduced by
* FEAT_SB, if it's enabled.
*/
.macro speculation_barrier
#if ENABLE_FEAT_SB
- sb
+ sb_barrier_insn
#else
dsb sy
isb
@@ -234,7 +246,7 @@
.macro exception_return
eret
#if ENABLE_FEAT_SB
- sb
+ sb_barrier_insn
#else
dsb nsh
isb