1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Ptrace user space interface. |
4 | * |
5 | * Copyright IBM Corp. 1999, 2010 |
6 | * Author(s): Denis Joseph Barrow |
7 | * Martin Schwidefsky (schwidefsky@de.ibm.com) |
8 | */ |
9 | |
10 | #include "asm/ptrace.h" |
11 | #include <linux/kernel.h> |
12 | #include <linux/sched.h> |
13 | #include <linux/sched/task_stack.h> |
14 | #include <linux/mm.h> |
15 | #include <linux/smp.h> |
16 | #include <linux/errno.h> |
17 | #include <linux/ptrace.h> |
18 | #include <linux/user.h> |
19 | #include <linux/security.h> |
20 | #include <linux/audit.h> |
21 | #include <linux/signal.h> |
22 | #include <linux/elf.h> |
23 | #include <linux/regset.h> |
24 | #include <linux/seccomp.h> |
25 | #include <linux/compat.h> |
26 | #include <trace/syscall.h> |
27 | #include <asm/guarded_storage.h> |
28 | #include <asm/access-regs.h> |
29 | #include <asm/page.h> |
30 | #include <linux/uaccess.h> |
31 | #include <asm/unistd.h> |
32 | #include <asm/runtime_instr.h> |
33 | #include <asm/facility.h> |
34 | #include <asm/fpu.h> |
35 | |
36 | #include "entry.h" |
37 | |
38 | #ifdef CONFIG_COMPAT |
39 | #include "compat_ptrace.h" |
40 | #endif |
41 | |
42 | void update_cr_regs(struct task_struct *task) |
43 | { |
44 | struct pt_regs *regs = task_pt_regs(task); |
45 | struct thread_struct *thread = &task->thread; |
46 | union ctlreg0 cr0_old, cr0_new; |
47 | union ctlreg2 cr2_old, cr2_new; |
48 | int cr0_changed, cr2_changed; |
49 | union { |
50 | struct ctlreg regs[3]; |
51 | struct { |
52 | struct ctlreg control; |
53 | struct ctlreg start; |
54 | struct ctlreg end; |
55 | }; |
56 | } old, new; |
57 | |
58 | local_ctl_store(0, &cr0_old.reg); |
59 | local_ctl_store(2, &cr2_old.reg); |
60 | cr0_new = cr0_old; |
61 | cr2_new = cr2_old; |
62 | /* Take care of the enable/disable of transactional execution. */ |
63 | if (MACHINE_HAS_TE) { |
64 | /* Set or clear transaction execution TXC bit 8. */ |
65 | cr0_new.tcx = 1; |
66 | if (task->thread.per_flags & PER_FLAG_NO_TE) |
67 | cr0_new.tcx = 0; |
68 | /* Set or clear transaction execution TDC bits 62 and 63. */ |
69 | cr2_new.tdc = 0; |
70 | if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) { |
71 | if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND) |
72 | cr2_new.tdc = 1; |
73 | else |
74 | cr2_new.tdc = 2; |
75 | } |
76 | } |
77 | /* Take care of enable/disable of guarded storage. */ |
78 | if (MACHINE_HAS_GS) { |
79 | cr2_new.gse = 0; |
80 | if (task->thread.gs_cb) |
81 | cr2_new.gse = 1; |
82 | } |
83 | /* Load control register 0/2 iff changed */ |
84 | cr0_changed = cr0_new.val != cr0_old.val; |
85 | cr2_changed = cr2_new.val != cr2_old.val; |
86 | if (cr0_changed) |
87 | local_ctl_load(0, &cr0_new.reg); |
88 | if (cr2_changed) |
89 | local_ctl_load(2, &cr2_new.reg); |
90 | /* Copy user specified PER registers */ |
91 | new.control.val = thread->per_user.control; |
92 | new.start.val = thread->per_user.start; |
93 | new.end.val = thread->per_user.end; |
94 | |
95 | /* merge TIF_SINGLE_STEP into user specified PER registers. */ |
96 | if (test_tsk_thread_flag(tsk: task, flag: TIF_SINGLE_STEP) || |
97 | test_tsk_thread_flag(tsk: task, flag: TIF_UPROBE_SINGLESTEP)) { |
98 | if (test_tsk_thread_flag(tsk: task, flag: TIF_BLOCK_STEP)) |
99 | new.control.val |= PER_EVENT_BRANCH; |
100 | else |
101 | new.control.val |= PER_EVENT_IFETCH; |
102 | new.control.val |= PER_CONTROL_SUSPENSION; |
103 | new.control.val |= PER_EVENT_TRANSACTION_END; |
104 | if (test_tsk_thread_flag(tsk: task, flag: TIF_UPROBE_SINGLESTEP)) |
105 | new.control.val |= PER_EVENT_IFETCH; |
106 | new.start.val = 0; |
107 | new.end.val = -1UL; |
108 | } |
109 | |
110 | /* Take care of the PER enablement bit in the PSW. */ |
111 | if (!(new.control.val & PER_EVENT_MASK)) { |
112 | regs->psw.mask &= ~PSW_MASK_PER; |
113 | return; |
114 | } |
115 | regs->psw.mask |= PSW_MASK_PER; |
116 | __local_ctl_store(9, 11, old.regs); |
117 | if (memcmp(&new, &old, sizeof(struct per_regs)) != 0) |
118 | __local_ctl_load(9, 11, new.regs); |
119 | } |
120 | |
121 | void user_enable_single_step(struct task_struct *task) |
122 | { |
123 | clear_tsk_thread_flag(task, TIF_BLOCK_STEP); |
124 | set_tsk_thread_flag(task, TIF_SINGLE_STEP); |
125 | } |
126 | |
127 | void user_disable_single_step(struct task_struct *task) |
128 | { |
129 | clear_tsk_thread_flag(task, TIF_BLOCK_STEP); |
130 | clear_tsk_thread_flag(task, TIF_SINGLE_STEP); |
131 | } |
132 | |
133 | void user_enable_block_step(struct task_struct *task) |
134 | { |
135 | set_tsk_thread_flag(task, TIF_SINGLE_STEP); |
136 | set_tsk_thread_flag(task, TIF_BLOCK_STEP); |
137 | } |
138 | |
139 | /* |
140 | * Called by kernel/ptrace.c when detaching.. |
141 | * |
142 | * Clear all debugging related fields. |
143 | */ |
144 | void ptrace_disable(struct task_struct *task) |
145 | { |
146 | memset(&task->thread.per_user, 0, sizeof(task->thread.per_user)); |
147 | memset(&task->thread.per_event, 0, sizeof(task->thread.per_event)); |
148 | clear_tsk_thread_flag(task, TIF_SINGLE_STEP); |
149 | clear_tsk_thread_flag(task, TIF_PER_TRAP); |
150 | task->thread.per_flags = 0; |
151 | } |
152 | |
153 | #define __ADDR_MASK 7 |
154 | |
155 | static inline unsigned long __peek_user_per(struct task_struct *child, |
156 | addr_t addr) |
157 | { |
158 | if (addr == offsetof(struct per_struct_kernel, cr9)) |
159 | /* Control bits of the active per set. */ |
160 | return test_thread_flag(TIF_SINGLE_STEP) ? |
161 | PER_EVENT_IFETCH : child->thread.per_user.control; |
162 | else if (addr == offsetof(struct per_struct_kernel, cr10)) |
163 | /* Start address of the active per set. */ |
164 | return test_thread_flag(TIF_SINGLE_STEP) ? |
165 | 0 : child->thread.per_user.start; |
166 | else if (addr == offsetof(struct per_struct_kernel, cr11)) |
167 | /* End address of the active per set. */ |
168 | return test_thread_flag(TIF_SINGLE_STEP) ? |
169 | -1UL : child->thread.per_user.end; |
170 | else if (addr == offsetof(struct per_struct_kernel, bits)) |
171 | /* Single-step bit. */ |
172 | return test_thread_flag(TIF_SINGLE_STEP) ? |
173 | (1UL << (BITS_PER_LONG - 1)) : 0; |
174 | else if (addr == offsetof(struct per_struct_kernel, starting_addr)) |
175 | /* Start address of the user specified per set. */ |
176 | return child->thread.per_user.start; |
177 | else if (addr == offsetof(struct per_struct_kernel, ending_addr)) |
178 | /* End address of the user specified per set. */ |
179 | return child->thread.per_user.end; |
180 | else if (addr == offsetof(struct per_struct_kernel, perc_atmid)) |
181 | /* PER code, ATMID and AI of the last PER trap */ |
182 | return (unsigned long) |
183 | child->thread.per_event.cause << (BITS_PER_LONG - 16); |
184 | else if (addr == offsetof(struct per_struct_kernel, address)) |
185 | /* Address of the last PER trap */ |
186 | return child->thread.per_event.address; |
187 | else if (addr == offsetof(struct per_struct_kernel, access_id)) |
188 | /* Access id of the last PER trap */ |
189 | return (unsigned long) |
190 | child->thread.per_event.paid << (BITS_PER_LONG - 8); |
191 | return 0; |
192 | } |
193 | |
194 | /* |
195 | * Read the word at offset addr from the user area of a process. The |
196 | * trouble here is that the information is littered over different |
197 | * locations. The process registers are found on the kernel stack, |
198 | * the floating point stuff and the trace settings are stored in |
199 | * the task structure. In addition the different structures in |
200 | * struct user contain pad bytes that should be read as zeroes. |
201 | * Lovely... |
202 | */ |
203 | static unsigned long __peek_user(struct task_struct *child, addr_t addr) |
204 | { |
205 | addr_t offset, tmp; |
206 | |
207 | if (addr < offsetof(struct user, regs.acrs)) { |
208 | /* |
209 | * psw and gprs are stored on the stack |
210 | */ |
211 | tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr); |
212 | if (addr == offsetof(struct user, regs.psw.mask)) { |
213 | /* Return a clean psw mask. */ |
214 | tmp &= PSW_MASK_USER | PSW_MASK_RI; |
215 | tmp |= PSW_USER_BITS; |
216 | } |
217 | |
218 | } else if (addr < offsetof(struct user, regs.orig_gpr2)) { |
219 | /* |
220 | * access registers are stored in the thread structure |
221 | */ |
222 | offset = addr - offsetof(struct user, regs.acrs); |
223 | /* |
224 | * Very special case: old & broken 64 bit gdb reading |
225 | * from acrs[15]. Result is a 64 bit value. Read the |
226 | * 32 bit acrs[15] value and shift it by 32. Sick... |
227 | */ |
228 | if (addr == offsetof(struct user, regs.acrs[15])) |
229 | tmp = ((unsigned long) child->thread.acrs[15]) << 32; |
230 | else |
231 | tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset); |
232 | |
233 | } else if (addr == offsetof(struct user, regs.orig_gpr2)) { |
234 | /* |
235 | * orig_gpr2 is stored on the kernel stack |
236 | */ |
237 | tmp = (addr_t) task_pt_regs(child)->orig_gpr2; |
238 | |
239 | } else if (addr < offsetof(struct user, regs.fp_regs)) { |
240 | /* |
241 | * prevent reads of padding hole between |
242 | * orig_gpr2 and fp_regs on s390. |
243 | */ |
244 | tmp = 0; |
245 | |
246 | } else if (addr == offsetof(struct user, regs.fp_regs.fpc)) { |
247 | /* |
248 | * floating point control reg. is in the thread structure |
249 | */ |
250 | tmp = child->thread.ufpu.fpc; |
251 | tmp <<= BITS_PER_LONG - 32; |
252 | |
253 | } else if (addr < offsetof(struct user, regs.fp_regs) + sizeof(s390_fp_regs)) { |
254 | /* |
255 | * floating point regs. are in the child->thread.ufpu.vxrs array |
256 | */ |
257 | offset = addr - offsetof(struct user, regs.fp_regs.fprs); |
258 | tmp = *(addr_t *)((addr_t)child->thread.ufpu.vxrs + 2 * offset); |
259 | } else if (addr < offsetof(struct user, regs.per_info) + sizeof(per_struct)) { |
260 | /* |
261 | * Handle access to the per_info structure. |
262 | */ |
263 | addr -= offsetof(struct user, regs.per_info); |
264 | tmp = __peek_user_per(child, addr); |
265 | |
266 | } else |
267 | tmp = 0; |
268 | |
269 | return tmp; |
270 | } |
271 | |
272 | static int |
273 | peek_user(struct task_struct *child, addr_t addr, addr_t data) |
274 | { |
275 | addr_t tmp, mask; |
276 | |
277 | /* |
278 | * Stupid gdb peeks/pokes the access registers in 64 bit with |
279 | * an alignment of 4. Programmers from hell... |
280 | */ |
281 | mask = __ADDR_MASK; |
282 | if (addr >= offsetof(struct user, regs.acrs) && |
283 | addr < offsetof(struct user, regs.orig_gpr2)) |
284 | mask = 3; |
285 | if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) |
286 | return -EIO; |
287 | |
288 | tmp = __peek_user(child, addr); |
289 | return put_user(tmp, (addr_t __user *) data); |
290 | } |
291 | |
292 | static inline void __poke_user_per(struct task_struct *child, |
293 | addr_t addr, addr_t data) |
294 | { |
295 | /* |
296 | * There are only three fields in the per_info struct that the |
297 | * debugger user can write to. |
298 | * 1) cr9: the debugger wants to set a new PER event mask |
299 | * 2) starting_addr: the debugger wants to set a new starting |
300 | * address to use with the PER event mask. |
301 | * 3) ending_addr: the debugger wants to set a new ending |
302 | * address to use with the PER event mask. |
303 | * The user specified PER event mask and the start and end |
304 | * addresses are used only if single stepping is not in effect. |
305 | * Writes to any other field in per_info are ignored. |
306 | */ |
307 | if (addr == offsetof(struct per_struct_kernel, cr9)) |
308 | /* PER event mask of the user specified per set. */ |
309 | child->thread.per_user.control = |
310 | data & (PER_EVENT_MASK | PER_CONTROL_MASK); |
311 | else if (addr == offsetof(struct per_struct_kernel, starting_addr)) |
312 | /* Starting address of the user specified per set. */ |
313 | child->thread.per_user.start = data; |
314 | else if (addr == offsetof(struct per_struct_kernel, ending_addr)) |
315 | /* Ending address of the user specified per set. */ |
316 | child->thread.per_user.end = data; |
317 | } |
318 | |
319 | /* |
320 | * Write a word to the user area of a process at location addr. This |
321 | * operation does have an additional problem compared to peek_user. |
322 | * Stores to the program status word and on the floating point |
323 | * control register needs to get checked for validity. |
324 | */ |
325 | static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) |
326 | { |
327 | addr_t offset; |
328 | |
329 | |
330 | if (addr < offsetof(struct user, regs.acrs)) { |
331 | struct pt_regs *regs = task_pt_regs(child); |
332 | /* |
333 | * psw and gprs are stored on the stack |
334 | */ |
335 | if (addr == offsetof(struct user, regs.psw.mask)) { |
336 | unsigned long mask = PSW_MASK_USER; |
337 | |
338 | mask |= is_ri_task(child) ? PSW_MASK_RI : 0; |
339 | if ((data ^ PSW_USER_BITS) & ~mask) |
340 | /* Invalid psw mask. */ |
341 | return -EINVAL; |
342 | if ((data & PSW_MASK_ASC) == PSW_ASC_HOME) |
343 | /* Invalid address-space-control bits */ |
344 | return -EINVAL; |
345 | if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA)) |
346 | /* Invalid addressing mode bits */ |
347 | return -EINVAL; |
348 | } |
349 | |
350 | if (test_pt_regs_flag(regs, PIF_SYSCALL) && |
351 | addr == offsetof(struct user, regs.gprs[2])) { |
352 | struct pt_regs *regs = task_pt_regs(child); |
353 | |
354 | regs->int_code = 0x20000 | (data & 0xffff); |
355 | } |
356 | *(addr_t *)((addr_t) ®s->psw + addr) = data; |
357 | } else if (addr < offsetof(struct user, regs.orig_gpr2)) { |
358 | /* |
359 | * access registers are stored in the thread structure |
360 | */ |
361 | offset = addr - offsetof(struct user, regs.acrs); |
362 | /* |
363 | * Very special case: old & broken 64 bit gdb writing |
364 | * to acrs[15] with a 64 bit value. Ignore the lower |
365 | * half of the value and write the upper 32 bit to |
366 | * acrs[15]. Sick... |
367 | */ |
368 | if (addr == offsetof(struct user, regs.acrs[15])) |
369 | child->thread.acrs[15] = (unsigned int) (data >> 32); |
370 | else |
371 | *(addr_t *)((addr_t) &child->thread.acrs + offset) = data; |
372 | |
373 | } else if (addr == offsetof(struct user, regs.orig_gpr2)) { |
374 | /* |
375 | * orig_gpr2 is stored on the kernel stack |
376 | */ |
377 | task_pt_regs(child)->orig_gpr2 = data; |
378 | |
379 | } else if (addr < offsetof(struct user, regs.fp_regs)) { |
380 | /* |
381 | * prevent writes of padding hole between |
382 | * orig_gpr2 and fp_regs on s390. |
383 | */ |
384 | return 0; |
385 | |
386 | } else if (addr == offsetof(struct user, regs.fp_regs.fpc)) { |
387 | /* |
388 | * floating point control reg. is in the thread structure |
389 | */ |
390 | if ((unsigned int)data != 0) |
391 | return -EINVAL; |
392 | child->thread.ufpu.fpc = data >> (BITS_PER_LONG - 32); |
393 | |
394 | } else if (addr < offsetof(struct user, regs.fp_regs) + sizeof(s390_fp_regs)) { |
395 | /* |
396 | * floating point regs. are in the child->thread.ufpu.vxrs array |
397 | */ |
398 | offset = addr - offsetof(struct user, regs.fp_regs.fprs); |
399 | *(addr_t *)((addr_t)child->thread.ufpu.vxrs + 2 * offset) = data; |
400 | } else if (addr < offsetof(struct user, regs.per_info) + sizeof(per_struct)) { |
401 | /* |
402 | * Handle access to the per_info structure. |
403 | */ |
404 | addr -= offsetof(struct user, regs.per_info); |
405 | __poke_user_per(child, addr, data); |
406 | |
407 | } |
408 | |
409 | return 0; |
410 | } |
411 | |
412 | static int poke_user(struct task_struct *child, addr_t addr, addr_t data) |
413 | { |
414 | addr_t mask; |
415 | |
416 | /* |
417 | * Stupid gdb peeks/pokes the access registers in 64 bit with |
418 | * an alignment of 4. Programmers from hell indeed... |
419 | */ |
420 | mask = __ADDR_MASK; |
421 | if (addr >= offsetof(struct user, regs.acrs) && |
422 | addr < offsetof(struct user, regs.orig_gpr2)) |
423 | mask = 3; |
424 | if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) |
425 | return -EIO; |
426 | |
427 | return __poke_user(child, addr, data); |
428 | } |
429 | |
430 | long arch_ptrace(struct task_struct *child, long request, |
431 | unsigned long addr, unsigned long data) |
432 | { |
433 | ptrace_area parea; |
434 | int copied, ret; |
435 | |
436 | switch (request) { |
437 | case PTRACE_PEEKUSR: |
438 | /* read the word at location addr in the USER area. */ |
439 | return peek_user(child, addr, data); |
440 | |
441 | case PTRACE_POKEUSR: |
442 | /* write the word at location addr in the USER area */ |
443 | return poke_user(child, addr, data); |
444 | |
445 | case PTRACE_PEEKUSR_AREA: |
446 | case PTRACE_POKEUSR_AREA: |
447 | if (copy_from_user(&parea, (void __force __user *) addr, |
448 | sizeof(parea))) |
449 | return -EFAULT; |
450 | addr = parea.kernel_addr; |
451 | data = parea.process_addr; |
452 | copied = 0; |
453 | while (copied < parea.len) { |
454 | if (request == PTRACE_PEEKUSR_AREA) |
455 | ret = peek_user(child, addr, data); |
456 | else { |
457 | addr_t utmp; |
458 | if (get_user(utmp, |
459 | (addr_t __force __user *) data)) |
460 | return -EFAULT; |
461 | ret = poke_user(child, addr, utmp); |
462 | } |
463 | if (ret) |
464 | return ret; |
465 | addr += sizeof(unsigned long); |
466 | data += sizeof(unsigned long); |
467 | copied += sizeof(unsigned long); |
468 | } |
469 | return 0; |
470 | case PTRACE_GET_LAST_BREAK: |
471 | return put_user(child->thread.last_break, (unsigned long __user *)data); |
472 | case PTRACE_ENABLE_TE: |
473 | if (!MACHINE_HAS_TE) |
474 | return -EIO; |
475 | child->thread.per_flags &= ~PER_FLAG_NO_TE; |
476 | return 0; |
477 | case PTRACE_DISABLE_TE: |
478 | if (!MACHINE_HAS_TE) |
479 | return -EIO; |
480 | child->thread.per_flags |= PER_FLAG_NO_TE; |
481 | child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND; |
482 | return 0; |
483 | case PTRACE_TE_ABORT_RAND: |
484 | if (!MACHINE_HAS_TE || (child->thread.per_flags & PER_FLAG_NO_TE)) |
485 | return -EIO; |
486 | switch (data) { |
487 | case 0UL: |
488 | child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND; |
489 | break; |
490 | case 1UL: |
491 | child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND; |
492 | child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND_TEND; |
493 | break; |
494 | case 2UL: |
495 | child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND; |
496 | child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND_TEND; |
497 | break; |
498 | default: |
499 | return -EINVAL; |
500 | } |
501 | return 0; |
502 | default: |
503 | return ptrace_request(child, request, addr, data); |
504 | } |
505 | } |
506 | |
507 | #ifdef CONFIG_COMPAT |
508 | /* |
509 | * Now the fun part starts... a 31 bit program running in the |
510 | * 31 bit emulation tracing another program. PTRACE_PEEKTEXT, |
511 | * PTRACE_PEEKDATA, PTRACE_POKETEXT and PTRACE_POKEDATA are easy |
512 | * to handle, the difference to the 64 bit versions of the requests |
513 | * is that the access is done in multiples of 4 byte instead of |
514 | * 8 bytes (sizeof(unsigned long) on 31/64 bit). |
515 | * The ugly part are PTRACE_PEEKUSR, PTRACE_PEEKUSR_AREA, |
516 | * PTRACE_POKEUSR and PTRACE_POKEUSR_AREA. If the traced program |
517 | * is a 31 bit program too, the content of struct user can be |
518 | * emulated. A 31 bit program peeking into the struct user of |
519 | * a 64 bit program is a no-no. |
520 | */ |
521 | |
522 | /* |
523 | * Same as peek_user_per but for a 31 bit program. |
524 | */ |
525 | static inline __u32 __peek_user_per_compat(struct task_struct *child, |
526 | addr_t addr) |
527 | { |
528 | if (addr == offsetof(struct compat_per_struct_kernel, cr9)) |
529 | /* Control bits of the active per set. */ |
530 | return (__u32) test_thread_flag(TIF_SINGLE_STEP) ? |
531 | PER_EVENT_IFETCH : child->thread.per_user.control; |
532 | else if (addr == offsetof(struct compat_per_struct_kernel, cr10)) |
533 | /* Start address of the active per set. */ |
534 | return (__u32) test_thread_flag(TIF_SINGLE_STEP) ? |
535 | 0 : child->thread.per_user.start; |
536 | else if (addr == offsetof(struct compat_per_struct_kernel, cr11)) |
537 | /* End address of the active per set. */ |
538 | return test_thread_flag(TIF_SINGLE_STEP) ? |
539 | PSW32_ADDR_INSN : child->thread.per_user.end; |
540 | else if (addr == offsetof(struct compat_per_struct_kernel, bits)) |
541 | /* Single-step bit. */ |
542 | return (__u32) test_thread_flag(TIF_SINGLE_STEP) ? |
543 | 0x80000000 : 0; |
544 | else if (addr == offsetof(struct compat_per_struct_kernel, starting_addr)) |
545 | /* Start address of the user specified per set. */ |
546 | return (__u32) child->thread.per_user.start; |
547 | else if (addr == offsetof(struct compat_per_struct_kernel, ending_addr)) |
548 | /* End address of the user specified per set. */ |
549 | return (__u32) child->thread.per_user.end; |
550 | else if (addr == offsetof(struct compat_per_struct_kernel, perc_atmid)) |
551 | /* PER code, ATMID and AI of the last PER trap */ |
552 | return (__u32) child->thread.per_event.cause << 16; |
553 | else if (addr == offsetof(struct compat_per_struct_kernel, address)) |
554 | /* Address of the last PER trap */ |
555 | return (__u32) child->thread.per_event.address; |
556 | else if (addr == offsetof(struct compat_per_struct_kernel, access_id)) |
557 | /* Access id of the last PER trap */ |
558 | return (__u32) child->thread.per_event.paid << 24; |
559 | return 0; |
560 | } |
561 | |
562 | /* |
563 | * Same as peek_user but for a 31 bit program. |
564 | */ |
565 | static u32 __peek_user_compat(struct task_struct *child, addr_t addr) |
566 | { |
567 | addr_t offset; |
568 | __u32 tmp; |
569 | |
570 | if (addr < offsetof(struct compat_user, regs.acrs)) { |
571 | struct pt_regs *regs = task_pt_regs(child); |
572 | /* |
573 | * psw and gprs are stored on the stack |
574 | */ |
575 | if (addr == offsetof(struct compat_user, regs.psw.mask)) { |
576 | /* Fake a 31 bit psw mask. */ |
577 | tmp = (__u32)(regs->psw.mask >> 32); |
578 | tmp &= PSW32_MASK_USER | PSW32_MASK_RI; |
579 | tmp |= PSW32_USER_BITS; |
580 | } else if (addr == offsetof(struct compat_user, regs.psw.addr)) { |
581 | /* Fake a 31 bit psw address. */ |
582 | tmp = (__u32) regs->psw.addr | |
583 | (__u32)(regs->psw.mask & PSW_MASK_BA); |
584 | } else { |
585 | /* gpr 0-15 */ |
586 | tmp = *(__u32 *)((addr_t) ®s->psw + addr*2 + 4); |
587 | } |
588 | } else if (addr < offsetof(struct compat_user, regs.orig_gpr2)) { |
589 | /* |
590 | * access registers are stored in the thread structure |
591 | */ |
592 | offset = addr - offsetof(struct compat_user, regs.acrs); |
593 | tmp = *(__u32*)((addr_t) &child->thread.acrs + offset); |
594 | |
595 | } else if (addr == offsetof(struct compat_user, regs.orig_gpr2)) { |
596 | /* |
597 | * orig_gpr2 is stored on the kernel stack |
598 | */ |
599 | tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4); |
600 | |
601 | } else if (addr < offsetof(struct compat_user, regs.fp_regs)) { |
602 | /* |
603 | * prevent reads of padding hole between |
604 | * orig_gpr2 and fp_regs on s390. |
605 | */ |
606 | tmp = 0; |
607 | |
608 | } else if (addr == offsetof(struct compat_user, regs.fp_regs.fpc)) { |
609 | /* |
610 | * floating point control reg. is in the thread structure |
611 | */ |
612 | tmp = child->thread.ufpu.fpc; |
613 | |
614 | } else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) { |
615 | /* |
616 | * floating point regs. are in the child->thread.ufpu.vxrs array |
617 | */ |
618 | offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs); |
619 | tmp = *(__u32 *)((addr_t)child->thread.ufpu.vxrs + 2 * offset); |
620 | } else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) { |
621 | /* |
622 | * Handle access to the per_info structure. |
623 | */ |
624 | addr -= offsetof(struct compat_user, regs.per_info); |
625 | tmp = __peek_user_per_compat(child, addr); |
626 | |
627 | } else |
628 | tmp = 0; |
629 | |
630 | return tmp; |
631 | } |
632 | |
633 | static int peek_user_compat(struct task_struct *child, |
634 | addr_t addr, addr_t data) |
635 | { |
636 | __u32 tmp; |
637 | |
638 | if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user) - 3) |
639 | return -EIO; |
640 | |
641 | tmp = __peek_user_compat(child, addr); |
642 | return put_user(tmp, (__u32 __user *) data); |
643 | } |
644 | |
645 | /* |
646 | * Same as poke_user_per but for a 31 bit program. |
647 | */ |
648 | static inline void __poke_user_per_compat(struct task_struct *child, |
649 | addr_t addr, __u32 data) |
650 | { |
651 | if (addr == offsetof(struct compat_per_struct_kernel, cr9)) |
652 | /* PER event mask of the user specified per set. */ |
653 | child->thread.per_user.control = |
654 | data & (PER_EVENT_MASK | PER_CONTROL_MASK); |
655 | else if (addr == offsetof(struct compat_per_struct_kernel, starting_addr)) |
656 | /* Starting address of the user specified per set. */ |
657 | child->thread.per_user.start = data; |
658 | else if (addr == offsetof(struct compat_per_struct_kernel, ending_addr)) |
659 | /* Ending address of the user specified per set. */ |
660 | child->thread.per_user.end = data; |
661 | } |
662 | |
663 | /* |
664 | * Same as poke_user but for a 31 bit program. |
665 | */ |
666 | static int __poke_user_compat(struct task_struct *child, |
667 | addr_t addr, addr_t data) |
668 | { |
669 | __u32 tmp = (__u32) data; |
670 | addr_t offset; |
671 | |
672 | if (addr < offsetof(struct compat_user, regs.acrs)) { |
673 | struct pt_regs *regs = task_pt_regs(child); |
674 | /* |
675 | * psw, gprs, acrs and orig_gpr2 are stored on the stack |
676 | */ |
677 | if (addr == offsetof(struct compat_user, regs.psw.mask)) { |
678 | __u32 mask = PSW32_MASK_USER; |
679 | |
680 | mask |= is_ri_task(child) ? PSW32_MASK_RI : 0; |
681 | /* Build a 64 bit psw mask from 31 bit mask. */ |
682 | if ((tmp ^ PSW32_USER_BITS) & ~mask) |
683 | /* Invalid psw mask. */ |
684 | return -EINVAL; |
685 | if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME) |
686 | /* Invalid address-space-control bits */ |
687 | return -EINVAL; |
688 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
689 | (regs->psw.mask & PSW_MASK_BA) | |
690 | (__u64)(tmp & mask) << 32; |
691 | } else if (addr == offsetof(struct compat_user, regs.psw.addr)) { |
692 | /* Build a 64 bit psw address from 31 bit address. */ |
693 | regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN; |
694 | /* Transfer 31 bit amode bit to psw mask. */ |
695 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) | |
696 | (__u64)(tmp & PSW32_ADDR_AMODE); |
697 | } else { |
698 | if (test_pt_regs_flag(regs, PIF_SYSCALL) && |
699 | addr == offsetof(struct compat_user, regs.gprs[2])) { |
700 | struct pt_regs *regs = task_pt_regs(child); |
701 | |
702 | regs->int_code = 0x20000 | (data & 0xffff); |
703 | } |
704 | /* gpr 0-15 */ |
705 | *(__u32*)((addr_t) ®s->psw + addr*2 + 4) = tmp; |
706 | } |
707 | } else if (addr < offsetof(struct compat_user, regs.orig_gpr2)) { |
708 | /* |
709 | * access registers are stored in the thread structure |
710 | */ |
711 | offset = addr - offsetof(struct compat_user, regs.acrs); |
712 | *(__u32*)((addr_t) &child->thread.acrs + offset) = tmp; |
713 | |
714 | } else if (addr == offsetof(struct compat_user, regs.orig_gpr2)) { |
715 | /* |
716 | * orig_gpr2 is stored on the kernel stack |
717 | */ |
718 | *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp; |
719 | |
720 | } else if (addr < offsetof(struct compat_user, regs.fp_regs)) { |
721 | /* |
722 | * prevent writess of padding hole between |
723 | * orig_gpr2 and fp_regs on s390. |
724 | */ |
725 | return 0; |
726 | |
727 | } else if (addr == offsetof(struct compat_user, regs.fp_regs.fpc)) { |
728 | /* |
729 | * floating point control reg. is in the thread structure |
730 | */ |
731 | child->thread.ufpu.fpc = data; |
732 | |
733 | } else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) { |
734 | /* |
735 | * floating point regs. are in the child->thread.ufpu.vxrs array |
736 | */ |
737 | offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs); |
738 | *(__u32 *)((addr_t)child->thread.ufpu.vxrs + 2 * offset) = tmp; |
739 | } else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) { |
740 | /* |
741 | * Handle access to the per_info structure. |
742 | */ |
743 | addr -= offsetof(struct compat_user, regs.per_info); |
744 | __poke_user_per_compat(child, addr, data); |
745 | } |
746 | |
747 | return 0; |
748 | } |
749 | |
750 | static int poke_user_compat(struct task_struct *child, |
751 | addr_t addr, addr_t data) |
752 | { |
753 | if (!is_compat_task() || (addr & 3) || |
754 | addr > sizeof(struct compat_user) - 3) |
755 | return -EIO; |
756 | |
757 | return __poke_user_compat(child, addr, data); |
758 | } |
759 | |
760 | long compat_arch_ptrace(struct task_struct *child, compat_long_t request, |
761 | compat_ulong_t caddr, compat_ulong_t cdata) |
762 | { |
763 | unsigned long addr = caddr; |
764 | unsigned long data = cdata; |
765 | compat_ptrace_area parea; |
766 | int copied, ret; |
767 | |
768 | switch (request) { |
769 | case PTRACE_PEEKUSR: |
770 | /* read the word at location addr in the USER area. */ |
771 | return peek_user_compat(child, addr, data); |
772 | |
773 | case PTRACE_POKEUSR: |
774 | /* write the word at location addr in the USER area */ |
775 | return poke_user_compat(child, addr, data); |
776 | |
777 | case PTRACE_PEEKUSR_AREA: |
778 | case PTRACE_POKEUSR_AREA: |
779 | if (copy_from_user(to: &parea, from: (void __force __user *) addr, |
780 | n: sizeof(parea))) |
781 | return -EFAULT; |
782 | addr = parea.kernel_addr; |
783 | data = parea.process_addr; |
784 | copied = 0; |
785 | while (copied < parea.len) { |
786 | if (request == PTRACE_PEEKUSR_AREA) |
787 | ret = peek_user_compat(child, addr, data); |
788 | else { |
789 | __u32 utmp; |
790 | if (get_user(utmp, |
791 | (__u32 __force __user *) data)) |
792 | return -EFAULT; |
793 | ret = poke_user_compat(child, addr, utmp); |
794 | } |
795 | if (ret) |
796 | return ret; |
797 | addr += sizeof(unsigned int); |
798 | data += sizeof(unsigned int); |
799 | copied += sizeof(unsigned int); |
800 | } |
801 | return 0; |
802 | case PTRACE_GET_LAST_BREAK: |
803 | return put_user(child->thread.last_break, (unsigned int __user *)data); |
804 | } |
805 | return compat_ptrace_request(child, request, addr, data); |
806 | } |
807 | #endif |
808 | |
809 | /* |
810 | * user_regset definitions. |
811 | */ |
812 | |
813 | static int s390_regs_get(struct task_struct *target, |
814 | const struct user_regset *regset, |
815 | struct membuf to) |
816 | { |
817 | unsigned pos; |
818 | if (target == current) |
819 | save_access_regs(target->thread.acrs); |
820 | |
821 | for (pos = 0; pos < sizeof(s390_regs); pos += sizeof(long)) |
822 | membuf_store(&to, __peek_user(target, pos)); |
823 | return 0; |
824 | } |
825 | |
826 | static int s390_regs_set(struct task_struct *target, |
827 | const struct user_regset *regset, |
828 | unsigned int pos, unsigned int count, |
829 | const void *kbuf, const void __user *ubuf) |
830 | { |
831 | int rc = 0; |
832 | |
833 | if (target == current) |
834 | save_access_regs(target->thread.acrs); |
835 | |
836 | if (kbuf) { |
837 | const unsigned long *k = kbuf; |
838 | while (count > 0 && !rc) { |
839 | rc = __poke_user(target, pos, *k++); |
840 | count -= sizeof(*k); |
841 | pos += sizeof(*k); |
842 | } |
843 | } else { |
844 | const unsigned long __user *u = ubuf; |
845 | while (count > 0 && !rc) { |
846 | unsigned long word; |
847 | rc = __get_user(word, u++); |
848 | if (rc) |
849 | break; |
850 | rc = __poke_user(target, pos, word); |
851 | count -= sizeof(*u); |
852 | pos += sizeof(*u); |
853 | } |
854 | } |
855 | |
856 | if (rc == 0 && target == current) |
857 | restore_access_regs(target->thread.acrs); |
858 | |
859 | return rc; |
860 | } |
861 | |
862 | static int s390_fpregs_get(struct task_struct *target, |
863 | const struct user_regset *regset, |
864 | struct membuf to) |
865 | { |
866 | _s390_fp_regs fp_regs; |
867 | |
868 | if (target == current) |
869 | save_user_fpu_regs(); |
870 | |
871 | fp_regs.fpc = target->thread.ufpu.fpc; |
872 | fpregs_store(&fp_regs, &target->thread.ufpu); |
873 | |
874 | return membuf_write(&to, &fp_regs, sizeof(fp_regs)); |
875 | } |
876 | |
877 | static int s390_fpregs_set(struct task_struct *target, |
878 | const struct user_regset *regset, unsigned int pos, |
879 | unsigned int count, const void *kbuf, |
880 | const void __user *ubuf) |
881 | { |
882 | int rc = 0; |
883 | freg_t fprs[__NUM_FPRS]; |
884 | |
885 | if (target == current) |
886 | save_user_fpu_regs(); |
887 | convert_vx_to_fp(fprs, target->thread.ufpu.vxrs); |
888 | if (count > 0 && pos < offsetof(s390_fp_regs, fprs)) { |
889 | u32 ufpc[2] = { target->thread.ufpu.fpc, 0 }; |
890 | rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ufpc, |
891 | 0, offsetof(s390_fp_regs, fprs)); |
892 | if (rc) |
893 | return rc; |
894 | if (ufpc[1] != 0) |
895 | return -EINVAL; |
896 | target->thread.ufpu.fpc = ufpc[0]; |
897 | } |
898 | |
899 | if (rc == 0 && count > 0) |
900 | rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
901 | fprs, offsetof(s390_fp_regs, fprs), -1); |
902 | if (rc) |
903 | return rc; |
904 | convert_fp_to_vx(target->thread.ufpu.vxrs, fprs); |
905 | return rc; |
906 | } |
907 | |
908 | static int s390_last_break_get(struct task_struct *target, |
909 | const struct user_regset *regset, |
910 | struct membuf to) |
911 | { |
912 | return membuf_store(&to, target->thread.last_break); |
913 | } |
914 | |
915 | static int s390_last_break_set(struct task_struct *target, |
916 | const struct user_regset *regset, |
917 | unsigned int pos, unsigned int count, |
918 | const void *kbuf, const void __user *ubuf) |
919 | { |
920 | return 0; |
921 | } |
922 | |
923 | static int s390_tdb_get(struct task_struct *target, |
924 | const struct user_regset *regset, |
925 | struct membuf to) |
926 | { |
927 | struct pt_regs *regs = task_pt_regs(target); |
928 | size_t size; |
929 | |
930 | if (!(regs->int_code & 0x200)) |
931 | return -ENODATA; |
932 | size = sizeof(target->thread.trap_tdb.data); |
933 | return membuf_write(s: &to, v: target->thread.trap_tdb.data, size); |
934 | } |
935 | |
936 | static int s390_tdb_set(struct task_struct *target, |
937 | const struct user_regset *regset, |
938 | unsigned int pos, unsigned int count, |
939 | const void *kbuf, const void __user *ubuf) |
940 | { |
941 | return 0; |
942 | } |
943 | |
944 | static int s390_vxrs_low_get(struct task_struct *target, |
945 | const struct user_regset *regset, |
946 | struct membuf to) |
947 | { |
948 | __u64 vxrs[__NUM_VXRS_LOW]; |
949 | int i; |
950 | |
951 | if (!cpu_has_vx()) |
952 | return -ENODEV; |
953 | if (target == current) |
954 | save_user_fpu_regs(); |
955 | for (i = 0; i < __NUM_VXRS_LOW; i++) |
956 | vxrs[i] = target->thread.ufpu.vxrs[i].low; |
957 | return membuf_write(s: &to, v: vxrs, size: sizeof(vxrs)); |
958 | } |
959 | |
960 | static int s390_vxrs_low_set(struct task_struct *target, |
961 | const struct user_regset *regset, |
962 | unsigned int pos, unsigned int count, |
963 | const void *kbuf, const void __user *ubuf) |
964 | { |
965 | __u64 vxrs[__NUM_VXRS_LOW]; |
966 | int i, rc; |
967 | |
968 | if (!cpu_has_vx()) |
969 | return -ENODEV; |
970 | if (target == current) |
971 | save_user_fpu_regs(); |
972 | |
973 | for (i = 0; i < __NUM_VXRS_LOW; i++) |
974 | vxrs[i] = target->thread.ufpu.vxrs[i].low; |
975 | |
976 | rc = user_regset_copyin(pos: &pos, count: &count, kbuf: &kbuf, ubuf: &ubuf, data: vxrs, start_pos: 0, end_pos: -1); |
977 | if (rc == 0) |
978 | for (i = 0; i < __NUM_VXRS_LOW; i++) |
979 | target->thread.ufpu.vxrs[i].low = vxrs[i]; |
980 | |
981 | return rc; |
982 | } |
983 | |
984 | static int s390_vxrs_high_get(struct task_struct *target, |
985 | const struct user_regset *regset, |
986 | struct membuf to) |
987 | { |
988 | if (!cpu_has_vx()) |
989 | return -ENODEV; |
990 | if (target == current) |
991 | save_user_fpu_regs(); |
992 | return membuf_write(&to, target->thread.ufpu.vxrs + __NUM_VXRS_LOW, |
993 | __NUM_VXRS_HIGH * sizeof(__vector128)); |
994 | } |
995 | |
996 | static int s390_vxrs_high_set(struct task_struct *target, |
997 | const struct user_regset *regset, |
998 | unsigned int pos, unsigned int count, |
999 | const void *kbuf, const void __user *ubuf) |
1000 | { |
1001 | int rc; |
1002 | |
1003 | if (!cpu_has_vx()) |
1004 | return -ENODEV; |
1005 | if (target == current) |
1006 | save_user_fpu_regs(); |
1007 | |
1008 | rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
1009 | target->thread.ufpu.vxrs + __NUM_VXRS_LOW, 0, -1); |
1010 | return rc; |
1011 | } |
1012 | |
1013 | static int s390_system_call_get(struct task_struct *target, |
1014 | const struct user_regset *regset, |
1015 | struct membuf to) |
1016 | { |
1017 | return membuf_store(&to, target->thread.system_call); |
1018 | } |
1019 | |
1020 | static int s390_system_call_set(struct task_struct *target, |
1021 | const struct user_regset *regset, |
1022 | unsigned int pos, unsigned int count, |
1023 | const void *kbuf, const void __user *ubuf) |
1024 | { |
1025 | unsigned int *data = &target->thread.system_call; |
1026 | return user_regset_copyin(pos: &pos, count: &count, kbuf: &kbuf, ubuf: &ubuf, |
1027 | data, start_pos: 0, end_pos: sizeof(unsigned int)); |
1028 | } |
1029 | |
1030 | static int s390_gs_cb_get(struct task_struct *target, |
1031 | const struct user_regset *regset, |
1032 | struct membuf to) |
1033 | { |
1034 | struct gs_cb *data = target->thread.gs_cb; |
1035 | |
1036 | if (!MACHINE_HAS_GS) |
1037 | return -ENODEV; |
1038 | if (!data) |
1039 | return -ENODATA; |
1040 | if (target == current) |
1041 | save_gs_cb(data); |
1042 | return membuf_write(&to, data, sizeof(struct gs_cb)); |
1043 | } |
1044 | |
1045 | static int s390_gs_cb_set(struct task_struct *target, |
1046 | const struct user_regset *regset, |
1047 | unsigned int pos, unsigned int count, |
1048 | const void *kbuf, const void __user *ubuf) |
1049 | { |
1050 | struct gs_cb gs_cb = { }, *data = NULL; |
1051 | int rc; |
1052 | |
1053 | if (!MACHINE_HAS_GS) |
1054 | return -ENODEV; |
1055 | if (!target->thread.gs_cb) { |
1056 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
1057 | if (!data) |
1058 | return -ENOMEM; |
1059 | } |
1060 | if (!target->thread.gs_cb) |
1061 | gs_cb.gsd = 25; |
1062 | else if (target == current) |
1063 | save_gs_cb(&gs_cb); |
1064 | else |
1065 | gs_cb = *target->thread.gs_cb; |
1066 | rc = user_regset_copyin(pos: &pos, count: &count, kbuf: &kbuf, ubuf: &ubuf, |
1067 | data: &gs_cb, start_pos: 0, end_pos: sizeof(gs_cb)); |
1068 | if (rc) { |
1069 | kfree(objp: data); |
1070 | return -EFAULT; |
1071 | } |
1072 | preempt_disable(); |
1073 | if (!target->thread.gs_cb) |
1074 | target->thread.gs_cb = data; |
1075 | *target->thread.gs_cb = gs_cb; |
1076 | if (target == current) { |
1077 | local_ctl_set_bit(2, CR2_GUARDED_STORAGE_BIT); |
1078 | restore_gs_cb(target->thread.gs_cb); |
1079 | } |
1080 | preempt_enable(); |
1081 | return rc; |
1082 | } |
1083 | |
1084 | static int s390_gs_bc_get(struct task_struct *target, |
1085 | const struct user_regset *regset, |
1086 | struct membuf to) |
1087 | { |
1088 | struct gs_cb *data = target->thread.gs_bc_cb; |
1089 | |
1090 | if (!MACHINE_HAS_GS) |
1091 | return -ENODEV; |
1092 | if (!data) |
1093 | return -ENODATA; |
1094 | return membuf_write(&to, data, sizeof(struct gs_cb)); |
1095 | } |
1096 | |
1097 | static int s390_gs_bc_set(struct task_struct *target, |
1098 | const struct user_regset *regset, |
1099 | unsigned int pos, unsigned int count, |
1100 | const void *kbuf, const void __user *ubuf) |
1101 | { |
1102 | struct gs_cb *data = target->thread.gs_bc_cb; |
1103 | |
1104 | if (!MACHINE_HAS_GS) |
1105 | return -ENODEV; |
1106 | if (!data) { |
1107 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
1108 | if (!data) |
1109 | return -ENOMEM; |
1110 | target->thread.gs_bc_cb = data; |
1111 | } |
1112 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
1113 | data, 0, sizeof(struct gs_cb)); |
1114 | } |
1115 | |
1116 | static bool is_ri_cb_valid(struct runtime_instr_cb *cb) |
1117 | { |
1118 | return (cb->rca & 0x1f) == 0 && |
1119 | (cb->roa & 0xfff) == 0 && |
1120 | (cb->rla & 0xfff) == 0xfff && |
1121 | cb->s == 1 && |
1122 | cb->k == 1 && |
1123 | cb->h == 0 && |
1124 | cb->reserved1 == 0 && |
1125 | cb->ps == 1 && |
1126 | cb->qs == 0 && |
1127 | cb->pc == 1 && |
1128 | cb->qc == 0 && |
1129 | cb->reserved2 == 0 && |
1130 | cb->reserved3 == 0 && |
1131 | cb->reserved4 == 0 && |
1132 | cb->reserved5 == 0 && |
1133 | cb->reserved6 == 0 && |
1134 | cb->reserved7 == 0 && |
1135 | cb->reserved8 == 0 && |
1136 | cb->rla >= cb->roa && |
1137 | cb->rca >= cb->roa && |
1138 | cb->rca <= cb->rla+1 && |
1139 | cb->m < 3; |
1140 | } |
1141 | |
1142 | static int s390_runtime_instr_get(struct task_struct *target, |
1143 | const struct user_regset *regset, |
1144 | struct membuf to) |
1145 | { |
1146 | struct runtime_instr_cb *data = target->thread.ri_cb; |
1147 | |
1148 | if (!test_facility(64)) |
1149 | return -ENODEV; |
1150 | if (!data) |
1151 | return -ENODATA; |
1152 | |
1153 | return membuf_write(&to, data, sizeof(struct runtime_instr_cb)); |
1154 | } |
1155 | |
1156 | static int s390_runtime_instr_set(struct task_struct *target, |
1157 | const struct user_regset *regset, |
1158 | unsigned int pos, unsigned int count, |
1159 | const void *kbuf, const void __user *ubuf) |
1160 | { |
1161 | struct runtime_instr_cb ri_cb = { }, *data = NULL; |
1162 | int rc; |
1163 | |
1164 | if (!test_facility(64)) |
1165 | return -ENODEV; |
1166 | |
1167 | if (!target->thread.ri_cb) { |
1168 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
1169 | if (!data) |
1170 | return -ENOMEM; |
1171 | } |
1172 | |
1173 | if (target->thread.ri_cb) { |
1174 | if (target == current) |
1175 | store_runtime_instr_cb(&ri_cb); |
1176 | else |
1177 | ri_cb = *target->thread.ri_cb; |
1178 | } |
1179 | |
1180 | rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
1181 | &ri_cb, 0, sizeof(struct runtime_instr_cb)); |
1182 | if (rc) { |
1183 | kfree(objp: data); |
1184 | return -EFAULT; |
1185 | } |
1186 | |
1187 | if (!is_ri_cb_valid(cb: &ri_cb)) { |
1188 | kfree(objp: data); |
1189 | return -EINVAL; |
1190 | } |
1191 | /* |
1192 | * Override access key in any case, since user space should |
1193 | * not be able to set it, nor should it care about it. |
1194 | */ |
1195 | ri_cb.key = PAGE_DEFAULT_KEY >> 4; |
1196 | preempt_disable(); |
1197 | if (!target->thread.ri_cb) |
1198 | target->thread.ri_cb = data; |
1199 | *target->thread.ri_cb = ri_cb; |
1200 | if (target == current) |
1201 | load_runtime_instr_cb(target->thread.ri_cb); |
1202 | preempt_enable(); |
1203 | |
1204 | return 0; |
1205 | } |
1206 | |
1207 | static const struct user_regset s390_regsets[] = { |
1208 | { |
1209 | .core_note_type = NT_PRSTATUS, |
1210 | .n = sizeof(s390_regs) / sizeof(long), |
1211 | .size = sizeof(long), |
1212 | .align = sizeof(long), |
1213 | .regset_get = s390_regs_get, |
1214 | .set = s390_regs_set, |
1215 | }, |
1216 | { |
1217 | .core_note_type = NT_PRFPREG, |
1218 | .n = sizeof(s390_fp_regs) / sizeof(long), |
1219 | .size = sizeof(long), |
1220 | .align = sizeof(long), |
1221 | .regset_get = s390_fpregs_get, |
1222 | .set = s390_fpregs_set, |
1223 | }, |
1224 | { |
1225 | .core_note_type = NT_S390_SYSTEM_CALL, |
1226 | .n = 1, |
1227 | .size = sizeof(unsigned int), |
1228 | .align = sizeof(unsigned int), |
1229 | .regset_get = s390_system_call_get, |
1230 | .set = s390_system_call_set, |
1231 | }, |
1232 | { |
1233 | .core_note_type = NT_S390_LAST_BREAK, |
1234 | .n = 1, |
1235 | .size = sizeof(long), |
1236 | .align = sizeof(long), |
1237 | .regset_get = s390_last_break_get, |
1238 | .set = s390_last_break_set, |
1239 | }, |
1240 | { |
1241 | .core_note_type = NT_S390_TDB, |
1242 | .n = 1, |
1243 | .size = 256, |
1244 | .align = 1, |
1245 | .regset_get = s390_tdb_get, |
1246 | .set = s390_tdb_set, |
1247 | }, |
1248 | { |
1249 | .core_note_type = NT_S390_VXRS_LOW, |
1250 | .n = __NUM_VXRS_LOW, |
1251 | .size = sizeof(__u64), |
1252 | .align = sizeof(__u64), |
1253 | .regset_get = s390_vxrs_low_get, |
1254 | .set = s390_vxrs_low_set, |
1255 | }, |
1256 | { |
1257 | .core_note_type = NT_S390_VXRS_HIGH, |
1258 | .n = __NUM_VXRS_HIGH, |
1259 | .size = sizeof(__vector128), |
1260 | .align = sizeof(__vector128), |
1261 | .regset_get = s390_vxrs_high_get, |
1262 | .set = s390_vxrs_high_set, |
1263 | }, |
1264 | { |
1265 | .core_note_type = NT_S390_GS_CB, |
1266 | .n = sizeof(struct gs_cb) / sizeof(__u64), |
1267 | .size = sizeof(__u64), |
1268 | .align = sizeof(__u64), |
1269 | .regset_get = s390_gs_cb_get, |
1270 | .set = s390_gs_cb_set, |
1271 | }, |
1272 | { |
1273 | .core_note_type = NT_S390_GS_BC, |
1274 | .n = sizeof(struct gs_cb) / sizeof(__u64), |
1275 | .size = sizeof(__u64), |
1276 | .align = sizeof(__u64), |
1277 | .regset_get = s390_gs_bc_get, |
1278 | .set = s390_gs_bc_set, |
1279 | }, |
1280 | { |
1281 | .core_note_type = NT_S390_RI_CB, |
1282 | .n = sizeof(struct runtime_instr_cb) / sizeof(__u64), |
1283 | .size = sizeof(__u64), |
1284 | .align = sizeof(__u64), |
1285 | .regset_get = s390_runtime_instr_get, |
1286 | .set = s390_runtime_instr_set, |
1287 | }, |
1288 | }; |
1289 | |
1290 | static const struct user_regset_view user_s390_view = { |
1291 | .name = "s390x" , |
1292 | .e_machine = EM_S390, |
1293 | .regsets = s390_regsets, |
1294 | .n = ARRAY_SIZE(s390_regsets) |
1295 | }; |
1296 | |
1297 | #ifdef CONFIG_COMPAT |
1298 | static int s390_compat_regs_get(struct task_struct *target, |
1299 | const struct user_regset *regset, |
1300 | struct membuf to) |
1301 | { |
1302 | unsigned n; |
1303 | |
1304 | if (target == current) |
1305 | save_access_regs(target->thread.acrs); |
1306 | |
1307 | for (n = 0; n < sizeof(s390_compat_regs); n += sizeof(compat_ulong_t)) |
1308 | membuf_store(&to, __peek_user_compat(target, n)); |
1309 | return 0; |
1310 | } |
1311 | |
1312 | static int s390_compat_regs_set(struct task_struct *target, |
1313 | const struct user_regset *regset, |
1314 | unsigned int pos, unsigned int count, |
1315 | const void *kbuf, const void __user *ubuf) |
1316 | { |
1317 | int rc = 0; |
1318 | |
1319 | if (target == current) |
1320 | save_access_regs(target->thread.acrs); |
1321 | |
1322 | if (kbuf) { |
1323 | const compat_ulong_t *k = kbuf; |
1324 | while (count > 0 && !rc) { |
1325 | rc = __poke_user_compat(target, pos, *k++); |
1326 | count -= sizeof(*k); |
1327 | pos += sizeof(*k); |
1328 | } |
1329 | } else { |
1330 | const compat_ulong_t __user *u = ubuf; |
1331 | while (count > 0 && !rc) { |
1332 | compat_ulong_t word; |
1333 | rc = __get_user(word, u++); |
1334 | if (rc) |
1335 | break; |
1336 | rc = __poke_user_compat(target, pos, word); |
1337 | count -= sizeof(*u); |
1338 | pos += sizeof(*u); |
1339 | } |
1340 | } |
1341 | |
1342 | if (rc == 0 && target == current) |
1343 | restore_access_regs(target->thread.acrs); |
1344 | |
1345 | return rc; |
1346 | } |
1347 | |
1348 | static int s390_compat_regs_high_get(struct task_struct *target, |
1349 | const struct user_regset *regset, |
1350 | struct membuf to) |
1351 | { |
1352 | compat_ulong_t *gprs_high; |
1353 | int i; |
1354 | |
1355 | gprs_high = (compat_ulong_t *)task_pt_regs(target)->gprs; |
1356 | for (i = 0; i < NUM_GPRS; i++, gprs_high += 2) |
1357 | membuf_store(&to, *gprs_high); |
1358 | return 0; |
1359 | } |
1360 | |
1361 | static int s390_compat_regs_high_set(struct task_struct *target, |
1362 | const struct user_regset *regset, |
1363 | unsigned int pos, unsigned int count, |
1364 | const void *kbuf, const void __user *ubuf) |
1365 | { |
1366 | compat_ulong_t *gprs_high; |
1367 | int rc = 0; |
1368 | |
1369 | gprs_high = (compat_ulong_t *) |
1370 | &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)]; |
1371 | if (kbuf) { |
1372 | const compat_ulong_t *k = kbuf; |
1373 | while (count > 0) { |
1374 | *gprs_high = *k++; |
1375 | *gprs_high += 2; |
1376 | count -= sizeof(*k); |
1377 | } |
1378 | } else { |
1379 | const compat_ulong_t __user *u = ubuf; |
1380 | while (count > 0 && !rc) { |
1381 | unsigned long word; |
1382 | rc = __get_user(word, u++); |
1383 | if (rc) |
1384 | break; |
1385 | *gprs_high = word; |
1386 | *gprs_high += 2; |
1387 | count -= sizeof(*u); |
1388 | } |
1389 | } |
1390 | |
1391 | return rc; |
1392 | } |
1393 | |
1394 | static int s390_compat_last_break_get(struct task_struct *target, |
1395 | const struct user_regset *regset, |
1396 | struct membuf to) |
1397 | { |
1398 | compat_ulong_t last_break = target->thread.last_break; |
1399 | |
1400 | return membuf_store(&to, (unsigned long)last_break); |
1401 | } |
1402 | |
1403 | static int s390_compat_last_break_set(struct task_struct *target, |
1404 | const struct user_regset *regset, |
1405 | unsigned int pos, unsigned int count, |
1406 | const void *kbuf, const void __user *ubuf) |
1407 | { |
1408 | return 0; |
1409 | } |
1410 | |
1411 | static const struct user_regset s390_compat_regsets[] = { |
1412 | { |
1413 | .core_note_type = NT_PRSTATUS, |
1414 | .n = sizeof(s390_compat_regs) / sizeof(compat_long_t), |
1415 | .size = sizeof(compat_long_t), |
1416 | .align = sizeof(compat_long_t), |
1417 | .regset_get = s390_compat_regs_get, |
1418 | .set = s390_compat_regs_set, |
1419 | }, |
1420 | { |
1421 | .core_note_type = NT_PRFPREG, |
1422 | .n = sizeof(s390_fp_regs) / sizeof(compat_long_t), |
1423 | .size = sizeof(compat_long_t), |
1424 | .align = sizeof(compat_long_t), |
1425 | .regset_get = s390_fpregs_get, |
1426 | .set = s390_fpregs_set, |
1427 | }, |
1428 | { |
1429 | .core_note_type = NT_S390_SYSTEM_CALL, |
1430 | .n = 1, |
1431 | .size = sizeof(compat_uint_t), |
1432 | .align = sizeof(compat_uint_t), |
1433 | .regset_get = s390_system_call_get, |
1434 | .set = s390_system_call_set, |
1435 | }, |
1436 | { |
1437 | .core_note_type = NT_S390_LAST_BREAK, |
1438 | .n = 1, |
1439 | .size = sizeof(long), |
1440 | .align = sizeof(long), |
1441 | .regset_get = s390_compat_last_break_get, |
1442 | .set = s390_compat_last_break_set, |
1443 | }, |
1444 | { |
1445 | .core_note_type = NT_S390_TDB, |
1446 | .n = 1, |
1447 | .size = 256, |
1448 | .align = 1, |
1449 | .regset_get = s390_tdb_get, |
1450 | .set = s390_tdb_set, |
1451 | }, |
1452 | { |
1453 | .core_note_type = NT_S390_VXRS_LOW, |
1454 | .n = __NUM_VXRS_LOW, |
1455 | .size = sizeof(__u64), |
1456 | .align = sizeof(__u64), |
1457 | .regset_get = s390_vxrs_low_get, |
1458 | .set = s390_vxrs_low_set, |
1459 | }, |
1460 | { |
1461 | .core_note_type = NT_S390_VXRS_HIGH, |
1462 | .n = __NUM_VXRS_HIGH, |
1463 | .size = sizeof(__vector128), |
1464 | .align = sizeof(__vector128), |
1465 | .regset_get = s390_vxrs_high_get, |
1466 | .set = s390_vxrs_high_set, |
1467 | }, |
1468 | { |
1469 | .core_note_type = NT_S390_HIGH_GPRS, |
1470 | .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t), |
1471 | .size = sizeof(compat_long_t), |
1472 | .align = sizeof(compat_long_t), |
1473 | .regset_get = s390_compat_regs_high_get, |
1474 | .set = s390_compat_regs_high_set, |
1475 | }, |
1476 | { |
1477 | .core_note_type = NT_S390_GS_CB, |
1478 | .n = sizeof(struct gs_cb) / sizeof(__u64), |
1479 | .size = sizeof(__u64), |
1480 | .align = sizeof(__u64), |
1481 | .regset_get = s390_gs_cb_get, |
1482 | .set = s390_gs_cb_set, |
1483 | }, |
1484 | { |
1485 | .core_note_type = NT_S390_GS_BC, |
1486 | .n = sizeof(struct gs_cb) / sizeof(__u64), |
1487 | .size = sizeof(__u64), |
1488 | .align = sizeof(__u64), |
1489 | .regset_get = s390_gs_bc_get, |
1490 | .set = s390_gs_bc_set, |
1491 | }, |
1492 | { |
1493 | .core_note_type = NT_S390_RI_CB, |
1494 | .n = sizeof(struct runtime_instr_cb) / sizeof(__u64), |
1495 | .size = sizeof(__u64), |
1496 | .align = sizeof(__u64), |
1497 | .regset_get = s390_runtime_instr_get, |
1498 | .set = s390_runtime_instr_set, |
1499 | }, |
1500 | }; |
1501 | |
1502 | static const struct user_regset_view user_s390_compat_view = { |
1503 | .name = "s390" , |
1504 | .e_machine = EM_S390, |
1505 | .regsets = s390_compat_regsets, |
1506 | .n = ARRAY_SIZE(s390_compat_regsets) |
1507 | }; |
1508 | #endif |
1509 | |
1510 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) |
1511 | { |
1512 | #ifdef CONFIG_COMPAT |
1513 | if (test_tsk_thread_flag(task, TIF_31BIT)) |
1514 | return &user_s390_compat_view; |
1515 | #endif |
1516 | return &user_s390_view; |
1517 | } |
1518 | |
1519 | static const char *gpr_names[NUM_GPRS] = { |
1520 | "r0" , "r1" , "r2" , "r3" , "r4" , "r5" , "r6" , "r7" , |
1521 | "r8" , "r9" , "r10" , "r11" , "r12" , "r13" , "r14" , "r15" , |
1522 | }; |
1523 | |
1524 | unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset) |
1525 | { |
1526 | if (offset >= NUM_GPRS) |
1527 | return 0; |
1528 | return regs->gprs[offset]; |
1529 | } |
1530 | |
1531 | int regs_query_register_offset(const char *name) |
1532 | { |
1533 | unsigned long offset; |
1534 | |
1535 | if (!name || *name != 'r') |
1536 | return -EINVAL; |
1537 | if (kstrtoul(s: name + 1, base: 10, res: &offset)) |
1538 | return -EINVAL; |
1539 | if (offset >= NUM_GPRS) |
1540 | return -EINVAL; |
1541 | return offset; |
1542 | } |
1543 | |
1544 | const char *regs_query_register_name(unsigned int offset) |
1545 | { |
1546 | if (offset >= NUM_GPRS) |
1547 | return NULL; |
1548 | return gpr_names[offset]; |
1549 | } |
1550 | |
1551 | static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) |
1552 | { |
1553 | unsigned long ksp = kernel_stack_pointer(regs); |
1554 | |
1555 | return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1)); |
1556 | } |
1557 | |
1558 | /** |
1559 | * regs_get_kernel_stack_nth() - get Nth entry of the stack |
1560 | * @regs:pt_regs which contains kernel stack pointer. |
1561 | * @n:stack entry number. |
1562 | * |
1563 | * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which |
1564 | * is specifined by @regs. If the @n th entry is NOT in the kernel stack, |
1565 | * this returns 0. |
1566 | */ |
1567 | unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) |
1568 | { |
1569 | unsigned long addr; |
1570 | |
1571 | addr = kernel_stack_pointer(regs) + n * sizeof(long); |
1572 | if (!regs_within_kernel_stack(regs, addr)) |
1573 | return 0; |
1574 | return *(unsigned long *)addr; |
1575 | } |
1576 | |