]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ARM: kprobes: treat R7 as the frame pointer register in Thumb2 builds
authorArd Biesheuvel <ardb@kernel.org>
Wed, 26 Jan 2022 10:27:21 +0000 (11:27 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Wed, 9 Feb 2022 08:13:59 +0000 (09:13 +0100)
Thumb2 code uses R7 as the frame pointer rather than R11, because the
opcodes to access it are generally shorter.

This means that there are cases where we cannot simply add it to the
clobber list of an asm() block, but need to preserve/restore it
explicitly, or the compiler may complain in some cases (e.g., Clang
builds with ftrace enabled).

Since R11 is not special in that case, clobber it instead, and use it to
preserve/restore the value of R7.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
arch/arm/probes/kprobes/actions-common.c
arch/arm/probes/kprobes/actions-thumb.c

index 836aebe596cd635cec83f73fd4ee603dd8ac6392..79171344dbeb487b374fbb0e3ad05775e733126c 100644 (file)
@@ -84,7 +84,8 @@ emulate_generic_r0_12_noflags(probes_opcode_t insn,
        register void *rfn asm("lr") = asi->insn_fn;
 
        __asm__ __volatile__ (
-               "stmdb  sp!, {%[regs], r11}     \n\t"
+ARM(           "stmdb  sp!, {%[regs], r11}     \n\t"   )
+THUMB(         "stmdb  sp!, {%[regs], r7}      \n\t"   )
                "ldmia  %[regs], {r0-r12}       \n\t"
 #if __LINUX_ARM_ARCH__ >= 6
                "blx    %[fn]                   \n\t"
@@ -96,10 +97,11 @@ emulate_generic_r0_12_noflags(probes_opcode_t insn,
 #endif
                "ldr    lr, [sp], #4            \n\t" /* lr = regs */
                "stmia  lr, {r0-r12}            \n\t"
-               "ldr    r11, [sp], #4           \n\t"
+ARM(           "ldr    r11, [sp], #4           \n\t"   )
+THUMB(         "ldr    r7, [sp], #4            \n\t"   )
                : [regs] "=r" (rregs), [fn] "=r" (rfn)
                : "0" (rregs), "1" (rfn)
-               : "r0", "r2", "r3", "r4", "r5", "r6", "r7",
+               : "r0", "r2", "r3", "r4", "r5", "r6", ARM("r7") THUMB("r11"),
                  "r8", "r9", "r10", "r12", "memory", "cc"
                );
 }
index 7884fcb81c26fe1875d88a4a00bde1bbc19cc516..51624fc263fc22c7a174e2b988cee6bc87c28fdb 100644 (file)
@@ -447,14 +447,16 @@ t16_emulate_loregs(probes_opcode_t insn,
 
        __asm__ __volatile__ (
                "msr    cpsr_fs, %[oldcpsr]     \n\t"
+               "mov    r11, r7                 \n\t"
                "ldmia  %[regs], {r0-r7}        \n\t"
                "blx    %[fn]                   \n\t"
                "stmia  %[regs], {r0-r7}        \n\t"
+               "mov    r7, r11                 \n\t"
                "mrs    %[newcpsr], cpsr        \n\t"
                : [newcpsr] "=r" (newcpsr)
                : [oldcpsr] "r" (oldcpsr), [regs] "r" (regs),
                  [fn] "r" (asi->insn_fn)
-               : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+               : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r11",
                  "lr", "memory", "cc"
                );
 
@@ -524,14 +526,16 @@ t16_emulate_push(probes_opcode_t insn,
                struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        __asm__ __volatile__ (
+               "mov    r11, r7                 \n\t"
                "ldr    r9, [%[regs], #13*4]    \n\t"
                "ldr    r8, [%[regs], #14*4]    \n\t"
                "ldmia  %[regs], {r0-r7}        \n\t"
                "blx    %[fn]                   \n\t"
                "str    r9, [%[regs], #13*4]    \n\t"
+               "mov    r7, r11                 \n\t"
                :
                : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
-               : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+               : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r11",
                  "lr", "memory", "cc"
                );
 }
@@ -558,14 +562,16 @@ t16_emulate_pop_nopc(probes_opcode_t insn,
                struct arch_probes_insn *asi, struct pt_regs *regs)
 {
        __asm__ __volatile__ (
+               "mov    r11, r7                 \n\t"
                "ldr    r9, [%[regs], #13*4]    \n\t"
                "ldmia  %[regs], {r0-r7}        \n\t"
                "blx    %[fn]                   \n\t"
                "stmia  %[regs], {r0-r7}        \n\t"
                "str    r9, [%[regs], #13*4]    \n\t"
+               "mov    r7, r11                 \n\t"
                :
                : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
-               : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
+               : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r9", "r11",
                  "lr", "memory", "cc"
                );
 }
@@ -577,14 +583,16 @@ t16_emulate_pop_pc(probes_opcode_t insn,
        register unsigned long pc asm("r8");
 
        __asm__ __volatile__ (
+               "mov    r11, r7                 \n\t"
                "ldr    r9, [%[regs], #13*4]    \n\t"
                "ldmia  %[regs], {r0-r7}        \n\t"
                "blx    %[fn]                   \n\t"
                "stmia  %[regs], {r0-r7}        \n\t"
                "str    r9, [%[regs], #13*4]    \n\t"
+               "mov    r7, r11                 \n\t"
                : "=r" (pc)
                : [regs] "r" (regs), [fn] "r" (asi->insn_fn)
-               : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r9",
+               : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r9", "r11",
                  "lr", "memory", "cc"
                );