[PATCH 2/3] arm: smh: Make semihosting trap calls more robust

Andre Przywara andre.przywara at arm.com
Wed Oct 5 18:38:48 CEST 2022


Commit f4b540e25c5c("arm: smh: Fix uninitialized parameters with newer
GCCs") added a memory clobber to the semihosting inline assembly trap
calls, to avoid too eager GCC optimisation: when passing a pointer, newer
compilers couldn't be bothered to actually fill in the structure that it
pointed to, as this data would seemingly never be used (at least from the
compiler's point of view).
But instead of the memory clobber we need to tell the compiler that we are
passing an *array* instead of some generic pointer, this forces the
compiler to actually populate the data structure.
This involves some rather hideous cast, which is best hidden in a macro.

But regardless of that, we actually need the memory clobber, but for two
different reasons: explain them in comments.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm/lib/semihosting.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c
index acc6b1be4f3..3dee7d51b36 100644
--- a/arch/arm/lib/semihosting.c
+++ b/arch/arm/lib/semihosting.c
@@ -20,6 +20,12 @@
 #define SYSFLEN		0x0C
 #define SYSERRNO	0x13
 
+/*
+ * Macro to force the compiler to *populate* memory (for an array or struct)
+ * before passing the pointer to an inline assembly call.
+ */
+#define USE_PTR(ptr) *(const char (*)[]) (ptr)
+
 #if defined(CONFIG_ARM64)
 	#define SMH_TRAP "hlt #0xf000"
 #elif defined(CONFIG_CPU_V7M)
@@ -37,9 +43,17 @@ static noinline long smh_trap(unsigned int sysnum, void *addr)
 {
 	register long result asm("r0");
 
+	/*
+	 * We need a memory clobber (aka compiler barrier) for two reasons:
+	 * - The compiler needs to populate any data structures pointed to
+	 *   by "addr" *before* the trap instruction is called.
+	 * - At least the SYSREAD function puts the result into memory pointed
+	 *   to by "addr", so the compiler must not use a cached version of
+	 *   the previous content, after the call has finished.
+	 */
 	asm volatile (SMH_TRAP
 		      : "=r" (result)
-		      : "0"(sysnum), "r"(addr)
+		      : "0"(sysnum), "r"(USE_PTR(addr))
 		      : "memory");
 
 	return result;
-- 
2.25.1



More information about the U-Boot mailing list