Skip to content

Commit

Permalink
arm64/kprobes: Tidy up sign-extension usage
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Robin Murphy authored and Catalin Marinas committed Nov 7, 2016
1 parent be8f185 commit 4890ae4
Showing 1 changed file with 7 additions and 9 deletions.
16 changes: 7 additions & 9 deletions arch/arm64/kernel/probes/simulate-insn.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,26 @@
* 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)
{
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 4890ae4

Please sign in to comment.