^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Kernel Probes (KProbes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * arch/ia64/kernel/kprobes.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) IBM Corporation, 2002, 2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) Intel Corporation, 2005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * <anil.s.keshavamurthy@intel.com> adapted from i386
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/preempt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/extable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/exception.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) enum instruction_type {A, I, M, F, B, L, X, u};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static enum instruction_type bundle_encoding[32][3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { M, I, I }, /* 00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) { M, I, I }, /* 01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { M, I, I }, /* 02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) { M, I, I }, /* 03 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) { M, L, X }, /* 04 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) { M, L, X }, /* 05 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) { u, u, u }, /* 06 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) { u, u, u }, /* 07 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) { M, M, I }, /* 08 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) { M, M, I }, /* 09 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) { M, M, I }, /* 0A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) { M, M, I }, /* 0B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) { M, F, I }, /* 0C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) { M, F, I }, /* 0D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) { M, M, F }, /* 0E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) { M, M, F }, /* 0F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) { M, I, B }, /* 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) { M, I, B }, /* 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) { M, B, B }, /* 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) { M, B, B }, /* 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) { u, u, u }, /* 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) { u, u, u }, /* 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) { B, B, B }, /* 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) { B, B, B }, /* 17 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) { M, M, B }, /* 18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) { M, M, B }, /* 19 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) { u, u, u }, /* 1A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) { u, u, u }, /* 1B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) { M, F, B }, /* 1C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) { M, F, B }, /* 1D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) { u, u, u }, /* 1E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) { u, u, u }, /* 1F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Insert a long branch code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void __kprobes set_brl_inst(void *from, void *to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) s64 rel = ((s64) to - (s64) from) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bundle_t *brl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) brl = (bundle_t *) ((u64) from & ~0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) brl->quad0.template = 0x05; /* [MLX](stop) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) brl->quad0.slot0 = NOP_M_INST; /* nop.m 0x0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) brl->quad0.slot1_p0 = ((rel >> 20) & 0x7fffffffff) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) brl->quad1.slot1_p1 = (((rel >> 20) & 0x7fffffffff) << 2) >> (64 - 46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* brl.cond.sptk.many.clr rel<<4 (qp=0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) brl->quad1.slot2 = BRL_INST(rel >> 59, rel & 0xfffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * In this function we check to see if the instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * is IP relative instruction and update the kprobe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * inst flag accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static void __kprobes update_kprobe_inst_flag(uint template, uint slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) uint major_opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned long kprobe_inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) p->ainsn.inst_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) p->ainsn.target_br_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) p->ainsn.slot = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* Check for Break instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Bits 37:40 Major opcode to be zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * Bits 27:32 X6 to be zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Bits 32:35 X3 to be zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if ((!major_opcode) && (!((kprobe_inst >> 27) & 0x1FF)) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* is a break instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) p->ainsn.inst_flag |= INST_FLAG_BREAK_INST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (bundle_encoding[template][slot] == B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) switch (major_opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case INDIRECT_CALL_OPCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case IP_RELATIVE_PREDICT_OPCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case IP_RELATIVE_BRANCH_OPCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case IP_RELATIVE_CALL_OPCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) } else if (bundle_encoding[template][slot] == X) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) switch (major_opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case LONG_CALL_OPCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * In this function we check to see if the instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * (qp) cmpx.crel.ctype p1,p2=r2,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * on which we are inserting kprobe is cmp instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * with ctype as unc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static uint __kprobes is_cmp_ctype_unc_inst(uint template, uint slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) uint major_opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned long kprobe_inst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) cmp_inst_t cmp_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) uint ctype_unc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!((bundle_encoding[template][slot] == I) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) (bundle_encoding[template][slot] == M)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (!((major_opcode == 0xC) || (major_opcode == 0xD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) (major_opcode == 0xE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) cmp_inst.l = kprobe_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Integer compare - Register Register (A6 type)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) &&(cmp_inst.f.c == 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ctype_unc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) } else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Integer compare - Immediate Register (A8 type)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ctype_unc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return ctype_unc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * In this function we check to see if the instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * on which we are inserting kprobe is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * Returns qp value if supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * Returns -EINVAL if unsupported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int __kprobes unsupported_inst(uint template, uint slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) uint major_opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned long kprobe_inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int qp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) qp = kprobe_inst & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (slot == 1 && qp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) printk(KERN_WARNING "Kprobes on cmp unc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) "instruction on slot 1 at <0x%lx> "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) "is not supported\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) qp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) else if (bundle_encoding[template][slot] == I) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (major_opcode == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Check for Integer speculation instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * - Bit 33-35 to be equal to 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (((kprobe_inst >> 33) & 0x7) == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) "Kprobes on speculation inst at <0x%lx> not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * IP relative mov instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * - Bit 27-35 to be equal to 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (((kprobe_inst >> 27) & 0x1FF) == 0x30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) "Kprobes on \"mov r1=ip\" at <0x%lx> not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) else if ((major_opcode == 5) && !(kprobe_inst & (0xFUl << 33)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) (kprobe_inst & (0x1UL << 12))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* test bit instructions, tbit,tnat,tf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * bit 33-36 to be equal to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * bit 12 to be equal to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (slot == 1 && qp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) printk(KERN_WARNING "Kprobes on test bit "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) "instruction on slot at <0x%lx> "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) "is not supported\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) qp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) else if (bundle_encoding[template][slot] == B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (major_opcode == 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* IP-Relative Predict major code is 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) printk(KERN_WARNING "Kprobes on IP-Relative"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) "Predict is not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) else if (major_opcode == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* Indirect Predict, major code is 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * bit 27-32 to be equal to 10 or 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int x6=(kprobe_inst >> 27) & 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if ((x6 == 0x10) || (x6 == 0x11)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) printk(KERN_WARNING "Kprobes on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) "Indirect Predict is not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* kernel does not use float instruction, here for safety kprobe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * will judge whether it is fcmp/flass/float approximation instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else if (unlikely(bundle_encoding[template][slot] == F)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if ((major_opcode == 4 || major_opcode == 5) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) (kprobe_inst & (0x1 << 12))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* fcmp/fclass unc instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (slot == 1 && qp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) printk(KERN_WARNING "Kprobes on fcmp/fclass "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) "instruction on slot at <0x%lx> "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) "is not supported\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) qp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if ((major_opcode == 0 || major_opcode == 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) (kprobe_inst & (0x1UL << 33))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* float Approximation instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (slot == 1 && qp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) printk(KERN_WARNING "Kprobes on float Approx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) "instr at <0x%lx> is not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) qp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return qp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * In this function we override the bundle with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * the break instruction at the given slot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void __kprobes prepare_break_inst(uint template, uint slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) uint major_opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unsigned long kprobe_inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct kprobe *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int qp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unsigned long break_inst = BREAK_INST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) bundle_t *bundle = &p->opcode.bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * Copy the original kprobe_inst qualifying predicate(qp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * to the break instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break_inst |= qp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) switch (slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) bundle->quad0.slot0 = break_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) bundle->quad0.slot1_p0 = break_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) bundle->quad1.slot1_p1 = break_inst >> (64-46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) bundle->quad1.slot2 = break_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * Update the instruction flag, so that we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * emulate the instruction properly after we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * single step on original instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) unsigned long *kprobe_inst, uint *major_opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned long kprobe_inst_p0, kprobe_inst_p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned int template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) template = bundle->quad0.template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) switch (slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) *kprobe_inst = bundle->quad0.slot0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) kprobe_inst_p0 = bundle->quad0.slot1_p0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) kprobe_inst_p1 = bundle->quad1.slot1_p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) *kprobe_inst = bundle->quad1.slot2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* Returns non-zero if the addr is in the Interrupt Vector Table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static int __kprobes in_ivt_functions(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return (addr >= (unsigned long)__start_ivt_text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) && addr < (unsigned long)__end_ivt_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int __kprobes valid_kprobe_addr(int template, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) printk(KERN_WARNING "Attempting to insert unaligned kprobe "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) "at 0x%lx\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (in_ivt_functions(addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) printk(KERN_WARNING "Kprobes can't be inserted inside "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) "IVT functions at 0x%lx\n", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) i = atomic_add_return(1, &kcb->prev_kprobe_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) kcb->prev_kprobe[i-1].kp = kprobe_running();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) kcb->prev_kprobe[i-1].status = kcb->kprobe_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) i = atomic_read(&kcb->prev_kprobe_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) __this_cpu_write(current_kprobe, kcb->prev_kprobe[i-1].kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) kcb->kprobe_status = kcb->prev_kprobe[i-1].status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) atomic_sub(1, &kcb->prev_kprobe_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static void __kprobes set_current_kprobe(struct kprobe *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct kprobe_ctlblk *kcb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) __this_cpu_write(current_kprobe, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static void kretprobe_trampoline(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) regs->cr_iip = __kretprobe_trampoline_handler(regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) dereference_function_descriptor(kretprobe_trampoline), NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * By returning a non-zero value, we are telling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * kprobe_handler() that we don't want the post_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * to run (and have re-enabled preemption)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ri->ret_addr = (kprobe_opcode_t *)regs->b0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ri->fp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* Replace the return addr with trampoline addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) regs->b0 = (unsigned long)dereference_function_descriptor(kretprobe_trampoline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Check the instruction in the slot is break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static int __kprobes __is_ia64_break_inst(bundle_t *bundle, uint slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) unsigned int major_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) unsigned int template = bundle->quad0.template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) unsigned long kprobe_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (slot == 1 && bundle_encoding[template][1] == L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) slot++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Get Kprobe probe instruction at given slot*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /* For break instruction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * Bits 37:40 Major opcode to be zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * Bits 27:32 X6 to be zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * Bits 32:35 X3 to be zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (major_opcode || ((kprobe_inst >> 27) & 0x1FF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* Not a break instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /* Is a break instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * In this function, we check whether the target bundle modifies IP or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * it triggers an exception. If so, it cannot be boostable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int __kprobes can_boost(bundle_t *bundle, uint slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) unsigned long bundle_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) unsigned int template = bundle->quad0.template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (search_exception_tables(bundle_addr + slot) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) __is_ia64_break_inst(bundle, slot))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return 0; /* exception may occur in this bundle*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) } while ((++slot) < 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) template &= 0x1e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (template >= 0x10 /* including B unit */ ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) template == 0x04 /* including X unit */ ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) template == 0x06) /* undefined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* Prepare long jump bundle and disables other boosters if need */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static void __kprobes prepare_booster(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) unsigned long addr = (unsigned long)p->addr & ~0xFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) unsigned int slot = (unsigned long)p->addr & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct kprobe *other_kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (can_boost(&p->ainsn.insn[0].bundle, slot, addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) set_brl_inst(&p->ainsn.insn[1].bundle, (bundle_t *)addr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) p->ainsn.inst_flag |= INST_FLAG_BOOSTABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* disables boosters in previous slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) for (; addr < (unsigned long)p->addr; addr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) other_kp = get_kprobe((void *)addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (other_kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) other_kp->ainsn.inst_flag &= ~INST_FLAG_BOOSTABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) int __kprobes arch_prepare_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) unsigned long addr = (unsigned long) p->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) unsigned long kprobe_inst=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) unsigned int slot = addr & 0xf, template, major_opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) bundle_t *bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) int qp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) template = bundle->quad0.template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if(valid_kprobe_addr(template, slot, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (slot == 1 && bundle_encoding[template][1] == L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) slot++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /* Get kprobe_inst and major_opcode from the bundle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) qp = unsupported_inst(template, slot, major_opcode, kprobe_inst, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (qp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) p->ainsn.insn = get_insn_slot();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (!p->ainsn.insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) memcpy(&p->opcode, kprobe_addr, sizeof(kprobe_opcode_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) memcpy(p->ainsn.insn, kprobe_addr, sizeof(kprobe_opcode_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) prepare_break_inst(template, slot, major_opcode, kprobe_inst, p, qp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) prepare_booster(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) void __kprobes arch_arm_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) unsigned long arm_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) bundle_t *src, *dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) arm_addr = ((unsigned long)p->addr) & ~0xFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) dest = &((kprobe_opcode_t *)arm_addr)->bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) src = &p->opcode.bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) flush_icache_range((unsigned long)p->ainsn.insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) (unsigned long)p->ainsn.insn +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) sizeof(kprobe_opcode_t) * MAX_INSN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) switch (p->ainsn.slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) dest->quad0.slot0 = src->quad0.slot0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) dest->quad1.slot1_p1 = src->quad1.slot1_p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) dest->quad1.slot2 = src->quad1.slot2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) void __kprobes arch_disarm_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) unsigned long arm_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) bundle_t *src, *dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) arm_addr = ((unsigned long)p->addr) & ~0xFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) dest = &((kprobe_opcode_t *)arm_addr)->bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* p->ainsn.insn contains the original unaltered kprobe_opcode_t */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) src = &p->ainsn.insn->bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) switch (p->ainsn.slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) dest->quad0.slot0 = src->quad0.slot0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dest->quad1.slot1_p1 = src->quad1.slot1_p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) dest->quad1.slot2 = src->quad1.slot2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) void __kprobes arch_remove_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (p->ainsn.insn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) free_insn_slot(p->ainsn.insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) p->ainsn.inst_flag & INST_FLAG_BOOSTABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) p->ainsn.insn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * We are resuming execution after a single step fault, so the pt_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * structure reflects the register state after we executed the instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * located in the kprobe (p->ainsn.insn->bundle). We still need to adjust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * the ip to point back to the original stack address. To set the IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * to original stack address, handle the case where we need to fixup the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * relative IP address and/or fixup branch register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) unsigned long template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int slot = ((unsigned long)p->addr & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) template = p->ainsn.insn->bundle.quad0.template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (slot == 1 && bundle_encoding[template][1] == L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) slot = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (p->ainsn.inst_flag & ~INST_FLAG_BOOSTABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* Fix relative IP address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) regs->cr_iip = (regs->cr_iip - bundle_addr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) resume_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * Fix target branch register, software convention is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * to use either b0 or b6 or b7, so just checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * only those registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) switch (p->ainsn.target_br_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if ((regs->b0 == bundle_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) (regs->b0 == bundle_addr + 0x10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) regs->b0 = (regs->b0 - bundle_addr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) resume_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if ((regs->b6 == bundle_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) (regs->b6 == bundle_addr + 0x10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) regs->b6 = (regs->b6 - bundle_addr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) resume_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if ((regs->b7 == bundle_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) (regs->b7 == bundle_addr + 0x10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) regs->b7 = (regs->b7 - bundle_addr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) resume_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) } /* end switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto turn_ss_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (slot == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (regs->cr_iip == bundle_addr + 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) regs->cr_iip = resume_addr + 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (regs->cr_iip == bundle_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) regs->cr_iip = resume_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) turn_ss_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* Turn off Single Step bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) ia64_psr(regs)->ss = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) unsigned long bundle_addr = (unsigned long) &p->ainsn.insn->bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) unsigned long slot = (unsigned long)p->addr & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) /* single step inline if break instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) regs->cr_iip = (unsigned long)p->addr & ~0xFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) regs->cr_iip = bundle_addr & ~0xFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (slot > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) slot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ia64_psr(regs)->ri = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) /* turn on single stepping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) ia64_psr(regs)->ss = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static int __kprobes is_ia64_break_inst(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) unsigned int slot = ia64_psr(regs)->ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) unsigned long *kprobe_addr = (unsigned long *)regs->cr_iip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) bundle_t bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) memcpy(&bundle, kprobe_addr, sizeof(bundle_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return __is_ia64_break_inst(&bundle, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static int __kprobes pre_kprobes_handler(struct die_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct kprobe *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct pt_regs *regs = args->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct kprobe_ctlblk *kcb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * We don't want to be preempted for the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * duration of kprobe processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) kcb = get_kprobe_ctlblk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* Handle recursion cases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (kprobe_running()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) p = get_kprobe(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ia64_psr(regs)->ss = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) goto no_kprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* We have reentered the pre_kprobe_handler(), since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * another probe was hit while within the handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * We here save the original kprobes variables and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * just single step on the instruction of the new probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * without calling any user handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) save_previous_kprobe(kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) set_current_kprobe(p, kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) kprobes_inc_nmissed_count(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) prepare_ss(p, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) kcb->kprobe_status = KPROBE_REENTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) } else if (!is_ia64_break_inst(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* The breakpoint instruction was removed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * another cpu right after we hit, no further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * handling of this interrupt is appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) goto no_kprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Not our break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) goto no_kprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) p = get_kprobe(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (!is_ia64_break_inst(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * The breakpoint instruction was removed right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * after we hit it. Another cpu has removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * either a probepoint or a debugger breakpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * at this address. In either case, no further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * handling of this interrupt is appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) /* Not one of our break, let kernel handle it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) goto no_kprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) set_current_kprobe(p, kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) kcb->kprobe_status = KPROBE_HIT_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (p->pre_handler && p->pre_handler(p, regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) reset_current_kprobe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) #if !defined(CONFIG_PREEMPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (p->ainsn.inst_flag == INST_FLAG_BOOSTABLE && !p->post_handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* Boost up -- we can execute copied instructions directly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ia64_psr(regs)->ri = p->ainsn.slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) regs->cr_iip = (unsigned long)&p->ainsn.insn->bundle & ~0xFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /* turn single stepping off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) ia64_psr(regs)->ss = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) reset_current_kprobe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) prepare_ss(p, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) kcb->kprobe_status = KPROBE_HIT_SS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) no_kprobe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static int __kprobes post_kprobes_handler(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct kprobe *cur = kprobe_running();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) kcb->kprobe_status = KPROBE_HIT_SSDONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) cur->post_handler(cur, regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) resume_execution(cur, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /*Restore back the original saved kprobes variables and continue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (kcb->kprobe_status == KPROBE_REENTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) restore_previous_kprobe(kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) reset_current_kprobe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct kprobe *cur = kprobe_running();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) switch(kcb->kprobe_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case KPROBE_HIT_SS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) case KPROBE_REENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * We are here because the instruction being single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * stepped caused a page fault. We reset the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * kprobe and the instruction pointer points back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * the probe address and allow the page fault handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * to continue as a normal page fault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) regs->cr_iip = ((unsigned long)cur->addr) & ~0xFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ia64_psr(regs)->ri = ((unsigned long)cur->addr) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (kcb->kprobe_status == KPROBE_REENTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) restore_previous_kprobe(kcb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) reset_current_kprobe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) preempt_enable_no_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) case KPROBE_HIT_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case KPROBE_HIT_SSDONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * We increment the nmissed count for accounting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * we can also use npre/npostfault count for accounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * these specific fault cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) kprobes_inc_nmissed_count(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * We come here because instructions in the pre/post
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * handler caused the page_fault, this could happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * if handler tries to access user space by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * copy_from_user(), get_user() etc. Let the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * user-specified handler try to fix it first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * In case the user-specified fault handler returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * zero, try to fix up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (ia64_done_with_exception(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * Let ia64_do_page_fault() fix it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) unsigned long val, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct die_args *args = (struct die_args *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int ret = NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (args->regs && user_mode(args->regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) switch(val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case DIE_BREAK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* err is break number from ia64_bad_break() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if ((args->err >> 12) == (__IA64_BREAK_KPROBE >> 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) || args->err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (pre_kprobes_handler(args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ret = NOTIFY_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) case DIE_FAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* err is vector number from ia64_fault() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (args->err == 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (post_kprobes_handler(args->regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ret = NOTIFY_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) unsigned long arch_deref_entry_point(void *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return ((struct fnptr *)entry)->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static struct kprobe trampoline_p = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .pre_handler = trampoline_probe_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int __init arch_init_kprobes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) trampoline_p.addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) dereference_function_descriptor(kretprobe_trampoline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return register_kprobe(&trampoline_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) int __kprobes arch_trampoline_kprobe(struct kprobe *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (p->addr ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) dereference_function_descriptor(kretprobe_trampoline))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }