[PATCH v2 11/12] ARM: cacheflush: avoid clobbering the frame pointer in Thumb2 mode

Ard Biesheuvel ardb at kernel.org
Mon Jan 31 09:03:46 PST 2022


Thumb2 uses R7 rather than R11 as the frame pointer, and even if we
rarely use a frame pointer to begin with when building in Thumb2 mode,
there are cases where it is required by the compiler (Clang when
inserting profiling hooks via -pg)

So let's preserve whichever register is considered the frame pointer
depending on whether we are building for ARM or Thumb2, rather than
preserving/restoring R11 explicitly.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/cacheflush.h  | 7 ++++---
 arch/arm/mach-exynos/mcpm-exynos.c | 7 ++++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index e68fb879e4f9..5c4c49086ac6 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -12,6 +12,7 @@
 #include <asm/glue-cache.h>
 #include <asm/shmparam.h>
 #include <asm/cachetype.h>
+#include <asm/opcodes.h>
 #include <asm/outercache.h>
 
 #define CACHE_COLOUR(vaddr)	((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
@@ -454,7 +455,7 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
 #define v7_exit_coherency_flush(level) \
 	asm volatile( \
 	".arch	armv7-a \n\t" \
-	"stmfd	sp!, {fp, ip} \n\t" \
+	"stmfd	sp!, {" FPREG_PRESERVE ", ip} \n\t" \
 	"mrc	p15, 0, r0, c1, c0, 0	@ get SCTLR \n\t" \
 	"bic	r0, r0, #"__stringify(CR_C)" \n\t" \
 	"mcr	p15, 0, r0, c1, c0, 0	@ set SCTLR \n\t" \
@@ -465,8 +466,8 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size)
 	"mcr	p15, 0, r0, c1, c0, 1	@ set ACTLR \n\t" \
 	"isb	\n\t" \
 	"dsb	\n\t" \
-	"ldmfd	sp!, {fp, ip}" \
-	: : : "r0","r1","r2","r3","r4","r5","r6","r7", \
+	"ldmfd	sp!, {" FPREG_PRESERVE ", ip}" \
+	: : : "r0","r1","r2","r3","r4","r5","r6", FPREG_CLOBBER, \
 	      "r9","r10","lr","memory" )
 
 void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index cd861c57d5ad..0cebc008d877 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -14,6 +14,7 @@
 #include <asm/cputype.h>
 #include <asm/cp15.h>
 #include <asm/mcpm.h>
+#include <asm/opcodes.h>
 #include <asm/smp_plat.h>
 
 #include "common.h"
@@ -35,7 +36,7 @@ static bool secure_firmware __ro_after_init;
  */
 #define exynos_v7_exit_coherency_flush(level) \
 	asm volatile( \
-	"stmfd	sp!, {fp, ip}\n\t"\
+	"stmfd	sp!, {" FPREG_PRESERVE ", ip} \n\t" \
 	"mrc	p15, 0, r0, c1, c0, 0	@ get SCTLR\n\t" \
 	"bic	r0, r0, #"__stringify(CR_C)"\n\t" \
 	"mcr	p15, 0, r0, c1, c0, 0	@ set SCTLR\n\t" \
@@ -50,10 +51,10 @@ static bool secure_firmware __ro_after_init;
 	"mcr	p15, 0, r0, c1, c0, 1	@ set ACTLR\n\t" \
 	"isb\n\t" \
 	"dsb\n\t" \
-	"ldmfd	sp!, {fp, ip}" \
+	"ldmfd	sp!, {" FPREG_PRESERVE ", ip}" \
 	: \
 	: "Ir" (pmu_base_addr + S5P_INFORM0) \
-	: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+	: "r0", "r1", "r2", "r3", "r4", "r5", "r6", FPREG_CLOBBER, \
 	  "r9", "r10", "lr", "memory")
 
 static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
-- 
2.30.2




More information about the linux-arm-kernel mailing list