GNU Linux-libre 5.4.274-gnu1
[releases.git] / arch / powerpc / kernel / uprobes.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * User-space Probes (UProbes) for powerpc
4  *
5  * Copyright IBM Corporation, 2007-2012
6  *
7  * Adapted from the x86 port by Ananth N Mavinakayanahalli <ananth@in.ibm.com>
8  */
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/ptrace.h>
12 #include <linux/uprobes.h>
13 #include <linux/uaccess.h>
14 #include <linux/kdebug.h>
15
16 #include <asm/sstep.h>
17
18 #define UPROBE_TRAP_NR  UINT_MAX
19
20 /**
21  * is_trap_insn - check if the instruction is a trap variant
22  * @insn: instruction to be checked.
23  * Returns true if @insn is a trap variant.
24  */
25 bool is_trap_insn(uprobe_opcode_t *insn)
26 {
27         return (is_trap(*insn));
28 }
29
30 /**
31  * arch_uprobe_analyze_insn
32  * @mm: the probed address space.
33  * @arch_uprobe: the probepoint information.
34  * @addr: vaddr to probe.
35  * Return 0 on success or a -ve number on error.
36  */
37 int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe,
38                 struct mm_struct *mm, unsigned long addr)
39 {
40         if (addr & 0x03)
41                 return -EINVAL;
42
43         return 0;
44 }
45
46 /*
47  * arch_uprobe_pre_xol - prepare to execute out of line.
48  * @auprobe: the probepoint information.
49  * @regs: reflects the saved user state of current task.
50  */
51 int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
52 {
53         struct arch_uprobe_task *autask = &current->utask->autask;
54
55         autask->saved_trap_nr = current->thread.trap_nr;
56         current->thread.trap_nr = UPROBE_TRAP_NR;
57         regs->nip = current->utask->xol_vaddr;
58
59         user_enable_single_step(current);
60         return 0;
61 }
62
63 /**
64  * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs
65  * @regs: Reflects the saved state of the task after it has hit a breakpoint
66  * instruction.
67  * Return the address of the breakpoint instruction.
68  */
69 unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
70 {
71         return instruction_pointer(regs);
72 }
73
74 /*
75  * If xol insn itself traps and generates a signal (SIGILL/SIGSEGV/etc),
76  * then detect the case where a singlestepped instruction jumps back to its
77  * own address. It is assumed that anything like do_page_fault/do_trap/etc
78  * sets thread.trap_nr != UINT_MAX.
79  *
80  * arch_uprobe_pre_xol/arch_uprobe_post_xol save/restore thread.trap_nr,
81  * arch_uprobe_xol_was_trapped() simply checks that ->trap_nr is not equal to
82  * UPROBE_TRAP_NR == UINT_MAX set by arch_uprobe_pre_xol().
83  */
84 bool arch_uprobe_xol_was_trapped(struct task_struct *t)
85 {
86         if (t->thread.trap_nr != UPROBE_TRAP_NR)
87                 return true;
88
89         return false;
90 }
91
92 /*
93  * Called after single-stepping. To avoid the SMP problems that can
94  * occur when we temporarily put back the original opcode to
95  * single-step, we single-stepped a copy of the instruction.
96  *
97  * This function prepares to resume execution after the single-step.
98  */
99 int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
100 {
101         struct uprobe_task *utask = current->utask;
102
103         WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR);
104
105         current->thread.trap_nr = utask->autask.saved_trap_nr;
106
107         /*
108          * On powerpc, except for loads and stores, most instructions
109          * including ones that alter code flow (branches, calls, returns)
110          * are emulated in the kernel. We get here only if the emulation
111          * support doesn't exist and have to fix-up the next instruction
112          * to be executed.
113          */
114         regs->nip = utask->vaddr + MAX_UINSN_BYTES;
115
116         user_disable_single_step(current);
117         return 0;
118 }
119
120 /* callback routine for handling exceptions. */
121 int arch_uprobe_exception_notify(struct notifier_block *self,
122                                 unsigned long val, void *data)
123 {
124         struct die_args *args = data;
125         struct pt_regs *regs = args->regs;
126
127         /* regs == NULL is a kernel bug */
128         if (WARN_ON(!regs))
129                 return NOTIFY_DONE;
130
131         /* We are only interested in userspace traps */
132         if (!user_mode(regs))
133                 return NOTIFY_DONE;
134
135         switch (val) {
136         case DIE_BPT:
137                 if (uprobe_pre_sstep_notifier(regs))
138                         return NOTIFY_STOP;
139                 break;
140         case DIE_SSTEP:
141                 if (uprobe_post_sstep_notifier(regs))
142                         return NOTIFY_STOP;
143         default:
144                 break;
145         }
146         return NOTIFY_DONE;
147 }
148
149 /*
150  * This function gets called when XOL instruction either gets trapped or
151  * the thread has a fatal signal, so reset the instruction pointer to its
152  * probed address.
153  */
154 void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
155 {
156         struct uprobe_task *utask = current->utask;
157
158         current->thread.trap_nr = utask->autask.saved_trap_nr;
159         instruction_pointer_set(regs, utask->vaddr);
160
161         user_disable_single_step(current);
162 }
163
164 /*
165  * See if the instruction can be emulated.
166  * Returns true if instruction was emulated, false otherwise.
167  */
168 bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
169 {
170         int ret;
171
172         /*
173          * emulate_step() returns 1 if the insn was successfully emulated.
174          * For all other cases, we need to single-step in hardware.
175          */
176         ret = emulate_step(regs, auprobe->insn);
177         if (ret > 0)
178                 return true;
179
180         return false;
181 }
182
183 unsigned long
184 arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs)
185 {
186         unsigned long orig_ret_vaddr;
187
188         orig_ret_vaddr = regs->link;
189
190         /* Replace the return addr with trampoline addr */
191         regs->link = trampoline_vaddr;
192
193         return orig_ret_vaddr;
194 }
195
196 bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
197                                 struct pt_regs *regs)
198 {
199         if (ctx == RP_CHECK_CHAIN_CALL)
200                 return regs->gpr[1] <= ret->stack;
201         else
202                 return regs->gpr[1] < ret->stack;
203 }