1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun #ifndef _ASM_KPROBES_H 3*4882a593Smuzhiyun #define _ASM_KPROBES_H 4*4882a593Smuzhiyun /* 5*4882a593Smuzhiyun * Kernel Probes (KProbes) 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Copyright (C) IBM Corporation, 2002, 2004 8*4882a593Smuzhiyun * Copyright (C) Intel Corporation, 2005 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy 11*4882a593Smuzhiyun * <anil.s.keshavamurthy@intel.com> adapted from i386 12*4882a593Smuzhiyun */ 13*4882a593Smuzhiyun #include <asm-generic/kprobes.h> 14*4882a593Smuzhiyun #include <asm/break.h> 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun #define BREAK_INST (long)(__IA64_BREAK_KPROBE << 6) 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #ifdef CONFIG_KPROBES 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #include <linux/types.h> 21*4882a593Smuzhiyun #include <linux/ptrace.h> 22*4882a593Smuzhiyun #include <linux/percpu.h> 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #define __ARCH_WANT_KPROBES_INSN_SLOT 25*4882a593Smuzhiyun #define MAX_INSN_SIZE 2 /* last half is for kprobe-booster */ 26*4882a593Smuzhiyun #define NOP_M_INST (long)(1<<27) 27*4882a593Smuzhiyun #define BRL_INST(i1, i2) ((long)((0xcL << 37) | /* brl */ \ 28*4882a593Smuzhiyun (0x1L << 12) | /* many */ \ 29*4882a593Smuzhiyun (((i1) & 1) << 36) | ((i2) << 13))) /* imm */ 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun typedef union cmp_inst { 32*4882a593Smuzhiyun struct { 33*4882a593Smuzhiyun unsigned long long qp : 6; 34*4882a593Smuzhiyun unsigned long long p1 : 6; 35*4882a593Smuzhiyun unsigned long long c : 1; 36*4882a593Smuzhiyun unsigned long long r2 : 7; 37*4882a593Smuzhiyun unsigned long long r3 : 7; 38*4882a593Smuzhiyun unsigned long long p2 : 6; 39*4882a593Smuzhiyun unsigned long long ta : 1; 40*4882a593Smuzhiyun unsigned long long x2 : 2; 41*4882a593Smuzhiyun unsigned long long tb : 1; 42*4882a593Smuzhiyun unsigned long long opcode : 4; 43*4882a593Smuzhiyun unsigned long long reserved : 23; 44*4882a593Smuzhiyun }f; 45*4882a593Smuzhiyun unsigned long long l; 46*4882a593Smuzhiyun } cmp_inst_t; 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun struct kprobe; 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun typedef struct _bundle { 51*4882a593Smuzhiyun struct { 52*4882a593Smuzhiyun unsigned long long template : 5; 53*4882a593Smuzhiyun unsigned long long slot0 : 41; 54*4882a593Smuzhiyun unsigned long long slot1_p0 : 64-46; 55*4882a593Smuzhiyun } quad0; 56*4882a593Smuzhiyun struct { 57*4882a593Smuzhiyun unsigned long long slot1_p1 : 41 - (64-46); 58*4882a593Smuzhiyun unsigned long long slot2 : 41; 59*4882a593Smuzhiyun } quad1; 60*4882a593Smuzhiyun } __attribute__((__aligned__(16))) bundle_t; 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun struct prev_kprobe { 63*4882a593Smuzhiyun struct kprobe *kp; 64*4882a593Smuzhiyun unsigned long status; 65*4882a593Smuzhiyun }; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun #define MAX_PARAM_RSE_SIZE (0x60+0x60/0x3f) 68*4882a593Smuzhiyun /* per-cpu kprobe control block */ 69*4882a593Smuzhiyun #define ARCH_PREV_KPROBE_SZ 2 70*4882a593Smuzhiyun struct kprobe_ctlblk { 71*4882a593Smuzhiyun unsigned long kprobe_status; 72*4882a593Smuzhiyun unsigned long *bsp; 73*4882a593Smuzhiyun unsigned long cfm; 74*4882a593Smuzhiyun atomic_t prev_kprobe_index; 75*4882a593Smuzhiyun struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ]; 76*4882a593Smuzhiyun }; 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun #define kretprobe_blacklist_size 0 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun #define SLOT0_OPCODE_SHIFT (37) 81*4882a593Smuzhiyun #define SLOT1_p1_OPCODE_SHIFT (37 - (64-46)) 82*4882a593Smuzhiyun #define SLOT2_OPCODE_SHIFT (37) 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun #define INDIRECT_CALL_OPCODE (1) 85*4882a593Smuzhiyun #define IP_RELATIVE_CALL_OPCODE (5) 86*4882a593Smuzhiyun #define IP_RELATIVE_BRANCH_OPCODE (4) 87*4882a593Smuzhiyun #define IP_RELATIVE_PREDICT_OPCODE (7) 88*4882a593Smuzhiyun #define LONG_BRANCH_OPCODE (0xC) 89*4882a593Smuzhiyun #define LONG_CALL_OPCODE (0xD) 90*4882a593Smuzhiyun #define flush_insn_slot(p) do { } while (0) 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun typedef struct kprobe_opcode { 93*4882a593Smuzhiyun bundle_t bundle; 94*4882a593Smuzhiyun } kprobe_opcode_t; 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun /* Architecture specific copy of original instruction*/ 97*4882a593Smuzhiyun struct arch_specific_insn { 98*4882a593Smuzhiyun /* copy of the instruction to be emulated */ 99*4882a593Smuzhiyun kprobe_opcode_t *insn; 100*4882a593Smuzhiyun #define INST_FLAG_FIX_RELATIVE_IP_ADDR 1 101*4882a593Smuzhiyun #define INST_FLAG_FIX_BRANCH_REG 2 102*4882a593Smuzhiyun #define INST_FLAG_BREAK_INST 4 103*4882a593Smuzhiyun #define INST_FLAG_BOOSTABLE 8 104*4882a593Smuzhiyun unsigned long inst_flag; 105*4882a593Smuzhiyun unsigned short target_br_reg; 106*4882a593Smuzhiyun unsigned short slot; 107*4882a593Smuzhiyun }; 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); 110*4882a593Smuzhiyun extern int kprobe_exceptions_notify(struct notifier_block *self, 111*4882a593Smuzhiyun unsigned long val, void *data); 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun extern void invalidate_stacked_regs(void); 114*4882a593Smuzhiyun extern void flush_register_stack(void); 115*4882a593Smuzhiyun extern void arch_remove_kprobe(struct kprobe *p); 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun #endif /* CONFIG_KPROBES */ 118*4882a593Smuzhiyun #endif /* _ASM_KPROBES_H */ 119