Loading arch/arm/include/asm/ptrace.h +0 −1 Original line number Diff line number Diff line Loading @@ -121,7 +121,6 @@ extern unsigned long profile_pc(struct pt_regs *regs); #define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0)) extern int regs_query_register_offset(const char *name); extern const char *regs_query_register_name(unsigned int offset); extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr); extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); Loading arch/arm64/Kconfig +3 −0 Original line number Diff line number Diff line Loading @@ -79,8 +79,11 @@ config ARM64 select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RCU_TABLE_FREE select HAVE_SYSCALL_TRACEPOINTS select HAVE_KPROBES select HAVE_KRETPROBES if HAVE_KPROBES select IOMMU_DMA if IOMMU_SUPPORT select IRQ_DOMAIN select IRQ_FORCED_THREADING Loading arch/arm64/include/asm/debug-monitors.h +5 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,11 @@ #define CACHE_FLUSH_IS_SAFE 1 /* kprobes BRK opcodes with ESR encoding */ #define BRK64_ESR_MASK 0xFFFF #define BRK64_ESR_KPROBES 0x0004 #define BRK64_OPCODE_KPROBES (AARCH64_BREAK_MON | (BRK64_ESR_KPROBES << 5)) /* AArch32 */ #define DBG_ESR_EVT_BKPT 0x4 #define DBG_ESR_EVT_VECC 0x5 Loading arch/arm64/include/asm/insn.h +41 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,29 @@ enum aarch64_insn_register { AARCH64_INSN_REG_SP = 31 /* Stack pointer: as load/store base reg */ }; enum aarch64_insn_special_register { AARCH64_INSN_SPCLREG_SPSR_EL1 = 0xC200, AARCH64_INSN_SPCLREG_ELR_EL1 = 0xC201, AARCH64_INSN_SPCLREG_SP_EL0 = 0xC208, AARCH64_INSN_SPCLREG_SPSEL = 0xC210, AARCH64_INSN_SPCLREG_CURRENTEL = 0xC212, AARCH64_INSN_SPCLREG_DAIF = 0xDA11, AARCH64_INSN_SPCLREG_NZCV = 0xDA10, AARCH64_INSN_SPCLREG_FPCR = 0xDA20, AARCH64_INSN_SPCLREG_DSPSR_EL0 = 0xDA28, AARCH64_INSN_SPCLREG_DLR_EL0 = 0xDA29, AARCH64_INSN_SPCLREG_SPSR_EL2 = 0xE200, AARCH64_INSN_SPCLREG_ELR_EL2 = 0xE201, AARCH64_INSN_SPCLREG_SP_EL1 = 0xE208, AARCH64_INSN_SPCLREG_SPSR_INQ = 0xE218, AARCH64_INSN_SPCLREG_SPSR_ABT = 0xE219, AARCH64_INSN_SPCLREG_SPSR_UND = 0xE21A, AARCH64_INSN_SPCLREG_SPSR_FIQ = 0xE21B, AARCH64_INSN_SPCLREG_SPSR_EL3 = 0xF200, AARCH64_INSN_SPCLREG_ELR_EL3 = 0xF201, AARCH64_INSN_SPCLREG_SP_EL2 = 0xF210 }; enum aarch64_insn_variant { AARCH64_INSN_VARIANT_32BIT, AARCH64_INSN_VARIANT_64BIT Loading Loading @@ -223,8 +246,15 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \ static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \ { return (val); } __AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000) __AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000) __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800) __AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000) __AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000) __AARCH64_INSN_FUNCS(exclusive, 0x3F800000, 0x08000000) __AARCH64_INSN_FUNCS(load_ex, 0x3F400000, 0x08400000) __AARCH64_INSN_FUNCS(store_ex, 0x3F400000, 0x08000000) __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000) __AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000) __AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000) Loading Loading @@ -273,10 +303,15 @@ __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001) __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) __AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003) __AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000) __AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000) __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000) __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000) __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000) __AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F03E0) __AARCH64_INSN_FUNCS(mrs, 0xFFF00000, 0xD5300000) __AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F) __AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000) #undef __AARCH64_INSN_FUNCS Loading @@ -286,6 +321,8 @@ bool aarch64_insn_is_branch_imm(u32 insn); int aarch64_insn_read(void *addr, u32 *insnp); int aarch64_insn_write(void *addr, u32 insn); enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn); bool aarch64_insn_uses_literal(u32 insn); bool aarch64_insn_is_branch(u32 insn); u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn); u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, u32 insn, u64 imm); Loading Loading @@ -367,9 +404,13 @@ bool aarch32_insn_is_wide(u32 insn); #define A32_RT_OFFSET 12 #define A32_RT2_OFFSET 0 u32 aarch64_insn_extract_system_reg(u32 insn); u32 aarch32_insn_extract_reg_num(u32 insn, int offset); u32 aarch32_insn_mcr_extract_opc2(u32 insn); u32 aarch32_insn_mcr_extract_crm(u32 insn); typedef bool (pstate_check_t)(unsigned long); extern pstate_check_t * const aarch32_opcode_cond_checks[16]; #endif /* __ASSEMBLY__ */ #endif /* __ASM_INSN_H */ arch/arm64/include/asm/kprobes.h 0 → 100644 +60 −0 Original line number Diff line number Diff line /* * arch/arm64/include/asm/kprobes.h * * Copyright (C) 2013 Linaro Limited * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ #ifndef _ARM_KPROBES_H #define _ARM_KPROBES_H #include <linux/types.h> #include <linux/ptrace.h> #include <linux/percpu.h> #define __ARCH_WANT_KPROBES_INSN_SLOT #define MAX_INSN_SIZE 1 #define flush_insn_slot(p) do { } while (0) #define kretprobe_blacklist_size 0 #include <asm/probes.h> struct prev_kprobe { struct kprobe *kp; unsigned int status; }; /* Single step context for kprobe */ struct kprobe_step_ctx { unsigned long ss_pending; unsigned long match_addr; }; /* per-cpu kprobe control block */ struct kprobe_ctlblk { unsigned int kprobe_status; unsigned long saved_irqflag; struct prev_kprobe prev_kprobe; struct kprobe_step_ctx ss_ctx; struct pt_regs jprobe_saved_regs; }; void arch_remove_kprobe(struct kprobe *); int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); int kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr); int kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr); void kretprobe_trampoline(void); void __kprobes *trampoline_probe_handler(struct pt_regs *regs); #endif /* _ARM_KPROBES_H */ Loading
arch/arm/include/asm/ptrace.h +0 −1 Original line number Diff line number Diff line Loading @@ -121,7 +121,6 @@ extern unsigned long profile_pc(struct pt_regs *regs); #define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0)) extern int regs_query_register_offset(const char *name); extern const char *regs_query_register_name(unsigned int offset); extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr); extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); Loading
arch/arm64/Kconfig +3 −0 Original line number Diff line number Diff line Loading @@ -79,8 +79,11 @@ config ARM64 select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RCU_TABLE_FREE select HAVE_SYSCALL_TRACEPOINTS select HAVE_KPROBES select HAVE_KRETPROBES if HAVE_KPROBES select IOMMU_DMA if IOMMU_SUPPORT select IRQ_DOMAIN select IRQ_FORCED_THREADING Loading
arch/arm64/include/asm/debug-monitors.h +5 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,11 @@ #define CACHE_FLUSH_IS_SAFE 1 /* kprobes BRK opcodes with ESR encoding */ #define BRK64_ESR_MASK 0xFFFF #define BRK64_ESR_KPROBES 0x0004 #define BRK64_OPCODE_KPROBES (AARCH64_BREAK_MON | (BRK64_ESR_KPROBES << 5)) /* AArch32 */ #define DBG_ESR_EVT_BKPT 0x4 #define DBG_ESR_EVT_VECC 0x5 Loading
arch/arm64/include/asm/insn.h +41 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,29 @@ enum aarch64_insn_register { AARCH64_INSN_REG_SP = 31 /* Stack pointer: as load/store base reg */ }; enum aarch64_insn_special_register { AARCH64_INSN_SPCLREG_SPSR_EL1 = 0xC200, AARCH64_INSN_SPCLREG_ELR_EL1 = 0xC201, AARCH64_INSN_SPCLREG_SP_EL0 = 0xC208, AARCH64_INSN_SPCLREG_SPSEL = 0xC210, AARCH64_INSN_SPCLREG_CURRENTEL = 0xC212, AARCH64_INSN_SPCLREG_DAIF = 0xDA11, AARCH64_INSN_SPCLREG_NZCV = 0xDA10, AARCH64_INSN_SPCLREG_FPCR = 0xDA20, AARCH64_INSN_SPCLREG_DSPSR_EL0 = 0xDA28, AARCH64_INSN_SPCLREG_DLR_EL0 = 0xDA29, AARCH64_INSN_SPCLREG_SPSR_EL2 = 0xE200, AARCH64_INSN_SPCLREG_ELR_EL2 = 0xE201, AARCH64_INSN_SPCLREG_SP_EL1 = 0xE208, AARCH64_INSN_SPCLREG_SPSR_INQ = 0xE218, AARCH64_INSN_SPCLREG_SPSR_ABT = 0xE219, AARCH64_INSN_SPCLREG_SPSR_UND = 0xE21A, AARCH64_INSN_SPCLREG_SPSR_FIQ = 0xE21B, AARCH64_INSN_SPCLREG_SPSR_EL3 = 0xF200, AARCH64_INSN_SPCLREG_ELR_EL3 = 0xF201, AARCH64_INSN_SPCLREG_SP_EL2 = 0xF210 }; enum aarch64_insn_variant { AARCH64_INSN_VARIANT_32BIT, AARCH64_INSN_VARIANT_64BIT Loading Loading @@ -223,8 +246,15 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \ static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \ { return (val); } __AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000) __AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000) __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800) __AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000) __AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000) __AARCH64_INSN_FUNCS(exclusive, 0x3F800000, 0x08000000) __AARCH64_INSN_FUNCS(load_ex, 0x3F400000, 0x08400000) __AARCH64_INSN_FUNCS(store_ex, 0x3F400000, 0x08000000) __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000) __AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000) __AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000) Loading Loading @@ -273,10 +303,15 @@ __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001) __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) __AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003) __AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000) __AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000) __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000) __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000) __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000) __AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F03E0) __AARCH64_INSN_FUNCS(mrs, 0xFFF00000, 0xD5300000) __AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F01F, 0xD500401F) __AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000) #undef __AARCH64_INSN_FUNCS Loading @@ -286,6 +321,8 @@ bool aarch64_insn_is_branch_imm(u32 insn); int aarch64_insn_read(void *addr, u32 *insnp); int aarch64_insn_write(void *addr, u32 insn); enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn); bool aarch64_insn_uses_literal(u32 insn); bool aarch64_insn_is_branch(u32 insn); u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn); u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, u32 insn, u64 imm); Loading Loading @@ -367,9 +404,13 @@ bool aarch32_insn_is_wide(u32 insn); #define A32_RT_OFFSET 12 #define A32_RT2_OFFSET 0 u32 aarch64_insn_extract_system_reg(u32 insn); u32 aarch32_insn_extract_reg_num(u32 insn, int offset); u32 aarch32_insn_mcr_extract_opc2(u32 insn); u32 aarch32_insn_mcr_extract_crm(u32 insn); typedef bool (pstate_check_t)(unsigned long); extern pstate_check_t * const aarch32_opcode_cond_checks[16]; #endif /* __ASSEMBLY__ */ #endif /* __ASM_INSN_H */
arch/arm64/include/asm/kprobes.h 0 → 100644 +60 −0 Original line number Diff line number Diff line /* * arch/arm64/include/asm/kprobes.h * * Copyright (C) 2013 Linaro Limited * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ #ifndef _ARM_KPROBES_H #define _ARM_KPROBES_H #include <linux/types.h> #include <linux/ptrace.h> #include <linux/percpu.h> #define __ARCH_WANT_KPROBES_INSN_SLOT #define MAX_INSN_SIZE 1 #define flush_insn_slot(p) do { } while (0) #define kretprobe_blacklist_size 0 #include <asm/probes.h> struct prev_kprobe { struct kprobe *kp; unsigned int status; }; /* Single step context for kprobe */ struct kprobe_step_ctx { unsigned long ss_pending; unsigned long match_addr; }; /* per-cpu kprobe control block */ struct kprobe_ctlblk { unsigned int kprobe_status; unsigned long saved_irqflag; struct prev_kprobe prev_kprobe; struct kprobe_step_ctx ss_ctx; struct pt_regs jprobe_saved_regs; }; void arch_remove_kprobe(struct kprobe *); int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); int kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr); int kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr); void kretprobe_trampoline(void); void __kprobes *trampoline_probe_handler(struct pt_regs *regs); #endif /* _ARM_KPROBES_H */