]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
arm64/kprobes: Tidy up sign-extension usage
authorRobin Murphy <robin.murphy@arm.com>
Tue, 18 Oct 2016 12:46:27 +0000 (13:46 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 7 Nov 2016 18:15:03 +0000 (18:15 +0000)
Kprobes does not need its own homebrewed (and frankly inscrutable) sign
extension macro; just use the standard kernel functions instead. Since
the compiler actually recognises the sign-extension idiom of the latter,
we also get the small bonus of some nicer codegen, as each displacement
calculation helper then compiles to a single optimal SBFX instruction.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/kernel/probes/simulate-insn.c

index 8977ce9d009d052f4c22c8be1be9217d30171bfd..357d3efe1366e6bc678d5e7ec4b32d38b020389d 100644 (file)
  * General Public License for more details.
  */
 
+#include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 
 #include "simulate-insn.h"
 
-#define sign_extend(x, signbit)                \
-       ((x) | (0 - ((x) & (1 << (signbit)))))
-
 #define bbl_displacement(insn)         \
-       sign_extend(((insn) & 0x3ffffff) << 2, 27)
+       sign_extend32(((insn) & 0x3ffffff) << 2, 27)
 
 #define bcond_displacement(insn)       \
-       sign_extend(((insn >> 5) & 0x7ffff) << 2, 20)
+       sign_extend32(((insn >> 5) & 0x7ffff) << 2, 20)
 
 #define cbz_displacement(insn) \
-       sign_extend(((insn >> 5) & 0x7ffff) << 2, 20)
+       sign_extend32(((insn >> 5) & 0x7ffff) << 2, 20)
 
 #define tbz_displacement(insn) \
-       sign_extend(((insn >> 5) & 0x3fff) << 2, 15)
+       sign_extend32(((insn >> 5) & 0x3fff) << 2, 15)
 
 #define ldr_displacement(insn) \
-       sign_extend(((insn >> 5) & 0x7ffff) << 2, 20)
+       sign_extend32(((insn >> 5) & 0x7ffff) << 2, 20)
 
 static inline void set_x_reg(struct pt_regs *regs, int reg, u64 val)
 {
@@ -106,7 +104,7 @@ simulate_adr_adrp(u32 opcode, long addr, struct pt_regs *regs)
 
        xn = opcode & 0x1f;
        imm = ((opcode >> 3) & 0x1ffffc) | ((opcode >> 29) & 0x3);
-       imm = sign_extend(imm, 20);
+       imm = sign_extend64(imm, 20);
        if (opcode & 0x80000000)
                val = (imm<<12) + (addr & 0xfffffffffffff000);
        else