1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * User-space Probes (UProbes) for s390 |
4 | * |
5 | * Copyright IBM Corp. 2014 |
6 | * Author(s): Jan Willeke, |
7 | */ |
8 | |
9 | #include <linux/uaccess.h> |
10 | #include <linux/uprobes.h> |
11 | #include <linux/compat.h> |
12 | #include <linux/kdebug.h> |
13 | #include <linux/sched/task_stack.h> |
14 | |
15 | #include <asm/facility.h> |
16 | #include <asm/kprobes.h> |
17 | #include <asm/dis.h> |
18 | #include "entry.h" |
19 | |
20 | #define UPROBE_TRAP_NR UINT_MAX |
21 | |
22 | int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, |
23 | unsigned long addr) |
24 | { |
25 | return probe_is_prohibited_opcode(auprobe->insn); |
26 | } |
27 | |
28 | int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) |
29 | { |
30 | if (psw_bits(regs->psw).eaba == PSW_BITS_AMODE_24BIT) |
31 | return -EINVAL; |
32 | if (!is_compat_task() && psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT) |
33 | return -EINVAL; |
34 | clear_thread_flag(TIF_PER_TRAP); |
35 | auprobe->saved_per = psw_bits(regs->psw).per; |
36 | auprobe->saved_int_code = regs->int_code; |
37 | regs->int_code = UPROBE_TRAP_NR; |
38 | regs->psw.addr = current->utask->xol_vaddr; |
39 | set_tsk_thread_flag(current, flag: TIF_UPROBE_SINGLESTEP); |
40 | update_cr_regs(current); |
41 | return 0; |
42 | } |
43 | |
44 | bool arch_uprobe_xol_was_trapped(struct task_struct *tsk) |
45 | { |
46 | struct pt_regs *regs = task_pt_regs(tsk); |
47 | |
48 | if (regs->int_code != UPROBE_TRAP_NR) |
49 | return true; |
50 | return false; |
51 | } |
52 | |
53 | static int check_per_event(unsigned short cause, unsigned long control, |
54 | struct pt_regs *regs) |
55 | { |
56 | if (!(regs->psw.mask & PSW_MASK_PER)) |
57 | return 0; |
58 | /* user space single step */ |
59 | if (control == 0) |
60 | return 1; |
61 | /* over indication for storage alteration */ |
62 | if ((control & 0x20200000) && (cause & 0x2000)) |
63 | return 1; |
64 | if (cause & 0x8000) { |
65 | /* all branches */ |
66 | if ((control & 0x80800000) == 0x80000000) |
67 | return 1; |
68 | /* branch into selected range */ |
69 | if (((control & 0x80800000) == 0x80800000) && |
70 | regs->psw.addr >= current->thread.per_user.start && |
71 | regs->psw.addr <= current->thread.per_user.end) |
72 | return 1; |
73 | } |
74 | return 0; |
75 | } |
76 | |
77 | int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) |
78 | { |
79 | int fixup = probe_get_fixup_type(auprobe->insn); |
80 | struct uprobe_task *utask = current->utask; |
81 | |
82 | clear_tsk_thread_flag(current, flag: TIF_UPROBE_SINGLESTEP); |
83 | update_cr_regs(current); |
84 | psw_bits(regs->psw).per = auprobe->saved_per; |
85 | regs->int_code = auprobe->saved_int_code; |
86 | |
87 | if (fixup & FIXUP_PSW_NORMAL) |
88 | regs->psw.addr += utask->vaddr - utask->xol_vaddr; |
89 | if (fixup & FIXUP_RETURN_REGISTER) { |
90 | int reg = (auprobe->insn[0] & 0xf0) >> 4; |
91 | |
92 | regs->gprs[reg] += utask->vaddr - utask->xol_vaddr; |
93 | } |
94 | if (fixup & FIXUP_BRANCH_NOT_TAKEN) { |
95 | int ilen = insn_length(auprobe->insn[0] >> 8); |
96 | |
97 | if (regs->psw.addr - utask->xol_vaddr == ilen) |
98 | regs->psw.addr = utask->vaddr + ilen; |
99 | } |
100 | if (check_per_event(current->thread.per_event.cause, |
101 | current->thread.per_user.control, regs)) { |
102 | /* fix per address */ |
103 | current->thread.per_event.address = utask->vaddr; |
104 | /* trigger per event */ |
105 | set_thread_flag(TIF_PER_TRAP); |
106 | } |
107 | return 0; |
108 | } |
109 | |
110 | int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, |
111 | void *data) |
112 | { |
113 | struct die_args *args = data; |
114 | struct pt_regs *regs = args->regs; |
115 | |
116 | if (!user_mode(regs)) |
117 | return NOTIFY_DONE; |
118 | if (regs->int_code & 0x200) /* Trap during transaction */ |
119 | return NOTIFY_DONE; |
120 | switch (val) { |
121 | case DIE_BPT: |
122 | if (uprobe_pre_sstep_notifier(regs)) |
123 | return NOTIFY_STOP; |
124 | break; |
125 | case DIE_SSTEP: |
126 | if (uprobe_post_sstep_notifier(regs)) |
127 | return NOTIFY_STOP; |
128 | break; |
129 | default: |
130 | break; |
131 | } |
132 | return NOTIFY_DONE; |
133 | } |
134 | |
135 | void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) |
136 | { |
137 | clear_thread_flag(TIF_UPROBE_SINGLESTEP); |
138 | regs->int_code = auprobe->saved_int_code; |
139 | regs->psw.addr = current->utask->vaddr; |
140 | current->thread.per_event.address = current->utask->vaddr; |
141 | } |
142 | |
143 | unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline, |
144 | struct pt_regs *regs) |
145 | { |
146 | unsigned long orig; |
147 | |
148 | orig = regs->gprs[14]; |
149 | regs->gprs[14] = trampoline; |
150 | return orig; |
151 | } |
152 | |
153 | bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, |
154 | struct pt_regs *regs) |
155 | { |
156 | if (ctx == RP_CHECK_CHAIN_CALL) |
157 | return user_stack_pointer(regs) <= ret->stack; |
158 | else |
159 | return user_stack_pointer(regs) < ret->stack; |
160 | } |
161 | |
162 | /* Instruction Emulation */ |
163 | |
164 | static void adjust_psw_addr(psw_t *psw, unsigned long len) |
165 | { |
166 | psw->addr = __rewind_psw(*psw, -len); |
167 | } |
168 | |
169 | #define EMU_ILLEGAL_OP 1 |
170 | #define EMU_SPECIFICATION 2 |
171 | #define EMU_ADDRESSING 3 |
172 | |
173 | #define emu_load_ril(ptr, output) \ |
174 | ({ \ |
175 | unsigned int mask = sizeof(*(ptr)) - 1; \ |
176 | __typeof__(*(ptr)) input; \ |
177 | int __rc = 0; \ |
178 | \ |
179 | if ((u64 __force)ptr & mask) \ |
180 | __rc = EMU_SPECIFICATION; \ |
181 | else if (get_user(input, ptr)) \ |
182 | __rc = EMU_ADDRESSING; \ |
183 | else \ |
184 | *(output) = input; \ |
185 | __rc; \ |
186 | }) |
187 | |
188 | #define emu_store_ril(regs, ptr, input) \ |
189 | ({ \ |
190 | unsigned int mask = sizeof(*(ptr)) - 1; \ |
191 | __typeof__(ptr) __ptr = (ptr); \ |
192 | int __rc = 0; \ |
193 | \ |
194 | if ((u64 __force)__ptr & mask) \ |
195 | __rc = EMU_SPECIFICATION; \ |
196 | else if (put_user(*(input), __ptr)) \ |
197 | __rc = EMU_ADDRESSING; \ |
198 | if (__rc == 0) \ |
199 | sim_stor_event(regs, \ |
200 | (void __force *)__ptr, \ |
201 | mask + 1); \ |
202 | __rc; \ |
203 | }) |
204 | |
205 | #define emu_cmp_ril(regs, ptr, cmp) \ |
206 | ({ \ |
207 | unsigned int mask = sizeof(*(ptr)) - 1; \ |
208 | __typeof__(*(ptr)) input; \ |
209 | int __rc = 0; \ |
210 | \ |
211 | if ((u64 __force)ptr & mask) \ |
212 | __rc = EMU_SPECIFICATION; \ |
213 | else if (get_user(input, ptr)) \ |
214 | __rc = EMU_ADDRESSING; \ |
215 | else if (input > *(cmp)) \ |
216 | psw_bits((regs)->psw).cc = 1; \ |
217 | else if (input < *(cmp)) \ |
218 | psw_bits((regs)->psw).cc = 2; \ |
219 | else \ |
220 | psw_bits((regs)->psw).cc = 0; \ |
221 | __rc; \ |
222 | }) |
223 | |
224 | struct insn_ril { |
225 | u8 opc0; |
226 | u8 reg : 4; |
227 | u8 opc1 : 4; |
228 | s32 disp; |
229 | } __packed; |
230 | |
231 | union split_register { |
232 | u64 u64; |
233 | u32 u32[2]; |
234 | u16 u16[4]; |
235 | s64 s64; |
236 | s32 s32[2]; |
237 | s16 s16[4]; |
238 | }; |
239 | |
240 | /* |
241 | * If user per registers are setup to trace storage alterations and an |
242 | * emulated store took place on a fitting address a user trap is generated. |
243 | */ |
244 | static void sim_stor_event(struct pt_regs *regs, void *addr, int len) |
245 | { |
246 | if (!(regs->psw.mask & PSW_MASK_PER)) |
247 | return; |
248 | if (!(current->thread.per_user.control & PER_EVENT_STORE)) |
249 | return; |
250 | if ((void *)current->thread.per_user.start > (addr + len)) |
251 | return; |
252 | if ((void *)current->thread.per_user.end < addr) |
253 | return; |
254 | current->thread.per_event.address = regs->psw.addr; |
255 | current->thread.per_event.cause = PER_EVENT_STORE >> 16; |
256 | set_thread_flag(TIF_PER_TRAP); |
257 | } |
258 | |
259 | /* |
260 | * pc relative instructions are emulated, since parameters may not be |
261 | * accessible from the xol area due to range limitations. |
262 | */ |
263 | static void handle_insn_ril(struct arch_uprobe *auprobe, struct pt_regs *regs) |
264 | { |
265 | union split_register *rx; |
266 | struct insn_ril *insn; |
267 | unsigned int ilen; |
268 | void *uptr; |
269 | int rc = 0; |
270 | |
271 | insn = (struct insn_ril *) &auprobe->insn; |
272 | rx = (union split_register *) ®s->gprs[insn->reg]; |
273 | uptr = (void *)(regs->psw.addr + (insn->disp * 2)); |
274 | ilen = insn_length(insn->opc0); |
275 | |
276 | switch (insn->opc0) { |
277 | case 0xc0: |
278 | switch (insn->opc1) { |
279 | case 0x00: /* larl */ |
280 | rx->u64 = (unsigned long)uptr; |
281 | break; |
282 | } |
283 | break; |
284 | case 0xc4: |
285 | switch (insn->opc1) { |
286 | case 0x02: /* llhrl */ |
287 | rc = emu_load_ril((u16 __user *)uptr, &rx->u32[1]); |
288 | break; |
289 | case 0x04: /* lghrl */ |
290 | rc = emu_load_ril((s16 __user *)uptr, &rx->u64); |
291 | break; |
292 | case 0x05: /* lhrl */ |
293 | rc = emu_load_ril((s16 __user *)uptr, &rx->u32[1]); |
294 | break; |
295 | case 0x06: /* llghrl */ |
296 | rc = emu_load_ril((u16 __user *)uptr, &rx->u64); |
297 | break; |
298 | case 0x08: /* lgrl */ |
299 | rc = emu_load_ril((u64 __user *)uptr, &rx->u64); |
300 | break; |
301 | case 0x0c: /* lgfrl */ |
302 | rc = emu_load_ril((s32 __user *)uptr, &rx->u64); |
303 | break; |
304 | case 0x0d: /* lrl */ |
305 | rc = emu_load_ril((u32 __user *)uptr, &rx->u32[1]); |
306 | break; |
307 | case 0x0e: /* llgfrl */ |
308 | rc = emu_load_ril((u32 __user *)uptr, &rx->u64); |
309 | break; |
310 | case 0x07: /* sthrl */ |
311 | rc = emu_store_ril(regs, (u16 __user *)uptr, &rx->u16[3]); |
312 | break; |
313 | case 0x0b: /* stgrl */ |
314 | rc = emu_store_ril(regs, (u64 __user *)uptr, &rx->u64); |
315 | break; |
316 | case 0x0f: /* strl */ |
317 | rc = emu_store_ril(regs, (u32 __user *)uptr, &rx->u32[1]); |
318 | break; |
319 | } |
320 | break; |
321 | case 0xc6: |
322 | switch (insn->opc1) { |
323 | case 0x04: /* cghrl */ |
324 | rc = emu_cmp_ril(regs, (s16 __user *)uptr, &rx->s64); |
325 | break; |
326 | case 0x05: /* chrl */ |
327 | rc = emu_cmp_ril(regs, (s16 __user *)uptr, &rx->s32[1]); |
328 | break; |
329 | case 0x06: /* clghrl */ |
330 | rc = emu_cmp_ril(regs, (u16 __user *)uptr, &rx->u64); |
331 | break; |
332 | case 0x07: /* clhrl */ |
333 | rc = emu_cmp_ril(regs, (u16 __user *)uptr, &rx->u32[1]); |
334 | break; |
335 | case 0x08: /* cgrl */ |
336 | rc = emu_cmp_ril(regs, (s64 __user *)uptr, &rx->s64); |
337 | break; |
338 | case 0x0a: /* clgrl */ |
339 | rc = emu_cmp_ril(regs, (u64 __user *)uptr, &rx->u64); |
340 | break; |
341 | case 0x0c: /* cgfrl */ |
342 | rc = emu_cmp_ril(regs, (s32 __user *)uptr, &rx->s64); |
343 | break; |
344 | case 0x0d: /* crl */ |
345 | rc = emu_cmp_ril(regs, (s32 __user *)uptr, &rx->s32[1]); |
346 | break; |
347 | case 0x0e: /* clgfrl */ |
348 | rc = emu_cmp_ril(regs, (u32 __user *)uptr, &rx->u64); |
349 | break; |
350 | case 0x0f: /* clrl */ |
351 | rc = emu_cmp_ril(regs, (u32 __user *)uptr, &rx->u32[1]); |
352 | break; |
353 | } |
354 | break; |
355 | } |
356 | adjust_psw_addr(®s->psw, ilen); |
357 | switch (rc) { |
358 | case EMU_ILLEGAL_OP: |
359 | regs->int_code = ilen << 16 | 0x0001; |
360 | do_report_trap(regs, SIGILL, ILL_ILLOPC, NULL); |
361 | break; |
362 | case EMU_SPECIFICATION: |
363 | regs->int_code = ilen << 16 | 0x0006; |
364 | do_report_trap(regs, SIGILL, ILL_ILLOPC , NULL); |
365 | break; |
366 | case EMU_ADDRESSING: |
367 | regs->int_code = ilen << 16 | 0x0005; |
368 | do_report_trap(regs, SIGSEGV, SEGV_MAPERR, NULL); |
369 | break; |
370 | } |
371 | } |
372 | |
373 | bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) |
374 | { |
375 | if ((psw_bits(regs->psw).eaba == PSW_BITS_AMODE_24BIT) || |
376 | ((psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT) && |
377 | !is_compat_task())) { |
378 | regs->psw.addr = __rewind_psw(regs->psw, UPROBE_SWBP_INSN_SIZE); |
379 | do_report_trap(regs, SIGILL, ILL_ILLADR, NULL); |
380 | return true; |
381 | } |
382 | if (probe_is_insn_relative_long(auprobe->insn)) { |
383 | handle_insn_ril(auprobe, regs); |
384 | return true; |
385 | } |
386 | return false; |
387 | } |
388 | |