11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2f684199fSMasami Hiramatsu /*
3f684199fSMasami Hiramatsu * Kernel Probes (KProbes)
4f684199fSMasami Hiramatsu *
5f684199fSMasami Hiramatsu * Copyright (C) IBM Corporation, 2002, 2004
6f684199fSMasami Hiramatsu *
7f684199fSMasami Hiramatsu * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
8f684199fSMasami Hiramatsu * Probes initial implementation ( includes contributions from
9f684199fSMasami Hiramatsu * Rusty Russell).
10f684199fSMasami Hiramatsu * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
11f684199fSMasami Hiramatsu * interface to access function arguments.
12f684199fSMasami Hiramatsu * 2004-Oct Jim Keniston <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
13f684199fSMasami Hiramatsu * <prasanna@in.ibm.com> adapted for x86_64 from i386.
14f684199fSMasami Hiramatsu * 2005-Mar Roland McGrath <roland@redhat.com>
15f684199fSMasami Hiramatsu * Fixed to handle %rip-relative addressing mode correctly.
16f684199fSMasami Hiramatsu * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston
17f684199fSMasami Hiramatsu * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
18f684199fSMasami Hiramatsu * <prasanna@in.ibm.com> added function-return probes.
19f684199fSMasami Hiramatsu * 2005-May Rusty Lynch <rusty.lynch@intel.com>
20f684199fSMasami Hiramatsu * Added function return probes functionality
21f684199fSMasami Hiramatsu * 2006-Feb Masami Hiramatsu <hiramatu@sdl.hitachi.co.jp> added
22f684199fSMasami Hiramatsu * kprobe-booster and kretprobe-booster for i386.
23f684199fSMasami Hiramatsu * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com> added kprobe-booster
24f684199fSMasami Hiramatsu * and kretprobe-booster for x86-64
25f684199fSMasami Hiramatsu * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com>, Arjan van de Ven
26f684199fSMasami Hiramatsu * <arjan@infradead.org> and Jim Keniston <jkenisto@us.ibm.com>
27f684199fSMasami Hiramatsu * unified x86 kprobes code.
28f684199fSMasami Hiramatsu */
29f684199fSMasami Hiramatsu #include <linux/kprobes.h>
30f684199fSMasami Hiramatsu #include <linux/ptrace.h>
31f684199fSMasami Hiramatsu #include <linux/string.h>
32f684199fSMasami Hiramatsu #include <linux/slab.h>
33f684199fSMasami Hiramatsu #include <linux/hardirq.h>
34f684199fSMasami Hiramatsu #include <linux/preempt.h>
35b17b0153SIngo Molnar #include <linux/sched/debug.h>
363e46bb40SAdrian Hunter #include <linux/perf_event.h>
37744c193eSPaul Gortmaker #include <linux/extable.h>
38f684199fSMasami Hiramatsu #include <linux/kdebug.h>
39f684199fSMasami Hiramatsu #include <linux/kallsyms.h>
401993bf97SMasami Hiramatsu (Google) #include <linux/kgdb.h>
41f684199fSMasami Hiramatsu #include <linux/ftrace.h>
429f7d416cSDmitry Vyukov #include <linux/kasan.h>
43c93f5cf5SMasami Hiramatsu #include <linux/moduleloader.h>
4400089c04SJulien Thierry #include <linux/objtool.h>
456315ec92SSean Christopherson #include <linux/vmalloc.h>
4665fddcfcSMike Rapoport #include <linux/pgtable.h>
47d48567c9SPeter Zijlstra #include <linux/set_memory.h>
48b6541376SMasami Hiramatsu #include <linux/cfi.h>
49f684199fSMasami Hiramatsu
5035de5b06SAndy Lutomirski #include <asm/text-patching.h>
51f684199fSMasami Hiramatsu #include <asm/cacheflush.h>
52f684199fSMasami Hiramatsu #include <asm/desc.h>
537c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
54f684199fSMasami Hiramatsu #include <asm/alternative.h>
55f684199fSMasami Hiramatsu #include <asm/insn.h>
56f684199fSMasami Hiramatsu #include <asm/debugreg.h>
57cc66bb91SPeter Zijlstra #include <asm/ibt.h>
58f684199fSMasami Hiramatsu
59f684199fSMasami Hiramatsu #include "common.h"
60f684199fSMasami Hiramatsu
61f684199fSMasami Hiramatsu DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
62f684199fSMasami Hiramatsu DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
63f684199fSMasami Hiramatsu
64f684199fSMasami Hiramatsu #define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
65f684199fSMasami Hiramatsu (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \
66f684199fSMasami Hiramatsu (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \
67f684199fSMasami Hiramatsu (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) | \
68f684199fSMasami Hiramatsu (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf)) \
69f684199fSMasami Hiramatsu << (row % 32))
70f684199fSMasami Hiramatsu /*
71f684199fSMasami Hiramatsu * Undefined/reserved opcodes, conditional jump, Opcode Extension
72f684199fSMasami Hiramatsu * Groups, and some special opcodes can not boost.
73f684199fSMasami Hiramatsu * This is non-const and volatile to keep gcc from statically
74f684199fSMasami Hiramatsu * optimizing it out, as variable_test_bit makes gcc think only
75f684199fSMasami Hiramatsu * *(unsigned long*) is used.
76f684199fSMasami Hiramatsu */
77f684199fSMasami Hiramatsu static volatile u32 twobyte_is_boostable[256 / 32] = {
78f684199fSMasami Hiramatsu /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
79f684199fSMasami Hiramatsu /* ---------------------------------------------- */
80f684199fSMasami Hiramatsu W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */
81b7e37567SWang Nan W(0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1) , /* 10 */
82f684199fSMasami Hiramatsu W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 20 */
83f684199fSMasami Hiramatsu W(0x30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 30 */
84f684199fSMasami Hiramatsu W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */
85f684199fSMasami Hiramatsu W(0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 50 */
86f684199fSMasami Hiramatsu W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1) | /* 60 */
87f684199fSMasami Hiramatsu W(0x70, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) , /* 70 */
88f684199fSMasami Hiramatsu W(0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 80 */
89f684199fSMasami Hiramatsu W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
90f684199fSMasami Hiramatsu W(0xa0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) | /* a0 */
91f684199fSMasami Hiramatsu W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1) , /* b0 */
92f684199fSMasami Hiramatsu W(0xc0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* c0 */
93f684199fSMasami Hiramatsu W(0xd0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) , /* d0 */
94f684199fSMasami Hiramatsu W(0xe0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1) | /* e0 */
95f684199fSMasami Hiramatsu W(0xf0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0) /* f0 */
96f684199fSMasami Hiramatsu /* ----------------------------------------------- */
97f684199fSMasami Hiramatsu /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
98f684199fSMasami Hiramatsu };
99f684199fSMasami Hiramatsu #undef W
100f684199fSMasami Hiramatsu
101f684199fSMasami Hiramatsu struct kretprobe_blackpoint kretprobe_blacklist[] = {
102f684199fSMasami Hiramatsu {"__switch_to", }, /* This function switches only current task, but
103f684199fSMasami Hiramatsu doesn't switch kernel stack.*/
104f684199fSMasami Hiramatsu {NULL, NULL} /* Terminator */
105f684199fSMasami Hiramatsu };
106f684199fSMasami Hiramatsu
107f684199fSMasami Hiramatsu const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
108f684199fSMasami Hiramatsu
1099326638cSMasami Hiramatsu static nokprobe_inline void
__synthesize_relative_insn(void * dest,void * from,void * to,u8 op)11063fef14fSMasami Hiramatsu __synthesize_relative_insn(void *dest, void *from, void *to, u8 op)
111f684199fSMasami Hiramatsu {
112f684199fSMasami Hiramatsu struct __arch_relative_insn {
113f684199fSMasami Hiramatsu u8 op;
114f684199fSMasami Hiramatsu s32 raddr;
115f684199fSMasami Hiramatsu } __packed *insn;
116f684199fSMasami Hiramatsu
11763fef14fSMasami Hiramatsu insn = (struct __arch_relative_insn *)dest;
118f684199fSMasami Hiramatsu insn->raddr = (s32)((long)(to) - ((long)(from) + 5));
119f684199fSMasami Hiramatsu insn->op = op;
120f684199fSMasami Hiramatsu }
121f684199fSMasami Hiramatsu
122f684199fSMasami Hiramatsu /* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
synthesize_reljump(void * dest,void * from,void * to)12363fef14fSMasami Hiramatsu void synthesize_reljump(void *dest, void *from, void *to)
124f684199fSMasami Hiramatsu {
125ab09e95cSPeter Zijlstra __synthesize_relative_insn(dest, from, to, JMP32_INSN_OPCODE);
126f684199fSMasami Hiramatsu }
1279326638cSMasami Hiramatsu NOKPROBE_SYMBOL(synthesize_reljump);
128f684199fSMasami Hiramatsu
129f684199fSMasami Hiramatsu /* Insert a call instruction at address 'from', which calls address 'to'.*/
synthesize_relcall(void * dest,void * from,void * to)13063fef14fSMasami Hiramatsu void synthesize_relcall(void *dest, void *from, void *to)
131f684199fSMasami Hiramatsu {
132ab09e95cSPeter Zijlstra __synthesize_relative_insn(dest, from, to, CALL_INSN_OPCODE);
133f684199fSMasami Hiramatsu }
1349326638cSMasami Hiramatsu NOKPROBE_SYMBOL(synthesize_relcall);
135f684199fSMasami Hiramatsu
136f684199fSMasami Hiramatsu /*
137a8d11cd0SMasami Hiramatsu * Returns non-zero if INSN is boostable.
138f684199fSMasami Hiramatsu * RIP relative instructions are adjusted at copying time in 64 bits mode
139f684199fSMasami Hiramatsu */
can_boost(struct insn * insn,void * addr)140a8d11cd0SMasami Hiramatsu int can_boost(struct insn *insn, void *addr)
141f684199fSMasami Hiramatsu {
142f684199fSMasami Hiramatsu kprobe_opcode_t opcode;
1436dd3b8c9SMasami Hiramatsu insn_byte_t prefix;
1446dd3b8c9SMasami Hiramatsu int i;
145f684199fSMasami Hiramatsu
14675013fb1SMasami Hiramatsu if (search_exception_tables((unsigned long)addr))
147f684199fSMasami Hiramatsu return 0; /* Page fault may occur on this address. */
148f684199fSMasami Hiramatsu
149f684199fSMasami Hiramatsu /* 2nd-byte opcode */
150a8d11cd0SMasami Hiramatsu if (insn->opcode.nbytes == 2)
151a8d11cd0SMasami Hiramatsu return test_bit(insn->opcode.bytes[1],
152f684199fSMasami Hiramatsu (unsigned long *)twobyte_is_boostable);
15317880e4dSMasami Hiramatsu
154a8d11cd0SMasami Hiramatsu if (insn->opcode.nbytes != 1)
15517880e4dSMasami Hiramatsu return 0;
15617880e4dSMasami Hiramatsu
1576dd3b8c9SMasami Hiramatsu for_each_insn_prefix(insn, i, prefix) {
1586dd3b8c9SMasami Hiramatsu insn_attr_t attr;
1596dd3b8c9SMasami Hiramatsu
1606dd3b8c9SMasami Hiramatsu attr = inat_get_opcode_attribute(prefix);
1616dd3b8c9SMasami Hiramatsu /* Can't boost Address-size override prefix and CS override prefix */
1626dd3b8c9SMasami Hiramatsu if (prefix == 0x2e || inat_is_address_size_prefix(attr))
16317880e4dSMasami Hiramatsu return 0;
1646dd3b8c9SMasami Hiramatsu }
16517880e4dSMasami Hiramatsu
166a8d11cd0SMasami Hiramatsu opcode = insn->opcode.bytes[0];
167f684199fSMasami Hiramatsu
1682f706e0eSMasami Hiramatsu switch (opcode) {
1692f706e0eSMasami Hiramatsu case 0x62: /* bound */
1702f706e0eSMasami Hiramatsu case 0x70 ... 0x7f: /* Conditional jumps */
1712f706e0eSMasami Hiramatsu case 0x9a: /* Call far */
1722f706e0eSMasami Hiramatsu case 0xc0 ... 0xc1: /* Grp2 */
1732f706e0eSMasami Hiramatsu case 0xcc ... 0xce: /* software exceptions */
1742f706e0eSMasami Hiramatsu case 0xd0 ... 0xd3: /* Grp2 */
1752f706e0eSMasami Hiramatsu case 0xd6: /* (UD) */
1762f706e0eSMasami Hiramatsu case 0xd8 ... 0xdf: /* ESC */
1772f706e0eSMasami Hiramatsu case 0xe0 ... 0xe3: /* LOOP*, JCXZ */
1782f706e0eSMasami Hiramatsu case 0xe8 ... 0xe9: /* near Call, JMP */
1792f706e0eSMasami Hiramatsu case 0xeb: /* Short JMP */
1802f706e0eSMasami Hiramatsu case 0xf0 ... 0xf4: /* LOCK/REP, HLT */
1812f706e0eSMasami Hiramatsu case 0xf6 ... 0xf7: /* Grp3 */
1822f706e0eSMasami Hiramatsu case 0xfe: /* Grp4 */
1832f706e0eSMasami Hiramatsu /* ... are not boostable */
1842f706e0eSMasami Hiramatsu return 0;
1852f706e0eSMasami Hiramatsu case 0xff: /* Grp5 */
1862f706e0eSMasami Hiramatsu /* Only indirect jmp is boostable */
1876256e668SMasami Hiramatsu return X86_MODRM_REG(insn->modrm.bytes[0]) == 4;
188f684199fSMasami Hiramatsu default:
1892f706e0eSMasami Hiramatsu return 1;
190f684199fSMasami Hiramatsu }
191f684199fSMasami Hiramatsu }
192f684199fSMasami Hiramatsu
193f684199fSMasami Hiramatsu static unsigned long
__recover_probed_insn(kprobe_opcode_t * buf,unsigned long addr)194f684199fSMasami Hiramatsu __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
195f684199fSMasami Hiramatsu {
196f684199fSMasami Hiramatsu struct kprobe *kp;
197aebfd125SPeter Zijlstra bool faddr;
198f684199fSMasami Hiramatsu
199f684199fSMasami Hiramatsu kp = get_kprobe((void *)addr);
200aebfd125SPeter Zijlstra faddr = ftrace_location(addr) == addr;
2012a6730c8SPetr Mladek /*
202650b7b23SPetr Mladek * Use the current code if it is not modified by Kprobe
203650b7b23SPetr Mladek * and it cannot be modified by ftrace.
204650b7b23SPetr Mladek */
205650b7b23SPetr Mladek if (!kp && !faddr)
206f684199fSMasami Hiramatsu return addr;
207f684199fSMasami Hiramatsu
208f684199fSMasami Hiramatsu /*
209f684199fSMasami Hiramatsu * Basically, kp->ainsn.insn has an original instruction.
210f684199fSMasami Hiramatsu * However, RIP-relative instruction can not do single-stepping
211f684199fSMasami Hiramatsu * at different place, __copy_instruction() tweaks the displacement of
212f684199fSMasami Hiramatsu * that instruction. In that case, we can't recover the instruction
213f684199fSMasami Hiramatsu * from the kp->ainsn.insn.
214f684199fSMasami Hiramatsu *
215650b7b23SPetr Mladek * On the other hand, in case on normal Kprobe, kp->opcode has a copy
216650b7b23SPetr Mladek * of the first byte of the probed instruction, which is overwritten
217650b7b23SPetr Mladek * by int3. And the instruction at kp->addr is not modified by kprobes
218650b7b23SPetr Mladek * except for the first byte, we can recover the original instruction
219f684199fSMasami Hiramatsu * from it and kp->opcode.
220650b7b23SPetr Mladek *
221650b7b23SPetr Mladek * In case of Kprobes using ftrace, we do not have a copy of
222650b7b23SPetr Mladek * the original instruction. In fact, the ftrace location might
223650b7b23SPetr Mladek * be modified at anytime and even could be in an inconsistent state.
224650b7b23SPetr Mladek * Fortunately, we know that the original code is the ideal 5-byte
225650b7b23SPetr Mladek * long NOP.
226f684199fSMasami Hiramatsu */
227fe557319SChristoph Hellwig if (copy_from_kernel_nofault(buf, (void *)addr,
228ea1e34fcSMasami Hiramatsu MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
229ea1e34fcSMasami Hiramatsu return 0UL;
230ea1e34fcSMasami Hiramatsu
231650b7b23SPetr Mladek if (faddr)
232a89dfde3SPeter Zijlstra memcpy(buf, x86_nops[5], 5);
233650b7b23SPetr Mladek else
234f684199fSMasami Hiramatsu buf[0] = kp->opcode;
235f684199fSMasami Hiramatsu return (unsigned long)buf;
236f684199fSMasami Hiramatsu }
237f684199fSMasami Hiramatsu
238f684199fSMasami Hiramatsu /*
239f684199fSMasami Hiramatsu * Recover the probed instruction at addr for further analysis.
240f684199fSMasami Hiramatsu * Caller must lock kprobes by kprobe_mutex, or disable preemption
241f684199fSMasami Hiramatsu * for preventing to release referencing kprobes.
242ea1e34fcSMasami Hiramatsu * Returns zero if the instruction can not get recovered (or access failed).
243f684199fSMasami Hiramatsu */
recover_probed_instruction(kprobe_opcode_t * buf,unsigned long addr)244f684199fSMasami Hiramatsu unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr)
245f684199fSMasami Hiramatsu {
246f684199fSMasami Hiramatsu unsigned long __addr;
247f684199fSMasami Hiramatsu
248f684199fSMasami Hiramatsu __addr = __recover_optprobed_insn(buf, addr);
249f684199fSMasami Hiramatsu if (__addr != addr)
250f684199fSMasami Hiramatsu return __addr;
251f684199fSMasami Hiramatsu
252f684199fSMasami Hiramatsu return __recover_probed_insn(buf, addr);
253f684199fSMasami Hiramatsu }
254f684199fSMasami Hiramatsu
255f684199fSMasami Hiramatsu /* Check if paddr is at an instruction boundary */
can_probe(unsigned long paddr)2567ec8a97aSMasami Hiramatsu static int can_probe(unsigned long paddr)
257f684199fSMasami Hiramatsu {
258f684199fSMasami Hiramatsu unsigned long addr, __addr, offset = 0;
259f684199fSMasami Hiramatsu struct insn insn;
260f684199fSMasami Hiramatsu kprobe_opcode_t buf[MAX_INSN_SIZE];
261f684199fSMasami Hiramatsu
262f684199fSMasami Hiramatsu if (!kallsyms_lookup_size_offset(paddr, NULL, &offset))
263f684199fSMasami Hiramatsu return 0;
264f684199fSMasami Hiramatsu
265f684199fSMasami Hiramatsu /* Decode instructions */
266f684199fSMasami Hiramatsu addr = paddr - offset;
267f684199fSMasami Hiramatsu while (addr < paddr) {
26877e768ecSBorislav Petkov int ret;
26977e768ecSBorislav Petkov
270f684199fSMasami Hiramatsu /*
271f684199fSMasami Hiramatsu * Check if the instruction has been modified by another
272f684199fSMasami Hiramatsu * kprobe, in which case we replace the breakpoint by the
273f684199fSMasami Hiramatsu * original instruction in our buffer.
274f684199fSMasami Hiramatsu * Also, jump optimization will change the breakpoint to
275f684199fSMasami Hiramatsu * relative-jump. Since the relative-jump itself is
276f684199fSMasami Hiramatsu * normally used, we just go through if there is no kprobe.
277f684199fSMasami Hiramatsu */
278f684199fSMasami Hiramatsu __addr = recover_probed_instruction(buf, addr);
2792a6730c8SPetr Mladek if (!__addr)
2802a6730c8SPetr Mladek return 0;
28177e768ecSBorislav Petkov
28252fa82c2SPeter Zijlstra ret = insn_decode_kernel(&insn, (void *)__addr);
28377e768ecSBorislav Petkov if (ret < 0)
28477e768ecSBorislav Petkov return 0;
285f684199fSMasami Hiramatsu
2861993bf97SMasami Hiramatsu (Google) #ifdef CONFIG_KGDB
287f684199fSMasami Hiramatsu /*
2881993bf97SMasami Hiramatsu (Google) * If there is a dynamically installed kgdb sw breakpoint,
2891993bf97SMasami Hiramatsu (Google) * this function should not be probed.
290f684199fSMasami Hiramatsu */
2911993bf97SMasami Hiramatsu (Google) if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
2921993bf97SMasami Hiramatsu (Google) kgdb_has_hit_break(addr))
293f684199fSMasami Hiramatsu return 0;
2941993bf97SMasami Hiramatsu (Google) #endif
295f684199fSMasami Hiramatsu addr += insn.length;
296f684199fSMasami Hiramatsu }
297b6541376SMasami Hiramatsu if (IS_ENABLED(CONFIG_CFI_CLANG)) {
298b6541376SMasami Hiramatsu /*
299b6541376SMasami Hiramatsu * The compiler generates the following instruction sequence
300b6541376SMasami Hiramatsu * for indirect call checks and cfi.c decodes this;
301b6541376SMasami Hiramatsu *
302b6541376SMasami Hiramatsu * movl -<id>, %r10d ; 6 bytes
303b6541376SMasami Hiramatsu * addl -4(%reg), %r10d ; 4 bytes
304b6541376SMasami Hiramatsu * je .Ltmp1 ; 2 bytes
305b6541376SMasami Hiramatsu * ud2 ; <- regs->ip
306b6541376SMasami Hiramatsu * .Ltmp1:
307b6541376SMasami Hiramatsu *
308b6541376SMasami Hiramatsu * Also, these movl and addl are used for showing expected
309b6541376SMasami Hiramatsu * type. So those must not be touched.
310b6541376SMasami Hiramatsu */
311b6541376SMasami Hiramatsu __addr = recover_probed_instruction(buf, addr);
312b6541376SMasami Hiramatsu if (!__addr)
313b6541376SMasami Hiramatsu return 0;
314f684199fSMasami Hiramatsu
315b6541376SMasami Hiramatsu if (insn_decode_kernel(&insn, (void *)__addr) < 0)
316b6541376SMasami Hiramatsu return 0;
317b6541376SMasami Hiramatsu
318b6541376SMasami Hiramatsu if (insn.opcode.value == 0xBA)
319b6541376SMasami Hiramatsu offset = 12;
320b6541376SMasami Hiramatsu else if (insn.opcode.value == 0x3)
321b6541376SMasami Hiramatsu offset = 6;
322b6541376SMasami Hiramatsu else
323b6541376SMasami Hiramatsu goto out;
324b6541376SMasami Hiramatsu
325b6541376SMasami Hiramatsu /* This movl/addl is used for decoding CFI. */
326b6541376SMasami Hiramatsu if (is_cfi_trap(addr + offset))
327b6541376SMasami Hiramatsu return 0;
328b6541376SMasami Hiramatsu }
329b6541376SMasami Hiramatsu
330b6541376SMasami Hiramatsu out:
331f684199fSMasami Hiramatsu return (addr == paddr);
332f684199fSMasami Hiramatsu }
333f684199fSMasami Hiramatsu
334cc66bb91SPeter Zijlstra /* If x86 supports IBT (ENDBR) it must be skipped. */
arch_adjust_kprobe_addr(unsigned long addr,unsigned long offset,bool * on_func_entry)335cc66bb91SPeter Zijlstra kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offset,
336cc66bb91SPeter Zijlstra bool *on_func_entry)
337cc66bb91SPeter Zijlstra {
338*f13edd18SMasami Hiramatsu (Google) u32 insn;
339*f13edd18SMasami Hiramatsu (Google)
340*f13edd18SMasami Hiramatsu (Google) /*
341*f13edd18SMasami Hiramatsu (Google) * Since 'addr' is not guaranteed to be safe to access, use
342*f13edd18SMasami Hiramatsu (Google) * copy_from_kernel_nofault() to read the instruction:
343*f13edd18SMasami Hiramatsu (Google) */
344*f13edd18SMasami Hiramatsu (Google) if (copy_from_kernel_nofault(&insn, (void *)addr, sizeof(u32)))
345*f13edd18SMasami Hiramatsu (Google) return NULL;
346*f13edd18SMasami Hiramatsu (Google)
347*f13edd18SMasami Hiramatsu (Google) if (is_endbr(insn)) {
348cc66bb91SPeter Zijlstra *on_func_entry = !offset || offset == 4;
349cc66bb91SPeter Zijlstra if (*on_func_entry)
350cc66bb91SPeter Zijlstra offset = 4;
351cc66bb91SPeter Zijlstra
352cc66bb91SPeter Zijlstra } else {
353cc66bb91SPeter Zijlstra *on_func_entry = !offset;
354cc66bb91SPeter Zijlstra }
355cc66bb91SPeter Zijlstra
356cc66bb91SPeter Zijlstra return (kprobe_opcode_t *)(addr + offset);
357cc66bb91SPeter Zijlstra }
358cc66bb91SPeter Zijlstra
359f684199fSMasami Hiramatsu /*
360129d17e8SMasami Hiramatsu * Copy an instruction with recovering modified instruction by kprobes
361129d17e8SMasami Hiramatsu * and adjust the displacement if the instruction uses the %rip-relative
36263fef14fSMasami Hiramatsu * addressing mode. Note that since @real will be the final place of copied
36363fef14fSMasami Hiramatsu * instruction, displacement must be adjust by @real, not @dest.
364129d17e8SMasami Hiramatsu * This returns the length of copied instruction, or 0 if it has an error.
365f684199fSMasami Hiramatsu */
__copy_instruction(u8 * dest,u8 * src,u8 * real,struct insn * insn)36663fef14fSMasami Hiramatsu int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
367f684199fSMasami Hiramatsu {
368f684199fSMasami Hiramatsu kprobe_opcode_t buf[MAX_INSN_SIZE];
36977e768ecSBorislav Petkov unsigned long recovered_insn = recover_probed_instruction(buf, (unsigned long)src);
37077e768ecSBorislav Petkov int ret;
371f684199fSMasami Hiramatsu
372a8d11cd0SMasami Hiramatsu if (!recovered_insn || !insn)
373f684199fSMasami Hiramatsu return 0;
374ea1e34fcSMasami Hiramatsu
375ea1e34fcSMasami Hiramatsu /* This can access kernel text if given address is not recovered */
376fe557319SChristoph Hellwig if (copy_from_kernel_nofault(dest, (void *)recovered_insn,
377fe557319SChristoph Hellwig MAX_INSN_SIZE))
378a8d11cd0SMasami Hiramatsu return 0;
379a8d11cd0SMasami Hiramatsu
38052fa82c2SPeter Zijlstra ret = insn_decode_kernel(insn, dest);
38177e768ecSBorislav Petkov if (ret < 0)
38277e768ecSBorislav Petkov return 0;
383a8d11cd0SMasami Hiramatsu
384004e8dceSMasami Hiramatsu /* We can not probe force emulate prefixed instruction */
385004e8dceSMasami Hiramatsu if (insn_has_emulate_prefix(insn))
386004e8dceSMasami Hiramatsu return 0;
387004e8dceSMasami Hiramatsu
388a8d11cd0SMasami Hiramatsu /* Another subsystem puts a breakpoint, failed to recover */
389ab09e95cSPeter Zijlstra if (insn->opcode.bytes[0] == INT3_INSN_OPCODE)
390ea1e34fcSMasami Hiramatsu return 0;
391f684199fSMasami Hiramatsu
392ee6a7354SMasami Hiramatsu /* We should not singlestep on the exception masking instructions */
393ee6a7354SMasami Hiramatsu if (insn_masking_exception(insn))
394ee6a7354SMasami Hiramatsu return 0;
395ee6a7354SMasami Hiramatsu
396f684199fSMasami Hiramatsu #ifdef CONFIG_X86_64
397129d17e8SMasami Hiramatsu /* Only x86_64 has RIP relative instructions */
398a8d11cd0SMasami Hiramatsu if (insn_rip_relative(insn)) {
399f684199fSMasami Hiramatsu s64 newdisp;
400f684199fSMasami Hiramatsu u8 *disp;
401f684199fSMasami Hiramatsu /*
402f684199fSMasami Hiramatsu * The copied instruction uses the %rip-relative addressing
403f684199fSMasami Hiramatsu * mode. Adjust the displacement for the difference between
404f684199fSMasami Hiramatsu * the original location of this instruction and the location
405f684199fSMasami Hiramatsu * of the copy that will actually be run. The tricky bit here
406f684199fSMasami Hiramatsu * is making sure that the sign extension happens correctly in
407f684199fSMasami Hiramatsu * this calculation, since we need a signed 32-bit result to
408f684199fSMasami Hiramatsu * be sign-extended to 64 bits when it's added to the %rip
409f684199fSMasami Hiramatsu * value and yield the same 64-bit result that the sign-
410f684199fSMasami Hiramatsu * extension of the original signed 32-bit displacement would
411f684199fSMasami Hiramatsu * have given.
412f684199fSMasami Hiramatsu */
413a8d11cd0SMasami Hiramatsu newdisp = (u8 *) src + (s64) insn->displacement.value
41463fef14fSMasami Hiramatsu - (u8 *) real;
4158101376dSMasami Hiramatsu if ((s64) (s32) newdisp != newdisp) {
4168101376dSMasami Hiramatsu pr_err("Kprobes error: new displacement does not fit into s32 (%llx)\n", newdisp);
4178101376dSMasami Hiramatsu return 0;
4188101376dSMasami Hiramatsu }
419a8d11cd0SMasami Hiramatsu disp = (u8 *) dest + insn_offset_displacement(insn);
420f684199fSMasami Hiramatsu *(s32 *) disp = (s32) newdisp;
421f684199fSMasami Hiramatsu }
422f684199fSMasami Hiramatsu #endif
423a8d11cd0SMasami Hiramatsu return insn->length;
424f684199fSMasami Hiramatsu }
425f684199fSMasami Hiramatsu
4266256e668SMasami Hiramatsu /* Prepare reljump or int3 right after instruction */
prepare_singlestep(kprobe_opcode_t * buf,struct kprobe * p,struct insn * insn)4276256e668SMasami Hiramatsu static int prepare_singlestep(kprobe_opcode_t *buf, struct kprobe *p,
42863fef14fSMasami Hiramatsu struct insn *insn)
429804dec5bSMasami Hiramatsu {
43063fef14fSMasami Hiramatsu int len = insn->length;
43163fef14fSMasami Hiramatsu
4326256e668SMasami Hiramatsu if (!IS_ENABLED(CONFIG_PREEMPTION) &&
4336256e668SMasami Hiramatsu !p->post_handler && can_boost(insn, p->addr) &&
434ab09e95cSPeter Zijlstra MAX_INSN_SIZE - len >= JMP32_INSN_SIZE) {
435804dec5bSMasami Hiramatsu /*
436804dec5bSMasami Hiramatsu * These instructions can be executed directly if it
437804dec5bSMasami Hiramatsu * jumps back to correct address.
438804dec5bSMasami Hiramatsu */
43963fef14fSMasami Hiramatsu synthesize_reljump(buf + len, p->ainsn.insn + len,
440a8d11cd0SMasami Hiramatsu p->addr + insn->length);
441ab09e95cSPeter Zijlstra len += JMP32_INSN_SIZE;
442abd82e53SMasami Hiramatsu p->ainsn.boostable = 1;
443804dec5bSMasami Hiramatsu } else {
4446256e668SMasami Hiramatsu /* Otherwise, put an int3 for trapping singlestep */
4456256e668SMasami Hiramatsu if (MAX_INSN_SIZE - len < INT3_INSN_SIZE)
4466256e668SMasami Hiramatsu return -ENOSPC;
4476256e668SMasami Hiramatsu
4486256e668SMasami Hiramatsu buf[len] = INT3_INSN_OPCODE;
4496256e668SMasami Hiramatsu len += INT3_INSN_SIZE;
450804dec5bSMasami Hiramatsu }
45163fef14fSMasami Hiramatsu
45263fef14fSMasami Hiramatsu return len;
45363fef14fSMasami Hiramatsu }
45463fef14fSMasami Hiramatsu
45563fef14fSMasami Hiramatsu /* Make page to RO mode when allocate it */
alloc_insn_page(void)45663fef14fSMasami Hiramatsu void *alloc_insn_page(void)
45763fef14fSMasami Hiramatsu {
45863fef14fSMasami Hiramatsu void *page;
45963fef14fSMasami Hiramatsu
46063fef14fSMasami Hiramatsu page = module_alloc(PAGE_SIZE);
4617298e24fSNadav Amit if (!page)
4627298e24fSNadav Amit return NULL;
4637298e24fSNadav Amit
4647298e24fSNadav Amit /*
4657298e24fSNadav Amit * TODO: Once additional kernel code protection mechanisms are set, ensure
4667298e24fSNadav Amit * that the page was not maliciously altered and it is still zeroed.
4677298e24fSNadav Amit */
468d48567c9SPeter Zijlstra set_memory_rox((unsigned long)page, 1);
46963fef14fSMasami Hiramatsu
47063fef14fSMasami Hiramatsu return page;
471804dec5bSMasami Hiramatsu }
472804dec5bSMasami Hiramatsu
4736256e668SMasami Hiramatsu /* Kprobe x86 instruction emulation - only regs->ip or IF flag modifiers */
4746256e668SMasami Hiramatsu
kprobe_emulate_ifmodifiers(struct kprobe * p,struct pt_regs * regs)4756256e668SMasami Hiramatsu static void kprobe_emulate_ifmodifiers(struct kprobe *p, struct pt_regs *regs)
4766256e668SMasami Hiramatsu {
4776256e668SMasami Hiramatsu switch (p->ainsn.opcode) {
4786256e668SMasami Hiramatsu case 0xfa: /* cli */
4796256e668SMasami Hiramatsu regs->flags &= ~(X86_EFLAGS_IF);
4806256e668SMasami Hiramatsu break;
4816256e668SMasami Hiramatsu case 0xfb: /* sti */
4826256e668SMasami Hiramatsu regs->flags |= X86_EFLAGS_IF;
4836256e668SMasami Hiramatsu break;
4846256e668SMasami Hiramatsu case 0x9c: /* pushf */
4856256e668SMasami Hiramatsu int3_emulate_push(regs, regs->flags);
4866256e668SMasami Hiramatsu break;
4876256e668SMasami Hiramatsu case 0x9d: /* popf */
4886256e668SMasami Hiramatsu regs->flags = int3_emulate_pop(regs);
4896256e668SMasami Hiramatsu break;
4906256e668SMasami Hiramatsu }
4916256e668SMasami Hiramatsu regs->ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
4926256e668SMasami Hiramatsu }
4936256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_emulate_ifmodifiers);
4946256e668SMasami Hiramatsu
kprobe_emulate_ret(struct kprobe * p,struct pt_regs * regs)4956256e668SMasami Hiramatsu static void kprobe_emulate_ret(struct kprobe *p, struct pt_regs *regs)
4966256e668SMasami Hiramatsu {
4976256e668SMasami Hiramatsu int3_emulate_ret(regs);
4986256e668SMasami Hiramatsu }
4996256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_emulate_ret);
5006256e668SMasami Hiramatsu
kprobe_emulate_call(struct kprobe * p,struct pt_regs * regs)5016256e668SMasami Hiramatsu static void kprobe_emulate_call(struct kprobe *p, struct pt_regs *regs)
5026256e668SMasami Hiramatsu {
5036256e668SMasami Hiramatsu unsigned long func = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
5046256e668SMasami Hiramatsu
5056256e668SMasami Hiramatsu func += p->ainsn.rel32;
5066256e668SMasami Hiramatsu int3_emulate_call(regs, func);
5076256e668SMasami Hiramatsu }
5086256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_emulate_call);
5096256e668SMasami Hiramatsu
kprobe_emulate_jmp(struct kprobe * p,struct pt_regs * regs)510db7adcfdSPeter Zijlstra static void kprobe_emulate_jmp(struct kprobe *p, struct pt_regs *regs)
5116256e668SMasami Hiramatsu {
5126256e668SMasami Hiramatsu unsigned long ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
5136256e668SMasami Hiramatsu
5146256e668SMasami Hiramatsu ip += p->ainsn.rel32;
5156256e668SMasami Hiramatsu int3_emulate_jmp(regs, ip);
5166256e668SMasami Hiramatsu }
5176256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_emulate_jmp);
5186256e668SMasami Hiramatsu
kprobe_emulate_jcc(struct kprobe * p,struct pt_regs * regs)5196256e668SMasami Hiramatsu static void kprobe_emulate_jcc(struct kprobe *p, struct pt_regs *regs)
5206256e668SMasami Hiramatsu {
521db7adcfdSPeter Zijlstra unsigned long ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
5226256e668SMasami Hiramatsu
523db7adcfdSPeter Zijlstra int3_emulate_jcc(regs, p->ainsn.jcc.type, ip, p->ainsn.rel32);
5246256e668SMasami Hiramatsu }
5256256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_emulate_jcc);
5266256e668SMasami Hiramatsu
kprobe_emulate_loop(struct kprobe * p,struct pt_regs * regs)5276256e668SMasami Hiramatsu static void kprobe_emulate_loop(struct kprobe *p, struct pt_regs *regs)
5286256e668SMasami Hiramatsu {
529db7adcfdSPeter Zijlstra unsigned long ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size;
5306256e668SMasami Hiramatsu bool match;
5316256e668SMasami Hiramatsu
5326256e668SMasami Hiramatsu if (p->ainsn.loop.type != 3) { /* LOOP* */
5336256e668SMasami Hiramatsu if (p->ainsn.loop.asize == 32)
5346256e668SMasami Hiramatsu match = ((*(u32 *)®s->cx)--) != 0;
5356256e668SMasami Hiramatsu #ifdef CONFIG_X86_64
5366256e668SMasami Hiramatsu else if (p->ainsn.loop.asize == 64)
5376256e668SMasami Hiramatsu match = ((*(u64 *)®s->cx)--) != 0;
5386256e668SMasami Hiramatsu #endif
5396256e668SMasami Hiramatsu else
5406256e668SMasami Hiramatsu match = ((*(u16 *)®s->cx)--) != 0;
5416256e668SMasami Hiramatsu } else { /* JCXZ */
5426256e668SMasami Hiramatsu if (p->ainsn.loop.asize == 32)
5436256e668SMasami Hiramatsu match = *(u32 *)(®s->cx) == 0;
5446256e668SMasami Hiramatsu #ifdef CONFIG_X86_64
5456256e668SMasami Hiramatsu else if (p->ainsn.loop.asize == 64)
5466256e668SMasami Hiramatsu match = *(u64 *)(®s->cx) == 0;
5476256e668SMasami Hiramatsu #endif
5486256e668SMasami Hiramatsu else
5496256e668SMasami Hiramatsu match = *(u16 *)(®s->cx) == 0;
5506256e668SMasami Hiramatsu }
5516256e668SMasami Hiramatsu
5526256e668SMasami Hiramatsu if (p->ainsn.loop.type == 0) /* LOOPNE */
5536256e668SMasami Hiramatsu match = match && !(regs->flags & X86_EFLAGS_ZF);
5546256e668SMasami Hiramatsu else if (p->ainsn.loop.type == 1) /* LOOPE */
5556256e668SMasami Hiramatsu match = match && (regs->flags & X86_EFLAGS_ZF);
5566256e668SMasami Hiramatsu
557db7adcfdSPeter Zijlstra if (match)
558db7adcfdSPeter Zijlstra ip += p->ainsn.rel32;
559db7adcfdSPeter Zijlstra int3_emulate_jmp(regs, ip);
5606256e668SMasami Hiramatsu }
5616256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_emulate_loop);
5626256e668SMasami Hiramatsu
5636256e668SMasami Hiramatsu static const int addrmode_regoffs[] = {
5646256e668SMasami Hiramatsu offsetof(struct pt_regs, ax),
5656256e668SMasami Hiramatsu offsetof(struct pt_regs, cx),
5666256e668SMasami Hiramatsu offsetof(struct pt_regs, dx),
5676256e668SMasami Hiramatsu offsetof(struct pt_regs, bx),
5686256e668SMasami Hiramatsu offsetof(struct pt_regs, sp),
5696256e668SMasami Hiramatsu offsetof(struct pt_regs, bp),
5706256e668SMasami Hiramatsu offsetof(struct pt_regs, si),
5716256e668SMasami Hiramatsu offsetof(struct pt_regs, di),
5726256e668SMasami Hiramatsu #ifdef CONFIG_X86_64
5736256e668SMasami Hiramatsu offsetof(struct pt_regs, r8),
5746256e668SMasami Hiramatsu offsetof(struct pt_regs, r9),
5756256e668SMasami Hiramatsu offsetof(struct pt_regs, r10),
5766256e668SMasami Hiramatsu offsetof(struct pt_regs, r11),
5776256e668SMasami Hiramatsu offsetof(struct pt_regs, r12),
5786256e668SMasami Hiramatsu offsetof(struct pt_regs, r13),
5796256e668SMasami Hiramatsu offsetof(struct pt_regs, r14),
5806256e668SMasami Hiramatsu offsetof(struct pt_regs, r15),
5816256e668SMasami Hiramatsu #endif
5826256e668SMasami Hiramatsu };
5836256e668SMasami Hiramatsu
kprobe_emulate_call_indirect(struct kprobe * p,struct pt_regs * regs)5846256e668SMasami Hiramatsu static void kprobe_emulate_call_indirect(struct kprobe *p, struct pt_regs *regs)
5856256e668SMasami Hiramatsu {
5866256e668SMasami Hiramatsu unsigned long offs = addrmode_regoffs[p->ainsn.indirect.reg];
5876256e668SMasami Hiramatsu
588dfb8a426SJinghao Jia int3_emulate_push(regs, regs->ip - INT3_INSN_SIZE + p->ainsn.size);
589dfb8a426SJinghao Jia int3_emulate_jmp(regs, regs_get_register(regs, offs));
5906256e668SMasami Hiramatsu }
5916256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_emulate_call_indirect);
5926256e668SMasami Hiramatsu
kprobe_emulate_jmp_indirect(struct kprobe * p,struct pt_regs * regs)5936256e668SMasami Hiramatsu static void kprobe_emulate_jmp_indirect(struct kprobe *p, struct pt_regs *regs)
5946256e668SMasami Hiramatsu {
5956256e668SMasami Hiramatsu unsigned long offs = addrmode_regoffs[p->ainsn.indirect.reg];
5966256e668SMasami Hiramatsu
5976256e668SMasami Hiramatsu int3_emulate_jmp(regs, regs_get_register(regs, offs));
5986256e668SMasami Hiramatsu }
5996256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_emulate_jmp_indirect);
6006256e668SMasami Hiramatsu
prepare_emulation(struct kprobe * p,struct insn * insn)6016256e668SMasami Hiramatsu static int prepare_emulation(struct kprobe *p, struct insn *insn)
602abd82e53SMasami Hiramatsu {
603abd82e53SMasami Hiramatsu insn_byte_t opcode = insn->opcode.bytes[0];
604abd82e53SMasami Hiramatsu
605abd82e53SMasami Hiramatsu switch (opcode) {
606abd82e53SMasami Hiramatsu case 0xfa: /* cli */
607abd82e53SMasami Hiramatsu case 0xfb: /* sti */
608abd82e53SMasami Hiramatsu case 0x9c: /* pushfl */
6096256e668SMasami Hiramatsu case 0x9d: /* popf/popfd */
6106256e668SMasami Hiramatsu /*
6116256e668SMasami Hiramatsu * IF modifiers must be emulated since it will enable interrupt while
6126256e668SMasami Hiramatsu * int3 single stepping.
6136256e668SMasami Hiramatsu */
6146256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_ifmodifiers;
6156256e668SMasami Hiramatsu p->ainsn.opcode = opcode;
616abd82e53SMasami Hiramatsu break;
617abd82e53SMasami Hiramatsu case 0xc2: /* ret/lret */
618abd82e53SMasami Hiramatsu case 0xc3:
619abd82e53SMasami Hiramatsu case 0xca:
620abd82e53SMasami Hiramatsu case 0xcb:
6216256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_ret;
622abd82e53SMasami Hiramatsu break;
6236256e668SMasami Hiramatsu case 0x9a: /* far call absolute -- segment is not supported */
6246256e668SMasami Hiramatsu case 0xea: /* far jmp absolute -- segment is not supported */
6256256e668SMasami Hiramatsu case 0xcc: /* int3 */
6266256e668SMasami Hiramatsu case 0xcf: /* iret -- in-kernel IRET is not supported */
6276256e668SMasami Hiramatsu return -EOPNOTSUPP;
628abd82e53SMasami Hiramatsu break;
6296256e668SMasami Hiramatsu case 0xe8: /* near call relative */
6306256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_call;
6316256e668SMasami Hiramatsu if (insn->immediate.nbytes == 2)
6326256e668SMasami Hiramatsu p->ainsn.rel32 = *(s16 *)&insn->immediate.value;
6336256e668SMasami Hiramatsu else
6346256e668SMasami Hiramatsu p->ainsn.rel32 = *(s32 *)&insn->immediate.value;
635abd82e53SMasami Hiramatsu break;
6366256e668SMasami Hiramatsu case 0xeb: /* short jump relative */
6376256e668SMasami Hiramatsu case 0xe9: /* near jump relative */
6386256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_jmp;
6396256e668SMasami Hiramatsu if (insn->immediate.nbytes == 1)
6406256e668SMasami Hiramatsu p->ainsn.rel32 = *(s8 *)&insn->immediate.value;
6416256e668SMasami Hiramatsu else if (insn->immediate.nbytes == 2)
6426256e668SMasami Hiramatsu p->ainsn.rel32 = *(s16 *)&insn->immediate.value;
6436256e668SMasami Hiramatsu else
6446256e668SMasami Hiramatsu p->ainsn.rel32 = *(s32 *)&insn->immediate.value;
6456256e668SMasami Hiramatsu break;
6466256e668SMasami Hiramatsu case 0x70 ... 0x7f:
6476256e668SMasami Hiramatsu /* 1 byte conditional jump */
6486256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_jcc;
6496256e668SMasami Hiramatsu p->ainsn.jcc.type = opcode & 0xf;
650ae052e3aSNadav Amit p->ainsn.rel32 = insn->immediate.value;
6516256e668SMasami Hiramatsu break;
6526256e668SMasami Hiramatsu case 0x0f:
6536256e668SMasami Hiramatsu opcode = insn->opcode.bytes[1];
6546256e668SMasami Hiramatsu if ((opcode & 0xf0) == 0x80) {
6556256e668SMasami Hiramatsu /* 2 bytes Conditional Jump */
6566256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_jcc;
6576256e668SMasami Hiramatsu p->ainsn.jcc.type = opcode & 0xf;
6586256e668SMasami Hiramatsu if (insn->immediate.nbytes == 2)
6596256e668SMasami Hiramatsu p->ainsn.rel32 = *(s16 *)&insn->immediate.value;
6606256e668SMasami Hiramatsu else
6616256e668SMasami Hiramatsu p->ainsn.rel32 = *(s32 *)&insn->immediate.value;
6626256e668SMasami Hiramatsu } else if (opcode == 0x01 &&
6636256e668SMasami Hiramatsu X86_MODRM_REG(insn->modrm.bytes[0]) == 0 &&
6646256e668SMasami Hiramatsu X86_MODRM_MOD(insn->modrm.bytes[0]) == 3) {
6656256e668SMasami Hiramatsu /* VM extensions - not supported */
6666256e668SMasami Hiramatsu return -EOPNOTSUPP;
6676256e668SMasami Hiramatsu }
6686256e668SMasami Hiramatsu break;
6696256e668SMasami Hiramatsu case 0xe0: /* Loop NZ */
6706256e668SMasami Hiramatsu case 0xe1: /* Loop */
6716256e668SMasami Hiramatsu case 0xe2: /* Loop */
6726256e668SMasami Hiramatsu case 0xe3: /* J*CXZ */
6736256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_loop;
6746256e668SMasami Hiramatsu p->ainsn.loop.type = opcode & 0x3;
6756256e668SMasami Hiramatsu p->ainsn.loop.asize = insn->addr_bytes * 8;
6766256e668SMasami Hiramatsu p->ainsn.rel32 = *(s8 *)&insn->immediate.value;
6776256e668SMasami Hiramatsu break;
678abd82e53SMasami Hiramatsu case 0xff:
679d60ad3d4SMasami Hiramatsu /*
680d60ad3d4SMasami Hiramatsu * Since the 0xff is an extended group opcode, the instruction
681d60ad3d4SMasami Hiramatsu * is determined by the MOD/RM byte.
682d60ad3d4SMasami Hiramatsu */
683d60ad3d4SMasami Hiramatsu opcode = insn->modrm.bytes[0];
6849fcad995SChuang Wang switch (X86_MODRM_REG(opcode)) {
6859fcad995SChuang Wang case 0b010: /* FF /2, call near, absolute indirect */
6866256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_call_indirect;
6879fcad995SChuang Wang break;
6889fcad995SChuang Wang case 0b100: /* FF /4, jmp near, absolute indirect */
6896256e668SMasami Hiramatsu p->ainsn.emulate_op = kprobe_emulate_jmp_indirect;
6909fcad995SChuang Wang break;
6919fcad995SChuang Wang case 0b011: /* FF /3, call far, absolute indirect */
6929fcad995SChuang Wang case 0b101: /* FF /5, jmp far, absolute indirect */
6939fcad995SChuang Wang return -EOPNOTSUPP;
6949fcad995SChuang Wang }
6959fcad995SChuang Wang
6969fcad995SChuang Wang if (!p->ainsn.emulate_op)
6976256e668SMasami Hiramatsu break;
6986256e668SMasami Hiramatsu
6996256e668SMasami Hiramatsu if (insn->addr_bytes != sizeof(unsigned long))
700c4342633SIngo Molnar return -EOPNOTSUPP; /* Don't support different size */
7016256e668SMasami Hiramatsu if (X86_MODRM_MOD(opcode) != 3)
7026256e668SMasami Hiramatsu return -EOPNOTSUPP; /* TODO: support memory addressing */
7036256e668SMasami Hiramatsu
7046256e668SMasami Hiramatsu p->ainsn.indirect.reg = X86_MODRM_RM(opcode);
7056256e668SMasami Hiramatsu #ifdef CONFIG_X86_64
7066256e668SMasami Hiramatsu if (X86_REX_B(insn->rex_prefix.value))
7076256e668SMasami Hiramatsu p->ainsn.indirect.reg += 8;
7086256e668SMasami Hiramatsu #endif
7096256e668SMasami Hiramatsu break;
7106256e668SMasami Hiramatsu default:
711abd82e53SMasami Hiramatsu break;
712abd82e53SMasami Hiramatsu }
7136256e668SMasami Hiramatsu p->ainsn.size = insn->length;
7146256e668SMasami Hiramatsu
7156256e668SMasami Hiramatsu return 0;
716abd82e53SMasami Hiramatsu }
717abd82e53SMasami Hiramatsu
arch_copy_kprobe(struct kprobe * p)7187ec8a97aSMasami Hiramatsu static int arch_copy_kprobe(struct kprobe *p)
719f684199fSMasami Hiramatsu {
720a8d11cd0SMasami Hiramatsu struct insn insn;
72163fef14fSMasami Hiramatsu kprobe_opcode_t buf[MAX_INSN_SIZE];
7226256e668SMasami Hiramatsu int ret, len;
723003002e0SMasami Hiramatsu
724f684199fSMasami Hiramatsu /* Copy an instruction with recovering if other optprobe modifies it.*/
72563fef14fSMasami Hiramatsu len = __copy_instruction(buf, p->addr, p->ainsn.insn, &insn);
726804dec5bSMasami Hiramatsu if (!len)
727003002e0SMasami Hiramatsu return -EINVAL;
728f684199fSMasami Hiramatsu
7296256e668SMasami Hiramatsu /* Analyze the opcode and setup emulate functions */
7306256e668SMasami Hiramatsu ret = prepare_emulation(p, &insn);
7316256e668SMasami Hiramatsu if (ret < 0)
7326256e668SMasami Hiramatsu return ret;
733d0381c81SMasami Hiramatsu
7346256e668SMasami Hiramatsu /* Add int3 for single-step or booster jmp */
7356256e668SMasami Hiramatsu len = prepare_singlestep(buf, p, &insn);
7366256e668SMasami Hiramatsu if (len < 0)
7376256e668SMasami Hiramatsu return len;
7389a556ab9SMasami Hiramatsu
739f684199fSMasami Hiramatsu /* Also, displacement change doesn't affect the first byte */
74063fef14fSMasami Hiramatsu p->opcode = buf[0];
74163fef14fSMasami Hiramatsu
7423e46bb40SAdrian Hunter p->ainsn.tp_len = len;
7433e46bb40SAdrian Hunter perf_event_text_poke(p->ainsn.insn, NULL, 0, buf, len);
7443e46bb40SAdrian Hunter
74563fef14fSMasami Hiramatsu /* OK, write back the instruction(s) into ROX insn buffer */
74663fef14fSMasami Hiramatsu text_poke(p->ainsn.insn, buf, len);
747003002e0SMasami Hiramatsu
748003002e0SMasami Hiramatsu return 0;
749f684199fSMasami Hiramatsu }
750f684199fSMasami Hiramatsu
arch_prepare_kprobe(struct kprobe * p)7517ec8a97aSMasami Hiramatsu int arch_prepare_kprobe(struct kprobe *p)
752f684199fSMasami Hiramatsu {
75338115f2fSMasami Hiramatsu int ret;
75438115f2fSMasami Hiramatsu
755f684199fSMasami Hiramatsu if (alternatives_text_reserved(p->addr, p->addr))
756f684199fSMasami Hiramatsu return -EINVAL;
757f684199fSMasami Hiramatsu
758f684199fSMasami Hiramatsu if (!can_probe((unsigned long)p->addr))
759f684199fSMasami Hiramatsu return -EILSEQ;
760abd82e53SMasami Hiramatsu
761abd82e53SMasami Hiramatsu memset(&p->ainsn, 0, sizeof(p->ainsn));
762abd82e53SMasami Hiramatsu
763f684199fSMasami Hiramatsu /* insn: must be on special executable page on x86. */
764f684199fSMasami Hiramatsu p->ainsn.insn = get_insn_slot();
765f684199fSMasami Hiramatsu if (!p->ainsn.insn)
766f684199fSMasami Hiramatsu return -ENOMEM;
767003002e0SMasami Hiramatsu
76838115f2fSMasami Hiramatsu ret = arch_copy_kprobe(p);
76938115f2fSMasami Hiramatsu if (ret) {
77038115f2fSMasami Hiramatsu free_insn_slot(p->ainsn.insn, 0);
77138115f2fSMasami Hiramatsu p->ainsn.insn = NULL;
77238115f2fSMasami Hiramatsu }
77338115f2fSMasami Hiramatsu
77438115f2fSMasami Hiramatsu return ret;
775f684199fSMasami Hiramatsu }
776f684199fSMasami Hiramatsu
arch_arm_kprobe(struct kprobe * p)7777ec8a97aSMasami Hiramatsu void arch_arm_kprobe(struct kprobe *p)
778f684199fSMasami Hiramatsu {
7793e46bb40SAdrian Hunter u8 int3 = INT3_INSN_OPCODE;
7803e46bb40SAdrian Hunter
7813e46bb40SAdrian Hunter text_poke(p->addr, &int3, 1);
7825c02ece8SPeter Zijlstra text_poke_sync();
7833e46bb40SAdrian Hunter perf_event_text_poke(p->addr, &p->opcode, 1, &int3, 1);
784f684199fSMasami Hiramatsu }
785f684199fSMasami Hiramatsu
arch_disarm_kprobe(struct kprobe * p)7867ec8a97aSMasami Hiramatsu void arch_disarm_kprobe(struct kprobe *p)
787f684199fSMasami Hiramatsu {
7883e46bb40SAdrian Hunter u8 int3 = INT3_INSN_OPCODE;
7893e46bb40SAdrian Hunter
7903e46bb40SAdrian Hunter perf_event_text_poke(p->addr, &int3, 1, &p->opcode, 1);
791f684199fSMasami Hiramatsu text_poke(p->addr, &p->opcode, 1);
7925c02ece8SPeter Zijlstra text_poke_sync();
793f684199fSMasami Hiramatsu }
794f684199fSMasami Hiramatsu
arch_remove_kprobe(struct kprobe * p)7957ec8a97aSMasami Hiramatsu void arch_remove_kprobe(struct kprobe *p)
796f684199fSMasami Hiramatsu {
797f684199fSMasami Hiramatsu if (p->ainsn.insn) {
7983e46bb40SAdrian Hunter /* Record the perf event before freeing the slot */
7993e46bb40SAdrian Hunter perf_event_text_poke(p->ainsn.insn, p->ainsn.insn,
8003e46bb40SAdrian Hunter p->ainsn.tp_len, NULL, 0);
801490154bcSMasami Hiramatsu free_insn_slot(p->ainsn.insn, p->ainsn.boostable);
802f684199fSMasami Hiramatsu p->ainsn.insn = NULL;
803f684199fSMasami Hiramatsu }
804f684199fSMasami Hiramatsu }
805f684199fSMasami Hiramatsu
8069326638cSMasami Hiramatsu static nokprobe_inline void
save_previous_kprobe(struct kprobe_ctlblk * kcb)8079326638cSMasami Hiramatsu save_previous_kprobe(struct kprobe_ctlblk *kcb)
808f684199fSMasami Hiramatsu {
809f684199fSMasami Hiramatsu kcb->prev_kprobe.kp = kprobe_running();
810f684199fSMasami Hiramatsu kcb->prev_kprobe.status = kcb->kprobe_status;
811f684199fSMasami Hiramatsu kcb->prev_kprobe.old_flags = kcb->kprobe_old_flags;
812f684199fSMasami Hiramatsu kcb->prev_kprobe.saved_flags = kcb->kprobe_saved_flags;
813f684199fSMasami Hiramatsu }
814f684199fSMasami Hiramatsu
8159326638cSMasami Hiramatsu static nokprobe_inline void
restore_previous_kprobe(struct kprobe_ctlblk * kcb)8169326638cSMasami Hiramatsu restore_previous_kprobe(struct kprobe_ctlblk *kcb)
817f684199fSMasami Hiramatsu {
818f684199fSMasami Hiramatsu __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
819f684199fSMasami Hiramatsu kcb->kprobe_status = kcb->prev_kprobe.status;
820f684199fSMasami Hiramatsu kcb->kprobe_old_flags = kcb->prev_kprobe.old_flags;
821f684199fSMasami Hiramatsu kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags;
822f684199fSMasami Hiramatsu }
823f684199fSMasami Hiramatsu
8249326638cSMasami Hiramatsu static nokprobe_inline void
set_current_kprobe(struct kprobe * p,struct pt_regs * regs,struct kprobe_ctlblk * kcb)8259326638cSMasami Hiramatsu set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
826f684199fSMasami Hiramatsu struct kprobe_ctlblk *kcb)
827f684199fSMasami Hiramatsu {
828f684199fSMasami Hiramatsu __this_cpu_write(current_kprobe, p);
829f684199fSMasami Hiramatsu kcb->kprobe_saved_flags = kcb->kprobe_old_flags
8306256e668SMasami Hiramatsu = (regs->flags & X86_EFLAGS_IF);
831f684199fSMasami Hiramatsu }
832f684199fSMasami Hiramatsu
kprobe_post_process(struct kprobe * cur,struct pt_regs * regs,struct kprobe_ctlblk * kcb)8336256e668SMasami Hiramatsu static void kprobe_post_process(struct kprobe *cur, struct pt_regs *regs,
8346256e668SMasami Hiramatsu struct kprobe_ctlblk *kcb)
8356256e668SMasami Hiramatsu {
8366256e668SMasami Hiramatsu /* Restore back the original saved kprobes variables and continue. */
837dec8784cSMasami Hiramatsu (Google) if (kcb->kprobe_status == KPROBE_REENTER) {
838dec8784cSMasami Hiramatsu (Google) /* This will restore both kcb and current_kprobe */
8396256e668SMasami Hiramatsu restore_previous_kprobe(kcb);
840dec8784cSMasami Hiramatsu (Google) } else {
841dec8784cSMasami Hiramatsu (Google) /*
842dec8784cSMasami Hiramatsu (Google) * Always update the kcb status because
843dec8784cSMasami Hiramatsu (Google) * reset_curent_kprobe() doesn't update kcb.
844dec8784cSMasami Hiramatsu (Google) */
845dec8784cSMasami Hiramatsu (Google) kcb->kprobe_status = KPROBE_HIT_SSDONE;
846dec8784cSMasami Hiramatsu (Google) if (cur->post_handler)
847dec8784cSMasami Hiramatsu (Google) cur->post_handler(cur, regs, 0);
8486256e668SMasami Hiramatsu reset_current_kprobe();
8496256e668SMasami Hiramatsu }
850dec8784cSMasami Hiramatsu (Google) }
8516256e668SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_post_process);
8526256e668SMasami Hiramatsu
setup_singlestep(struct kprobe * p,struct pt_regs * regs,struct kprobe_ctlblk * kcb,int reenter)8539326638cSMasami Hiramatsu static void setup_singlestep(struct kprobe *p, struct pt_regs *regs,
8549326638cSMasami Hiramatsu struct kprobe_ctlblk *kcb, int reenter)
855f684199fSMasami Hiramatsu {
856f684199fSMasami Hiramatsu if (setup_detour_execution(p, regs, reenter))
857f684199fSMasami Hiramatsu return;
858f684199fSMasami Hiramatsu
85948593975SThomas Gleixner #if !defined(CONFIG_PREEMPTION)
8606256e668SMasami Hiramatsu if (p->ainsn.boostable) {
861f684199fSMasami Hiramatsu /* Boost up -- we can execute copied instructions directly */
862f684199fSMasami Hiramatsu if (!reenter)
863f684199fSMasami Hiramatsu reset_current_kprobe();
864f684199fSMasami Hiramatsu /*
865f684199fSMasami Hiramatsu * Reentering boosted probe doesn't reset current_kprobe,
866f684199fSMasami Hiramatsu * nor set current_kprobe, because it doesn't use single
867f684199fSMasami Hiramatsu * stepping.
868f684199fSMasami Hiramatsu */
869f684199fSMasami Hiramatsu regs->ip = (unsigned long)p->ainsn.insn;
870f684199fSMasami Hiramatsu return;
871f684199fSMasami Hiramatsu }
872f684199fSMasami Hiramatsu #endif
873f684199fSMasami Hiramatsu if (reenter) {
874f684199fSMasami Hiramatsu save_previous_kprobe(kcb);
875f684199fSMasami Hiramatsu set_current_kprobe(p, regs, kcb);
876f684199fSMasami Hiramatsu kcb->kprobe_status = KPROBE_REENTER;
877f684199fSMasami Hiramatsu } else
878f684199fSMasami Hiramatsu kcb->kprobe_status = KPROBE_HIT_SS;
8796256e668SMasami Hiramatsu
8806256e668SMasami Hiramatsu if (p->ainsn.emulate_op) {
8816256e668SMasami Hiramatsu p->ainsn.emulate_op(p, regs);
8826256e668SMasami Hiramatsu kprobe_post_process(p, regs, kcb);
8836256e668SMasami Hiramatsu return;
8846256e668SMasami Hiramatsu }
8856256e668SMasami Hiramatsu
8866256e668SMasami Hiramatsu /* Disable interrupt, and set ip register on trampoline */
887f684199fSMasami Hiramatsu regs->flags &= ~X86_EFLAGS_IF;
888f684199fSMasami Hiramatsu regs->ip = (unsigned long)p->ainsn.insn;
889f684199fSMasami Hiramatsu }
8909326638cSMasami Hiramatsu NOKPROBE_SYMBOL(setup_singlestep);
891f684199fSMasami Hiramatsu
892f684199fSMasami Hiramatsu /*
8936256e668SMasami Hiramatsu * Called after single-stepping. p->addr is the address of the
8946256e668SMasami Hiramatsu * instruction whose first byte has been replaced by the "int3"
8956256e668SMasami Hiramatsu * instruction. To avoid the SMP problems that can occur when we
8966256e668SMasami Hiramatsu * temporarily put back the original opcode to single-step, we
8976256e668SMasami Hiramatsu * single-stepped a copy of the instruction. The address of this
8986256e668SMasami Hiramatsu * copy is p->ainsn.insn. We also doesn't use trap, but "int3" again
8996256e668SMasami Hiramatsu * right after the copied instruction.
9006256e668SMasami Hiramatsu * Different from the trap single-step, "int3" single-step can not
9016256e668SMasami Hiramatsu * handle the instruction which changes the ip register, e.g. jmp,
9026256e668SMasami Hiramatsu * call, conditional jmp, and the instructions which changes the IF
9036256e668SMasami Hiramatsu * flags because interrupt must be disabled around the single-stepping.
9046256e668SMasami Hiramatsu * Such instructions are software emulated, but others are single-stepped
9056256e668SMasami Hiramatsu * using "int3".
9066256e668SMasami Hiramatsu *
9076256e668SMasami Hiramatsu * When the 2nd "int3" handled, the regs->ip and regs->flags needs to
9086256e668SMasami Hiramatsu * be adjusted, so that we can resume execution on correct code.
9096256e668SMasami Hiramatsu */
resume_singlestep(struct kprobe * p,struct pt_regs * regs,struct kprobe_ctlblk * kcb)9106256e668SMasami Hiramatsu static void resume_singlestep(struct kprobe *p, struct pt_regs *regs,
9116256e668SMasami Hiramatsu struct kprobe_ctlblk *kcb)
9126256e668SMasami Hiramatsu {
9136256e668SMasami Hiramatsu unsigned long copy_ip = (unsigned long)p->ainsn.insn;
9146256e668SMasami Hiramatsu unsigned long orig_ip = (unsigned long)p->addr;
9156256e668SMasami Hiramatsu
9166256e668SMasami Hiramatsu /* Restore saved interrupt flag and ip register */
9176256e668SMasami Hiramatsu regs->flags |= kcb->kprobe_saved_flags;
9186256e668SMasami Hiramatsu /* Note that regs->ip is executed int3 so must be a step back */
9196256e668SMasami Hiramatsu regs->ip += (orig_ip - copy_ip) - INT3_INSN_SIZE;
9206256e668SMasami Hiramatsu }
9216256e668SMasami Hiramatsu NOKPROBE_SYMBOL(resume_singlestep);
9226256e668SMasami Hiramatsu
9236256e668SMasami Hiramatsu /*
924f684199fSMasami Hiramatsu * We have reentered the kprobe_handler(), since another probe was hit while
925f684199fSMasami Hiramatsu * within the handler. We save the original kprobes variables and just single
926f684199fSMasami Hiramatsu * step on the instruction of the new probe without calling any user handlers.
927f684199fSMasami Hiramatsu */
reenter_kprobe(struct kprobe * p,struct pt_regs * regs,struct kprobe_ctlblk * kcb)9289326638cSMasami Hiramatsu static int reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
9299326638cSMasami Hiramatsu struct kprobe_ctlblk *kcb)
930f684199fSMasami Hiramatsu {
931f684199fSMasami Hiramatsu switch (kcb->kprobe_status) {
932f684199fSMasami Hiramatsu case KPROBE_HIT_SSDONE:
933f684199fSMasami Hiramatsu case KPROBE_HIT_ACTIVE:
9346a5022a5SMasami Hiramatsu case KPROBE_HIT_SS:
935f684199fSMasami Hiramatsu kprobes_inc_nmissed_count(p);
936f684199fSMasami Hiramatsu setup_singlestep(p, regs, kcb, 1);
937f684199fSMasami Hiramatsu break;
9386a5022a5SMasami Hiramatsu case KPROBE_REENTER:
939f684199fSMasami Hiramatsu /* A probe has been hit in the codepath leading up to, or just
940f684199fSMasami Hiramatsu * after, single-stepping of a probed instruction. This entire
941f684199fSMasami Hiramatsu * codepath should strictly reside in .kprobes.text section.
942f684199fSMasami Hiramatsu * Raise a BUG or we'll continue in an endless reentering loop
943f684199fSMasami Hiramatsu * and eventually a stack overflow.
944f684199fSMasami Hiramatsu */
9450ea06330SMasami Hiramatsu pr_err("Unrecoverable kprobe detected.\n");
946f684199fSMasami Hiramatsu dump_kprobe(p);
947f684199fSMasami Hiramatsu BUG();
948f684199fSMasami Hiramatsu default:
949f684199fSMasami Hiramatsu /* impossible cases */
950f684199fSMasami Hiramatsu WARN_ON(1);
951f684199fSMasami Hiramatsu return 0;
952f684199fSMasami Hiramatsu }
953f684199fSMasami Hiramatsu
954f684199fSMasami Hiramatsu return 1;
955f684199fSMasami Hiramatsu }
9569326638cSMasami Hiramatsu NOKPROBE_SYMBOL(reenter_kprobe);
957f684199fSMasami Hiramatsu
kprobe_is_ss(struct kprobe_ctlblk * kcb)9582304d14dSWei Yongjun static nokprobe_inline int kprobe_is_ss(struct kprobe_ctlblk *kcb)
9596256e668SMasami Hiramatsu {
9606256e668SMasami Hiramatsu return (kcb->kprobe_status == KPROBE_HIT_SS ||
9616256e668SMasami Hiramatsu kcb->kprobe_status == KPROBE_REENTER);
9626256e668SMasami Hiramatsu }
9636256e668SMasami Hiramatsu
964f684199fSMasami Hiramatsu /*
965f684199fSMasami Hiramatsu * Interrupts are disabled on entry as trap3 is an interrupt gate and they
966f684199fSMasami Hiramatsu * remain disabled throughout this function.
967f684199fSMasami Hiramatsu */
kprobe_int3_handler(struct pt_regs * regs)9689326638cSMasami Hiramatsu int kprobe_int3_handler(struct pt_regs *regs)
969f684199fSMasami Hiramatsu {
970f684199fSMasami Hiramatsu kprobe_opcode_t *addr;
971f684199fSMasami Hiramatsu struct kprobe *p;
972f684199fSMasami Hiramatsu struct kprobe_ctlblk *kcb;
973f684199fSMasami Hiramatsu
974f39b6f0eSAndy Lutomirski if (user_mode(regs))
9750cdd192cSAndy Lutomirski return 0;
9760cdd192cSAndy Lutomirski
977f684199fSMasami Hiramatsu addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
978f684199fSMasami Hiramatsu /*
9792bbda764SMasami Hiramatsu * We don't want to be preempted for the entire duration of kprobe
9802bbda764SMasami Hiramatsu * processing. Since int3 and debug trap disables irqs and we clear
9812bbda764SMasami Hiramatsu * IF while singlestepping, it must be no preemptible.
982f684199fSMasami Hiramatsu */
983f684199fSMasami Hiramatsu
984f684199fSMasami Hiramatsu kcb = get_kprobe_ctlblk();
985f684199fSMasami Hiramatsu p = get_kprobe(addr);
986f684199fSMasami Hiramatsu
987f684199fSMasami Hiramatsu if (p) {
988f684199fSMasami Hiramatsu if (kprobe_running()) {
989f684199fSMasami Hiramatsu if (reenter_kprobe(p, regs, kcb))
990f684199fSMasami Hiramatsu return 1;
991f684199fSMasami Hiramatsu } else {
992f684199fSMasami Hiramatsu set_current_kprobe(p, regs, kcb);
993f684199fSMasami Hiramatsu kcb->kprobe_status = KPROBE_HIT_ACTIVE;
994f684199fSMasami Hiramatsu
995f684199fSMasami Hiramatsu /*
996f684199fSMasami Hiramatsu * If we have no pre-handler or it returned 0, we
997f684199fSMasami Hiramatsu * continue with normal processing. If we have a
99880006dbeSMasami Hiramatsu * pre-handler and it returned non-zero, that means
99980006dbeSMasami Hiramatsu * user handler setup registers to exit to another
100080006dbeSMasami Hiramatsu * instruction, we must skip the single stepping.
1001f684199fSMasami Hiramatsu */
1002f684199fSMasami Hiramatsu if (!p->pre_handler || !p->pre_handler(p, regs))
1003f684199fSMasami Hiramatsu setup_singlestep(p, regs, kcb, 0);
10042bbda764SMasami Hiramatsu else
1005cce188bdSMasami Hiramatsu reset_current_kprobe();
1006f684199fSMasami Hiramatsu return 1;
1007f684199fSMasami Hiramatsu }
10086256e668SMasami Hiramatsu } else if (kprobe_is_ss(kcb)) {
10096256e668SMasami Hiramatsu p = kprobe_running();
10106256e668SMasami Hiramatsu if ((unsigned long)p->ainsn.insn < regs->ip &&
10116256e668SMasami Hiramatsu (unsigned long)p->ainsn.insn + MAX_INSN_SIZE > regs->ip) {
10126256e668SMasami Hiramatsu /* Most provably this is the second int3 for singlestep */
10136256e668SMasami Hiramatsu resume_singlestep(p, regs, kcb);
10146256e668SMasami Hiramatsu kprobe_post_process(p, regs, kcb);
10156256e668SMasami Hiramatsu return 1;
10166256e668SMasami Hiramatsu }
1017f684199fSMasami Hiramatsu } /* else: not a kprobe fault; let the kernel handle it */
1018f684199fSMasami Hiramatsu
1019f684199fSMasami Hiramatsu return 0;
1020f684199fSMasami Hiramatsu }
10219326638cSMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_int3_handler);
1022f684199fSMasami Hiramatsu
kprobe_fault_handler(struct pt_regs * regs,int trapnr)10239326638cSMasami Hiramatsu int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
1024f684199fSMasami Hiramatsu {
1025f684199fSMasami Hiramatsu struct kprobe *cur = kprobe_running();
1026f684199fSMasami Hiramatsu struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
1027f684199fSMasami Hiramatsu
10286381c24cSMasami Hiramatsu if (unlikely(regs->ip == (unsigned long)cur->ainsn.insn)) {
10296381c24cSMasami Hiramatsu /* This must happen on single-stepping */
10306381c24cSMasami Hiramatsu WARN_ON(kcb->kprobe_status != KPROBE_HIT_SS &&
10316381c24cSMasami Hiramatsu kcb->kprobe_status != KPROBE_REENTER);
1032f684199fSMasami Hiramatsu /*
1033f684199fSMasami Hiramatsu * We are here because the instruction being single
1034f684199fSMasami Hiramatsu * stepped caused a page fault. We reset the current
1035f684199fSMasami Hiramatsu * kprobe and the ip points back to the probe address
1036f684199fSMasami Hiramatsu * and allow the page fault handler to continue as a
1037f684199fSMasami Hiramatsu * normal page fault.
1038f684199fSMasami Hiramatsu */
1039f684199fSMasami Hiramatsu regs->ip = (unsigned long)cur->addr;
1040dcfc4724SMasami Hiramatsu
1041dcfc4724SMasami Hiramatsu /*
10426256e668SMasami Hiramatsu * If the IF flag was set before the kprobe hit,
1043dcfc4724SMasami Hiramatsu * don't touch it:
1044dcfc4724SMasami Hiramatsu */
1045f684199fSMasami Hiramatsu regs->flags |= kcb->kprobe_old_flags;
1046dcfc4724SMasami Hiramatsu
1047f684199fSMasami Hiramatsu if (kcb->kprobe_status == KPROBE_REENTER)
1048f684199fSMasami Hiramatsu restore_previous_kprobe(kcb);
1049f684199fSMasami Hiramatsu else
1050f684199fSMasami Hiramatsu reset_current_kprobe();
1051f684199fSMasami Hiramatsu }
10526381c24cSMasami Hiramatsu
1053f684199fSMasami Hiramatsu return 0;
1054f684199fSMasami Hiramatsu }
10559326638cSMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_fault_handler);
1056f684199fSMasami Hiramatsu
arch_populate_kprobe_blacklist(void)1057fe6e6561SMasami Hiramatsu int __init arch_populate_kprobe_blacklist(void)
1058fe6e6561SMasami Hiramatsu {
1059fe6e6561SMasami Hiramatsu return kprobe_add_area_blacklist((unsigned long)__entry_text_start,
1060fe6e6561SMasami Hiramatsu (unsigned long)__entry_text_end);
1061fe6e6561SMasami Hiramatsu }
1062fe6e6561SMasami Hiramatsu
arch_init_kprobes(void)1063f684199fSMasami Hiramatsu int __init arch_init_kprobes(void)
1064f684199fSMasami Hiramatsu {
1065a7b0133eSMasami Hiramatsu return 0;
1066f684199fSMasami Hiramatsu }
1067f684199fSMasami Hiramatsu
arch_trampoline_kprobe(struct kprobe * p)10687ec8a97aSMasami Hiramatsu int arch_trampoline_kprobe(struct kprobe *p)
1069f684199fSMasami Hiramatsu {
1070f684199fSMasami Hiramatsu return 0;
1071f684199fSMasami Hiramatsu }
1072