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

Nick Desaulniers ndesaulniers at google.com
Mon Jan 31 10:40:31 PST 2022


On Mon, Jan 31, 2022 at 9:04 AM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> 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>

Thanks for the patch!
Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>

> ---
>  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
>


-- 
Thanks,
~Nick Desaulniers



More information about the linux-arm-kernel mailing list