xref: /openbmc/linux/arch/x86/kernel/kprobes/core.c (revision 46eeaa11bdd1bc9e077bdf741d32ca7235d263c6)
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 *)&regs->cx)--) != 0;
5356256e668SMasami Hiramatsu #ifdef CONFIG_X86_64
5366256e668SMasami Hiramatsu 		else if (p->ainsn.loop.asize == 64)
5376256e668SMasami Hiramatsu 			match = ((*(u64 *)&regs->cx)--) != 0;
5386256e668SMasami Hiramatsu #endif
5396256e668SMasami Hiramatsu 		else
5406256e668SMasami Hiramatsu 			match = ((*(u16 *)&regs->cx)--) != 0;
5416256e668SMasami Hiramatsu 	} else {			/* JCXZ */
5426256e668SMasami Hiramatsu 		if (p->ainsn.loop.asize == 32)
5436256e668SMasami Hiramatsu 			match = *(u32 *)(&regs->cx) == 0;
5446256e668SMasami Hiramatsu #ifdef CONFIG_X86_64
5456256e668SMasami Hiramatsu 		else if (p->ainsn.loop.asize == 64)
5466256e668SMasami Hiramatsu 			match = *(u64 *)(&regs->cx) == 0;
5476256e668SMasami Hiramatsu #endif
5486256e668SMasami Hiramatsu 		else
5496256e668SMasami Hiramatsu 			match = *(u16 *)(&regs->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