blob: 5dc7ad9e2fbf2d1b035194b30db18a82957c1358 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +01002 * Ptrace user space interface.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
Heiko Carstensa53c8fa2012-07-20 11:15:04 +02004 * Copyright IBM Corp. 1999, 2010
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +01005 * Author(s): Denis Joseph Barrow
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 * Martin Schwidefsky (schwidefsky@de.ibm.com)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 */
8
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/mm.h>
12#include <linux/smp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/errno.h>
14#include <linux/ptrace.h>
15#include <linux/user.h>
16#include <linux/security.h>
17#include <linux/audit.h>
Jesper Juhl7ed20e12005-05-01 08:59:14 -070018#include <linux/signal.h>
Martin Schwidefsky63506c42008-07-14 09:58:54 +020019#include <linux/elf.h>
20#include <linux/regset.h>
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +020021#include <linux/tracehook.h>
Heiko Carstensbcf5cef2009-06-12 10:26:26 +020022#include <linux/seccomp.h>
Heiko Carstens048cd4e2012-02-27 10:01:52 +010023#include <linux/compat.h>
Heiko Carstens9bf12262009-06-12 10:26:47 +020024#include <trace/syscall.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <asm/segment.h>
26#include <asm/page.h>
27#include <asm/pgtable.h>
28#include <asm/pgalloc.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <asm/uaccess.h>
Martin Schwidefsky778959d2005-06-04 15:43:30 -070030#include <asm/unistd.h>
David Howellsa0616cd2012-03-28 18:30:02 +010031#include <asm/switch_to.h>
Heiko Carstensa8061702008-04-17 07:46:26 +020032#include "entry.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -080034#ifdef CONFIG_COMPAT
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include "compat_ptrace.h"
36#endif
37
Josh Stone1c569f02009-08-24 14:43:14 -070038#define CREATE_TRACE_POINTS
39#include <trace/events/syscalls.h>
Ingo Molnar5e9ad7d2009-08-18 10:41:57 +020040
Martin Schwidefsky63506c42008-07-14 09:58:54 +020041enum s390_regset {
42 REGSET_GENERAL,
43 REGSET_FP,
Martin Schwidefsky86f25522010-05-17 10:00:05 +020044 REGSET_LAST_BREAK,
Martin Schwidefskyd35339a2012-07-31 11:03:04 +020045 REGSET_TDB,
Martin Schwidefsky20b40a72011-10-30 15:16:47 +010046 REGSET_SYSTEM_CALL,
Heiko Carstensea2a4d32009-10-06 10:34:13 +020047 REGSET_GENERAL_EXTENDED,
Martin Schwidefsky63506c42008-07-14 09:58:54 +020048};
49
Michael Mueller64597f92013-07-02 22:58:26 +020050void update_cr_regs(struct task_struct *task)
Linus Torvalds1da177e2005-04-16 15:20:36 -070051{
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +010052 struct pt_regs *regs = task_pt_regs(task);
53 struct thread_struct *thread = &task->thread;
Martin Schwidefskya45aff52011-10-30 15:16:07 +010054 struct per_regs old, new;
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Heiko Carstens66389e82012-09-14 12:59:47 +020056#ifdef CONFIG_64BIT
Martin Schwidefskyd35339a2012-07-31 11:03:04 +020057 /* Take care of the enable/disable of transactional execution. */
58 if (MACHINE_HAS_TE) {
Martin Schwidefskyc63bade2013-12-03 14:57:18 +010059 unsigned long cr, cr_new;
Martin Schwidefskyd35339a2012-07-31 11:03:04 +020060
Martin Schwidefskyc63bade2013-12-03 14:57:18 +010061 __ctl_store(cr, 0, 0);
Martin Schwidefsky0628a5f2013-08-27 09:56:55 +020062 /* Set or clear transaction execution TXC bit 8. */
Martin Schwidefskyc63bade2013-12-03 14:57:18 +010063 cr_new = cr | (1UL << 55);
Martin Schwidefskyd35339a2012-07-31 11:03:04 +020064 if (task->thread.per_flags & PER_FLAG_NO_TE)
Martin Schwidefskyc63bade2013-12-03 14:57:18 +010065 cr_new &= ~(1UL << 55);
66 if (cr_new != cr)
Martin Schwidefskya8a934e2014-04-01 13:45:33 +020067 __ctl_load(cr_new, 0, 0);
Michael Mueller64597f92013-07-02 22:58:26 +020068 /* Set or clear transaction execution TDC bits 62 and 63. */
Martin Schwidefskyc63bade2013-12-03 14:57:18 +010069 __ctl_store(cr, 2, 2);
70 cr_new = cr & ~3UL;
Michael Mueller64597f92013-07-02 22:58:26 +020071 if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) {
72 if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND)
Martin Schwidefskyc63bade2013-12-03 14:57:18 +010073 cr_new |= 1UL;
Michael Mueller64597f92013-07-02 22:58:26 +020074 else
Martin Schwidefskyc63bade2013-12-03 14:57:18 +010075 cr_new |= 2UL;
Michael Mueller64597f92013-07-02 22:58:26 +020076 }
Martin Schwidefskyc63bade2013-12-03 14:57:18 +010077 if (cr_new != cr)
78 __ctl_load(cr_new, 2, 2);
Martin Schwidefskyd35339a2012-07-31 11:03:04 +020079 }
Heiko Carstens66389e82012-09-14 12:59:47 +020080#endif
Martin Schwidefskya45aff52011-10-30 15:16:07 +010081 /* Copy user specified PER registers */
82 new.control = thread->per_user.control;
83 new.start = thread->per_user.start;
84 new.end = thread->per_user.end;
85
86 /* merge TIF_SINGLE_STEP into user specified PER registers. */
87 if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) {
Martin Schwidefsky818a3302014-03-14 12:01:08 +010088 if (test_tsk_thread_flag(task, TIF_BLOCK_STEP))
89 new.control |= PER_EVENT_BRANCH;
90 else
91 new.control |= PER_EVENT_IFETCH;
Martin Schwidefskyd35339a2012-07-31 11:03:04 +020092#ifdef CONFIG_64BIT
93 new.control |= PER_CONTROL_SUSPENSION;
94 new.control |= PER_EVENT_TRANSACTION_END;
95#endif
Martin Schwidefskya45aff52011-10-30 15:16:07 +010096 new.start = 0;
97 new.end = PSW_ADDR_INSN;
98 }
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +010099
100 /* Take care of the PER enablement bit in the PSW. */
Martin Schwidefskya45aff52011-10-30 15:16:07 +0100101 if (!(new.control & PER_EVENT_MASK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 regs->psw.mask &= ~PSW_MASK_PER;
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100103 return;
Martin Schwidefskyc3311c12010-01-13 20:44:25 +0100104 }
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100105 regs->psw.mask |= PSW_MASK_PER;
106 __ctl_store(old, 9, 11);
Martin Schwidefskya45aff52011-10-30 15:16:07 +0100107 if (memcmp(&new, &old, sizeof(struct per_regs)) != 0)
108 __ctl_load(new, 9, 11);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109}
110
Roland McGrath0ac30be2008-01-26 14:11:22 +0100111void user_enable_single_step(struct task_struct *task)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112{
Martin Schwidefsky818a3302014-03-14 12:01:08 +0100113 clear_tsk_thread_flag(task, TIF_BLOCK_STEP);
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100114 set_tsk_thread_flag(task, TIF_SINGLE_STEP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115}
116
Roland McGrath0ac30be2008-01-26 14:11:22 +0100117void user_disable_single_step(struct task_struct *task)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118{
Martin Schwidefsky818a3302014-03-14 12:01:08 +0100119 clear_tsk_thread_flag(task, TIF_BLOCK_STEP);
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100120 clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121}
122
Martin Schwidefsky818a3302014-03-14 12:01:08 +0100123void user_enable_block_step(struct task_struct *task)
124{
125 set_tsk_thread_flag(task, TIF_SINGLE_STEP);
126 set_tsk_thread_flag(task, TIF_BLOCK_STEP);
127}
128
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129/*
130 * Called by kernel/ptrace.c when detaching..
131 *
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100132 * Clear all debugging related fields.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 */
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100134void ptrace_disable(struct task_struct *task)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135{
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100136 memset(&task->thread.per_user, 0, sizeof(task->thread.per_user));
137 memset(&task->thread.per_event, 0, sizeof(task->thread.per_event));
138 clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
Martin Schwidefskyd3a73ac2014-04-15 12:55:07 +0200139 clear_pt_regs_flag(task_pt_regs(task), PIF_PER_TRAP);
Martin Schwidefskyd35339a2012-07-31 11:03:04 +0200140 task->thread.per_flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141}
142
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800143#ifndef CONFIG_64BIT
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144# define __ADDR_MASK 3
145#else
146# define __ADDR_MASK 7
147#endif
148
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100149static inline unsigned long __peek_user_per(struct task_struct *child,
150 addr_t addr)
151{
152 struct per_struct_kernel *dummy = NULL;
153
154 if (addr == (addr_t) &dummy->cr9)
155 /* Control bits of the active per set. */
156 return test_thread_flag(TIF_SINGLE_STEP) ?
157 PER_EVENT_IFETCH : child->thread.per_user.control;
158 else if (addr == (addr_t) &dummy->cr10)
159 /* Start address of the active per set. */
160 return test_thread_flag(TIF_SINGLE_STEP) ?
161 0 : child->thread.per_user.start;
162 else if (addr == (addr_t) &dummy->cr11)
163 /* End address of the active per set. */
164 return test_thread_flag(TIF_SINGLE_STEP) ?
165 PSW_ADDR_INSN : child->thread.per_user.end;
166 else if (addr == (addr_t) &dummy->bits)
167 /* Single-step bit. */
168 return test_thread_flag(TIF_SINGLE_STEP) ?
169 (1UL << (BITS_PER_LONG - 1)) : 0;
170 else if (addr == (addr_t) &dummy->starting_addr)
171 /* Start address of the user specified per set. */
172 return child->thread.per_user.start;
173 else if (addr == (addr_t) &dummy->ending_addr)
174 /* End address of the user specified per set. */
175 return child->thread.per_user.end;
176 else if (addr == (addr_t) &dummy->perc_atmid)
177 /* PER code, ATMID and AI of the last PER trap */
178 return (unsigned long)
179 child->thread.per_event.cause << (BITS_PER_LONG - 16);
180 else if (addr == (addr_t) &dummy->address)
181 /* Address of the last PER trap */
182 return child->thread.per_event.address;
183 else if (addr == (addr_t) &dummy->access_id)
184 /* Access id of the last PER trap */
185 return (unsigned long)
186 child->thread.per_event.paid << (BITS_PER_LONG - 8);
187 return 0;
188}
189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190/*
191 * Read the word at offset addr from the user area of a process. The
192 * trouble here is that the information is littered over different
193 * locations. The process registers are found on the kernel stack,
194 * the floating point stuff and the trace settings are stored in
195 * the task structure. In addition the different structures in
196 * struct user contain pad bytes that should be read as zeroes.
197 * Lovely...
198 */
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200199static unsigned long __peek_user(struct task_struct *child, addr_t addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200{
201 struct user *dummy = NULL;
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200202 addr_t offset, tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204 if (addr < (addr_t) &dummy->regs.acrs) {
205 /*
206 * psw and gprs are stored on the stack
207 */
Al Viroc7584fb2006-01-12 01:05:49 -0800208 tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
Heiko Carstens5ebf2502013-10-16 09:58:01 +0200209 if (addr == (addr_t) &dummy->regs.psw.mask) {
Martin Schwidefskyb50511e2011-10-30 15:16:50 +0100210 /* Return a clean psw mask. */
Heiko Carstens5ebf2502013-10-16 09:58:01 +0200211 tmp &= PSW_MASK_USER | PSW_MASK_RI;
212 tmp |= PSW_USER_BITS;
213 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214
215 } else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
216 /*
217 * access registers are stored in the thread structure
218 */
219 offset = addr - (addr_t) &dummy->regs.acrs;
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800220#ifdef CONFIG_64BIT
Martin Schwidefsky778959d2005-06-04 15:43:30 -0700221 /*
222 * Very special case: old & broken 64 bit gdb reading
223 * from acrs[15]. Result is a 64 bit value. Read the
224 * 32 bit acrs[15] value and shift it by 32. Sick...
225 */
226 if (addr == (addr_t) &dummy->regs.acrs[15])
227 tmp = ((unsigned long) child->thread.acrs[15]) << 32;
228 else
229#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
231
232 } else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
233 /*
234 * orig_gpr2 is stored on the kernel stack
235 */
Al Viroc7584fb2006-01-12 01:05:49 -0800236 tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
Jarod Wilson3d6e48f2008-09-09 12:38:56 +0200238 } else if (addr < (addr_t) &dummy->regs.fp_regs) {
239 /*
240 * prevent reads of padding hole between
241 * orig_gpr2 and fp_regs on s390.
242 */
243 tmp = 0;
244
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
246 /*
247 * floating point regs. are stored in the thread structure
248 */
249 offset = addr - (addr_t) &dummy->regs.fp_regs;
250 tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
Martin Schwidefsky778959d2005-06-04 15:43:30 -0700251 if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200252 tmp <<= BITS_PER_LONG - 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253
254 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
255 /*
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100256 * Handle access to the per_info structure.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 */
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100258 addr -= (addr_t) &dummy->regs.per_info;
259 tmp = __peek_user_per(child, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260
261 } else
262 tmp = 0;
263
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200264 return tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265}
266
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267static int
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200268peek_user(struct task_struct *child, addr_t addr, addr_t data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269{
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200270 addr_t tmp, mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
272 /*
273 * Stupid gdb peeks/pokes the access registers in 64 bit with
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200274 * an alignment of 4. Programmers from hell...
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 */
Martin Schwidefsky778959d2005-06-04 15:43:30 -0700276 mask = __ADDR_MASK;
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800277#ifdef CONFIG_64BIT
Martin Schwidefsky547e3ce2008-12-25 13:39:00 +0100278 if (addr >= (addr_t) &((struct user *) NULL)->regs.acrs &&
279 addr < (addr_t) &((struct user *) NULL)->regs.orig_gpr2)
Martin Schwidefsky778959d2005-06-04 15:43:30 -0700280 mask = 3;
281#endif
282 if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 return -EIO;
284
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200285 tmp = __peek_user(child, addr);
286 return put_user(tmp, (addr_t __user *) data);
287}
288
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100289static inline void __poke_user_per(struct task_struct *child,
290 addr_t addr, addr_t data)
291{
292 struct per_struct_kernel *dummy = NULL;
293
294 /*
295 * There are only three fields in the per_info struct that the
296 * debugger user can write to.
297 * 1) cr9: the debugger wants to set a new PER event mask
298 * 2) starting_addr: the debugger wants to set a new starting
299 * address to use with the PER event mask.
300 * 3) ending_addr: the debugger wants to set a new ending
301 * address to use with the PER event mask.
302 * The user specified PER event mask and the start and end
303 * addresses are used only if single stepping is not in effect.
304 * Writes to any other field in per_info are ignored.
305 */
306 if (addr == (addr_t) &dummy->cr9)
307 /* PER event mask of the user specified per set. */
308 child->thread.per_user.control =
309 data & (PER_EVENT_MASK | PER_CONTROL_MASK);
310 else if (addr == (addr_t) &dummy->starting_addr)
311 /* Starting address of the user specified per set. */
312 child->thread.per_user.start = data;
313 else if (addr == (addr_t) &dummy->ending_addr)
314 /* Ending address of the user specified per set. */
315 child->thread.per_user.end = data;
316}
317
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200318/*
319 * Write a word to the user area of a process at location addr. This
320 * operation does have an additional problem compared to peek_user.
321 * Stores to the program status word and on the floating point
322 * control register needs to get checked for validity.
323 */
324static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
325{
326 struct user *dummy = NULL;
Martin Schwidefskyd4e81b32011-10-30 15:16:51 +0100327 addr_t offset;
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200328
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 if (addr < (addr_t) &dummy->regs.acrs) {
330 /*
331 * psw and gprs are stored on the stack
332 */
Heiko Carstens5ebf2502013-10-16 09:58:01 +0200333 if (addr == (addr_t) &dummy->regs.psw.mask) {
334 unsigned long mask = PSW_MASK_USER;
335
336 mask |= is_ri_task(child) ? PSW_MASK_RI : 0;
Martin Schwidefskydab6cf552014-06-23 15:29:40 +0200337 if ((data ^ PSW_USER_BITS) & ~mask)
338 /* Invalid psw mask. */
339 return -EINVAL;
340 if ((data & PSW_MASK_ASC) == PSW_ASC_HOME)
341 /* Invalid address-space-control bits */
Heiko Carstens5ebf2502013-10-16 09:58:01 +0200342 return -EINVAL;
343 if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))
Martin Schwidefskydab6cf552014-06-23 15:29:40 +0200344 /* Invalid addressing mode bits */
Heiko Carstens5ebf2502013-10-16 09:58:01 +0200345 return -EINVAL;
346 }
Al Viroc7584fb2006-01-12 01:05:49 -0800347 *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348
349 } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
350 /*
351 * access registers are stored in the thread structure
352 */
353 offset = addr - (addr_t) &dummy->regs.acrs;
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800354#ifdef CONFIG_64BIT
Martin Schwidefsky778959d2005-06-04 15:43:30 -0700355 /*
356 * Very special case: old & broken 64 bit gdb writing
357 * to acrs[15] with a 64 bit value. Ignore the lower
358 * half of the value and write the upper 32 bit to
359 * acrs[15]. Sick...
360 */
361 if (addr == (addr_t) &dummy->regs.acrs[15])
362 child->thread.acrs[15] = (unsigned int) (data >> 32);
363 else
364#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 *(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
366
367 } else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
368 /*
369 * orig_gpr2 is stored on the kernel stack
370 */
Al Viroc7584fb2006-01-12 01:05:49 -0800371 task_pt_regs(child)->orig_gpr2 = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Jarod Wilson3d6e48f2008-09-09 12:38:56 +0200373 } else if (addr < (addr_t) &dummy->regs.fp_regs) {
374 /*
375 * prevent writes of padding hole between
376 * orig_gpr2 and fp_regs on s390.
377 */
378 return 0;
379
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
381 /*
382 * floating point regs. are stored in the thread structure
383 */
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200384 if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
385 if ((unsigned int) data != 0 ||
386 test_fp_ctl(data >> (BITS_PER_LONG - 32)))
387 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 offset = addr - (addr_t) &dummy->regs.fp_regs;
389 *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
390
391 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
392 /*
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100393 * Handle access to the per_info structure.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 */
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100395 addr -= (addr_t) &dummy->regs.per_info;
396 __poke_user_per(child, addr, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
398 }
399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 return 0;
401}
402
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100403static int poke_user(struct task_struct *child, addr_t addr, addr_t data)
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200404{
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200405 addr_t mask;
406
407 /*
408 * Stupid gdb peeks/pokes the access registers in 64 bit with
409 * an alignment of 4. Programmers from hell indeed...
410 */
411 mask = __ADDR_MASK;
412#ifdef CONFIG_64BIT
Martin Schwidefsky547e3ce2008-12-25 13:39:00 +0100413 if (addr >= (addr_t) &((struct user *) NULL)->regs.acrs &&
414 addr < (addr_t) &((struct user *) NULL)->regs.orig_gpr2)
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200415 mask = 3;
416#endif
417 if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
418 return -EIO;
419
420 return __poke_user(child, addr, data);
421}
422
Namhyung Kim9b05a692010-10-27 15:33:47 -0700423long arch_ptrace(struct task_struct *child, long request,
424 unsigned long addr, unsigned long data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 ptrace_area parea;
427 int copied, ret;
428
429 switch (request) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 case PTRACE_PEEKUSR:
431 /* read the word at location addr in the USER area. */
432 return peek_user(child, addr, data);
433
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 case PTRACE_POKEUSR:
435 /* write the word at location addr in the USER area */
436 return poke_user(child, addr, data);
437
438 case PTRACE_PEEKUSR_AREA:
439 case PTRACE_POKEUSR_AREA:
Heiko Carstens2b67fc42007-02-05 21:16:47 +0100440 if (copy_from_user(&parea, (void __force __user *) addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 sizeof(parea)))
442 return -EFAULT;
443 addr = parea.kernel_addr;
444 data = parea.process_addr;
445 copied = 0;
446 while (copied < parea.len) {
447 if (request == PTRACE_PEEKUSR_AREA)
448 ret = peek_user(child, addr, data);
449 else {
Heiko Carstens2b67fc42007-02-05 21:16:47 +0100450 addr_t utmp;
451 if (get_user(utmp,
452 (addr_t __force __user *) data))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 return -EFAULT;
Heiko Carstens2b67fc42007-02-05 21:16:47 +0100454 ret = poke_user(child, addr, utmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 }
456 if (ret)
457 return ret;
458 addr += sizeof(unsigned long);
459 data += sizeof(unsigned long);
460 copied += sizeof(unsigned long);
461 }
462 return 0;
Martin Schwidefsky86f25522010-05-17 10:00:05 +0200463 case PTRACE_GET_LAST_BREAK:
464 put_user(task_thread_info(child)->last_break,
465 (unsigned long __user *) data);
466 return 0;
Martin Schwidefskyd35339a2012-07-31 11:03:04 +0200467 case PTRACE_ENABLE_TE:
468 if (!MACHINE_HAS_TE)
469 return -EIO;
470 child->thread.per_flags &= ~PER_FLAG_NO_TE;
471 return 0;
472 case PTRACE_DISABLE_TE:
473 if (!MACHINE_HAS_TE)
474 return -EIO;
475 child->thread.per_flags |= PER_FLAG_NO_TE;
Michael Mueller64597f92013-07-02 22:58:26 +0200476 child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND;
477 return 0;
478 case PTRACE_TE_ABORT_RAND:
479 if (!MACHINE_HAS_TE || (child->thread.per_flags & PER_FLAG_NO_TE))
480 return -EIO;
481 switch (data) {
482 case 0UL:
483 child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND;
484 break;
485 case 1UL:
486 child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND;
487 child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND_TEND;
488 break;
489 case 2UL:
490 child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND;
491 child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND_TEND;
492 break;
493 default:
494 return -EINVAL;
495 }
Martin Schwidefskyd35339a2012-07-31 11:03:04 +0200496 return 0;
Christian Borntraeger07805ac2009-09-22 22:58:48 +0200497 default:
498 /* Removing high order bit from addr (only for 31 bit). */
499 addr &= PSW_ADDR_INSN;
500 return ptrace_request(child, request, addr, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502}
503
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800504#ifdef CONFIG_COMPAT
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505/*
506 * Now the fun part starts... a 31 bit program running in the
507 * 31 bit emulation tracing another program. PTRACE_PEEKTEXT,
508 * PTRACE_PEEKDATA, PTRACE_POKETEXT and PTRACE_POKEDATA are easy
509 * to handle, the difference to the 64 bit versions of the requests
510 * is that the access is done in multiples of 4 byte instead of
511 * 8 bytes (sizeof(unsigned long) on 31/64 bit).
512 * The ugly part are PTRACE_PEEKUSR, PTRACE_PEEKUSR_AREA,
513 * PTRACE_POKEUSR and PTRACE_POKEUSR_AREA. If the traced program
514 * is a 31 bit program too, the content of struct user can be
515 * emulated. A 31 bit program peeking into the struct user of
516 * a 64 bit program is a no-no.
517 */
518
519/*
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100520 * Same as peek_user_per but for a 31 bit program.
521 */
522static inline __u32 __peek_user_per_compat(struct task_struct *child,
523 addr_t addr)
524{
525 struct compat_per_struct_kernel *dummy32 = NULL;
526
527 if (addr == (addr_t) &dummy32->cr9)
528 /* Control bits of the active per set. */
529 return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
530 PER_EVENT_IFETCH : child->thread.per_user.control;
531 else if (addr == (addr_t) &dummy32->cr10)
532 /* Start address of the active per set. */
533 return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
534 0 : child->thread.per_user.start;
535 else if (addr == (addr_t) &dummy32->cr11)
536 /* End address of the active per set. */
537 return test_thread_flag(TIF_SINGLE_STEP) ?
538 PSW32_ADDR_INSN : child->thread.per_user.end;
539 else if (addr == (addr_t) &dummy32->bits)
540 /* Single-step bit. */
541 return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
542 0x80000000 : 0;
543 else if (addr == (addr_t) &dummy32->starting_addr)
544 /* Start address of the user specified per set. */
545 return (__u32) child->thread.per_user.start;
546 else if (addr == (addr_t) &dummy32->ending_addr)
547 /* End address of the user specified per set. */
548 return (__u32) child->thread.per_user.end;
549 else if (addr == (addr_t) &dummy32->perc_atmid)
550 /* PER code, ATMID and AI of the last PER trap */
551 return (__u32) child->thread.per_event.cause << 16;
552 else if (addr == (addr_t) &dummy32->address)
553 /* Address of the last PER trap */
554 return (__u32) child->thread.per_event.address;
555 else if (addr == (addr_t) &dummy32->access_id)
556 /* Access id of the last PER trap */
557 return (__u32) child->thread.per_event.paid << 24;
558 return 0;
559}
560
561/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 * Same as peek_user but for a 31 bit program.
563 */
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200564static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565{
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100566 struct compat_user *dummy32 = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 addr_t offset;
568 __u32 tmp;
569
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 if (addr < (addr_t) &dummy32->regs.acrs) {
Martin Schwidefskyb50511e2011-10-30 15:16:50 +0100571 struct pt_regs *regs = task_pt_regs(child);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 /*
573 * psw and gprs are stored on the stack
574 */
575 if (addr == (addr_t) &dummy32->regs.psw.mask) {
576 /* Fake a 31 bit psw mask. */
Martin Schwidefskyb50511e2011-10-30 15:16:50 +0100577 tmp = (__u32)(regs->psw.mask >> 32);
Heiko Carstens5ebf2502013-10-16 09:58:01 +0200578 tmp &= PSW32_MASK_USER | PSW32_MASK_RI;
Heiko Carstensf26946d2013-10-16 14:17:29 +0200579 tmp |= PSW32_USER_BITS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
581 /* Fake a 31 bit psw address. */
Martin Schwidefskyd4e81b32011-10-30 15:16:51 +0100582 tmp = (__u32) regs->psw.addr |
583 (__u32)(regs->psw.mask & PSW_MASK_BA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 } else {
585 /* gpr 0-15 */
Martin Schwidefskyb50511e2011-10-30 15:16:50 +0100586 tmp = *(__u32 *)((addr_t) &regs->psw + addr*2 + 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 }
588 } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
589 /*
590 * access registers are stored in the thread structure
591 */
592 offset = addr - (addr_t) &dummy32->regs.acrs;
593 tmp = *(__u32*)((addr_t) &child->thread.acrs + offset);
594
595 } else if (addr == (addr_t) (&dummy32->regs.orig_gpr2)) {
596 /*
597 * orig_gpr2 is stored on the kernel stack
598 */
Al Viroc7584fb2006-01-12 01:05:49 -0800599 tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
Jarod Wilson3d6e48f2008-09-09 12:38:56 +0200601 } else if (addr < (addr_t) &dummy32->regs.fp_regs) {
602 /*
603 * prevent reads of padding hole between
604 * orig_gpr2 and fp_regs on s390.
605 */
606 tmp = 0;
607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
609 /*
610 * floating point regs. are stored in the thread structure
611 */
612 offset = addr - (addr_t) &dummy32->regs.fp_regs;
613 tmp = *(__u32 *)((addr_t) &child->thread.fp_regs + offset);
614
615 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
616 /*
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100617 * Handle access to the per_info structure.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 */
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100619 addr -= (addr_t) &dummy32->regs.per_info;
620 tmp = __peek_user_per_compat(child, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
622 } else
623 tmp = 0;
624
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200625 return tmp;
626}
627
628static int peek_user_compat(struct task_struct *child,
629 addr_t addr, addr_t data)
630{
631 __u32 tmp;
632
Heiko Carstens77575912009-06-12 10:26:25 +0200633 if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user) - 3)
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200634 return -EIO;
635
636 tmp = __peek_user_compat(child, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 return put_user(tmp, (__u32 __user *) data);
638}
639
640/*
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100641 * Same as poke_user_per but for a 31 bit program.
642 */
643static inline void __poke_user_per_compat(struct task_struct *child,
644 addr_t addr, __u32 data)
645{
646 struct compat_per_struct_kernel *dummy32 = NULL;
647
648 if (addr == (addr_t) &dummy32->cr9)
649 /* PER event mask of the user specified per set. */
650 child->thread.per_user.control =
651 data & (PER_EVENT_MASK | PER_CONTROL_MASK);
652 else if (addr == (addr_t) &dummy32->starting_addr)
653 /* Starting address of the user specified per set. */
654 child->thread.per_user.start = data;
655 else if (addr == (addr_t) &dummy32->ending_addr)
656 /* Ending address of the user specified per set. */
657 child->thread.per_user.end = data;
658}
659
660/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 * Same as poke_user but for a 31 bit program.
662 */
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200663static int __poke_user_compat(struct task_struct *child,
664 addr_t addr, addr_t data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665{
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100666 struct compat_user *dummy32 = NULL;
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200667 __u32 tmp = (__u32) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 addr_t offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669
670 if (addr < (addr_t) &dummy32->regs.acrs) {
Martin Schwidefskyb50511e2011-10-30 15:16:50 +0100671 struct pt_regs *regs = task_pt_regs(child);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 /*
673 * psw, gprs, acrs and orig_gpr2 are stored on the stack
674 */
675 if (addr == (addr_t) &dummy32->regs.psw.mask) {
Heiko Carstens5ebf2502013-10-16 09:58:01 +0200676 __u32 mask = PSW32_MASK_USER;
677
678 mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 /* Build a 64 bit psw mask from 31 bit mask. */
Martin Schwidefskydab6cf552014-06-23 15:29:40 +0200680 if ((tmp ^ PSW32_USER_BITS) & ~mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 /* Invalid psw mask. */
682 return -EINVAL;
Martin Schwidefskydab6cf552014-06-23 15:29:40 +0200683 if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME)
684 /* Invalid address-space-control bits */
685 return -EINVAL;
Martin Schwidefskyb50511e2011-10-30 15:16:50 +0100686 regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
Martin Schwidefskyd4e81b32011-10-30 15:16:51 +0100687 (regs->psw.mask & PSW_MASK_BA) |
Heiko Carstens5ebf2502013-10-16 09:58:01 +0200688 (__u64)(tmp & mask) << 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
690 /* Build a 64 bit psw address from 31 bit address. */
Martin Schwidefskyb50511e2011-10-30 15:16:50 +0100691 regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN;
Martin Schwidefskyd4e81b32011-10-30 15:16:51 +0100692 /* Transfer 31 bit amode bit to psw mask. */
693 regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) |
694 (__u64)(tmp & PSW32_ADDR_AMODE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 } else {
696 /* gpr 0-15 */
Martin Schwidefskyb50511e2011-10-30 15:16:50 +0100697 *(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 }
699 } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
700 /*
701 * access registers are stored in the thread structure
702 */
703 offset = addr - (addr_t) &dummy32->regs.acrs;
704 *(__u32*)((addr_t) &child->thread.acrs + offset) = tmp;
705
706 } else if (addr == (addr_t) (&dummy32->regs.orig_gpr2)) {
707 /*
708 * orig_gpr2 is stored on the kernel stack
709 */
Al Viroc7584fb2006-01-12 01:05:49 -0800710 *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711
Jarod Wilson3d6e48f2008-09-09 12:38:56 +0200712 } else if (addr < (addr_t) &dummy32->regs.fp_regs) {
713 /*
714 * prevent writess of padding hole between
715 * orig_gpr2 and fp_regs on s390.
716 */
717 return 0;
718
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
720 /*
721 * floating point regs. are stored in the thread structure
722 */
723 if (addr == (addr_t) &dummy32->regs.fp_regs.fpc &&
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200724 test_fp_ctl(tmp))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 return -EINVAL;
726 offset = addr - (addr_t) &dummy32->regs.fp_regs;
727 *(__u32 *)((addr_t) &child->thread.fp_regs + offset) = tmp;
728
729 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
730 /*
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100731 * Handle access to the per_info structure.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 */
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100733 addr -= (addr_t) &dummy32->regs.per_info;
734 __poke_user_per_compat(child, addr, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 }
736
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 return 0;
738}
739
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200740static int poke_user_compat(struct task_struct *child,
741 addr_t addr, addr_t data)
742{
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100743 if (!is_compat_task() || (addr & 3) ||
744 addr > sizeof(struct compat_user) - 3)
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200745 return -EIO;
746
747 return __poke_user_compat(child, addr, data);
748}
749
Roland McGrathb499d762008-05-07 09:22:57 +0200750long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
751 compat_ulong_t caddr, compat_ulong_t cdata)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752{
Roland McGrathb499d762008-05-07 09:22:57 +0200753 unsigned long addr = caddr;
754 unsigned long data = cdata;
Martin Schwidefsky5e9a2692011-01-05 12:48:10 +0100755 compat_ptrace_area parea;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 int copied, ret;
757
758 switch (request) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 case PTRACE_PEEKUSR:
760 /* read the word at location addr in the USER area. */
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200761 return peek_user_compat(child, addr, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 case PTRACE_POKEUSR:
764 /* write the word at location addr in the USER area */
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200765 return poke_user_compat(child, addr, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766
767 case PTRACE_PEEKUSR_AREA:
768 case PTRACE_POKEUSR_AREA:
Heiko Carstens2b67fc42007-02-05 21:16:47 +0100769 if (copy_from_user(&parea, (void __force __user *) addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 sizeof(parea)))
771 return -EFAULT;
772 addr = parea.kernel_addr;
773 data = parea.process_addr;
774 copied = 0;
775 while (copied < parea.len) {
776 if (request == PTRACE_PEEKUSR_AREA)
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200777 ret = peek_user_compat(child, addr, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 else {
Heiko Carstens2b67fc42007-02-05 21:16:47 +0100779 __u32 utmp;
780 if (get_user(utmp,
781 (__u32 __force __user *) data))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 return -EFAULT;
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200783 ret = poke_user_compat(child, addr, utmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 }
785 if (ret)
786 return ret;
787 addr += sizeof(unsigned int);
788 data += sizeof(unsigned int);
789 copied += sizeof(unsigned int);
790 }
791 return 0;
Martin Schwidefsky86f25522010-05-17 10:00:05 +0200792 case PTRACE_GET_LAST_BREAK:
793 put_user(task_thread_info(child)->last_break,
794 (unsigned int __user *) data);
795 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 }
Roland McGrathb499d762008-05-07 09:22:57 +0200797 return compat_ptrace_request(child, request, addr, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798}
799#endif
800
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +0200801asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802{
Gerald Schaefer545c1742010-05-12 09:32:12 +0200803 long ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
Heiko Carstensbcf5cef2009-06-12 10:26:26 +0200805 /* Do the secure computing check first. */
Heiko Carstensc63cb462012-07-31 15:37:13 +0200806 if (secure_computing(regs->gprs[2])) {
807 /* seccomp failures shouldn't expose any additional code. */
808 ret = -1;
809 goto out;
810 }
Heiko Carstensbcf5cef2009-06-12 10:26:26 +0200811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 /*
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +0200813 * The sysc_tracesys code in entry.S stored the system
814 * call number to gprs[2].
Bodo Stroesserc5c3a6d2005-06-04 15:43:32 -0700815 */
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +0200816 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
817 (tracehook_report_syscall_entry(regs) ||
818 regs->gprs[2] >= NR_syscalls)) {
819 /*
820 * Tracing decided this syscall should not happen or the
821 * debugger stored an invalid system call number. Skip
822 * the system call and the system call restart handling.
823 */
Martin Schwidefskyd3a73ac2014-04-15 12:55:07 +0200824 clear_pt_regs_flag(regs, PIF_SYSCALL);
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +0200825 ret = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 }
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +0200827
Josh Stone66700002009-08-24 14:43:11 -0700828 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
Josh Stone1c569f02009-08-24 14:43:14 -0700829 trace_sys_enter(regs, regs->gprs[2]);
Heiko Carstens9bf12262009-06-12 10:26:47 +0200830
Eric Parisb05d8442012-01-03 14:23:06 -0500831 audit_syscall_entry(is_compat_task() ?
832 AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
833 regs->gprs[2], regs->orig_gpr2,
834 regs->gprs[3], regs->gprs[4],
835 regs->gprs[5]);
Heiko Carstensc63cb462012-07-31 15:37:13 +0200836out:
Gerald Schaefer545c1742010-05-12 09:32:12 +0200837 return ret ?: regs->gprs[2];
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +0200838}
839
840asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
841{
Eric Parisd7e75282012-01-03 14:23:06 -0500842 audit_syscall_exit(regs);
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +0200843
Josh Stone66700002009-08-24 14:43:11 -0700844 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
Josh Stone1c569f02009-08-24 14:43:14 -0700845 trace_sys_exit(regs, regs->gprs[2]);
Heiko Carstens9bf12262009-06-12 10:26:47 +0200846
Martin Schwidefsky753c4dd2008-10-10 21:33:20 +0200847 if (test_thread_flag(TIF_SYSCALL_TRACE))
848 tracehook_report_syscall_exit(regs, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849}
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200850
851/*
852 * user_regset definitions.
853 */
854
855static int s390_regs_get(struct task_struct *target,
856 const struct user_regset *regset,
857 unsigned int pos, unsigned int count,
858 void *kbuf, void __user *ubuf)
859{
860 if (target == current)
861 save_access_regs(target->thread.acrs);
862
863 if (kbuf) {
864 unsigned long *k = kbuf;
865 while (count > 0) {
866 *k++ = __peek_user(target, pos);
867 count -= sizeof(*k);
868 pos += sizeof(*k);
869 }
870 } else {
871 unsigned long __user *u = ubuf;
872 while (count > 0) {
873 if (__put_user(__peek_user(target, pos), u++))
874 return -EFAULT;
875 count -= sizeof(*u);
876 pos += sizeof(*u);
877 }
878 }
879 return 0;
880}
881
882static int s390_regs_set(struct task_struct *target,
883 const struct user_regset *regset,
884 unsigned int pos, unsigned int count,
885 const void *kbuf, const void __user *ubuf)
886{
887 int rc = 0;
888
889 if (target == current)
890 save_access_regs(target->thread.acrs);
891
892 if (kbuf) {
893 const unsigned long *k = kbuf;
894 while (count > 0 && !rc) {
895 rc = __poke_user(target, pos, *k++);
896 count -= sizeof(*k);
897 pos += sizeof(*k);
898 }
899 } else {
900 const unsigned long __user *u = ubuf;
901 while (count > 0 && !rc) {
902 unsigned long word;
903 rc = __get_user(word, u++);
904 if (rc)
905 break;
906 rc = __poke_user(target, pos, word);
907 count -= sizeof(*u);
908 pos += sizeof(*u);
909 }
910 }
911
912 if (rc == 0 && target == current)
913 restore_access_regs(target->thread.acrs);
914
915 return rc;
916}
917
918static int s390_fpregs_get(struct task_struct *target,
919 const struct user_regset *regset, unsigned int pos,
920 unsigned int count, void *kbuf, void __user *ubuf)
921{
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200922 if (target == current) {
923 save_fp_ctl(&target->thread.fp_regs.fpc);
924 save_fp_regs(target->thread.fp_regs.fprs);
925 }
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200926
927 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
928 &target->thread.fp_regs, 0, -1);
929}
930
931static int s390_fpregs_set(struct task_struct *target,
932 const struct user_regset *regset, unsigned int pos,
933 unsigned int count, const void *kbuf,
934 const void __user *ubuf)
935{
936 int rc = 0;
937
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200938 if (target == current) {
939 save_fp_ctl(&target->thread.fp_regs.fpc);
940 save_fp_regs(target->thread.fp_regs.fprs);
941 }
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200942
943 /* If setting FPC, must validate it first. */
944 if (count > 0 && pos < offsetof(s390_fp_regs, fprs)) {
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200945 u32 ufpc[2] = { target->thread.fp_regs.fpc, 0 };
946 rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ufpc,
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200947 0, offsetof(s390_fp_regs, fprs));
948 if (rc)
949 return rc;
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200950 if (ufpc[1] != 0 || test_fp_ctl(ufpc[0]))
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200951 return -EINVAL;
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200952 target->thread.fp_regs.fpc = ufpc[0];
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200953 }
954
955 if (rc == 0 && count > 0)
956 rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
957 target->thread.fp_regs.fprs,
958 offsetof(s390_fp_regs, fprs), -1);
959
Martin Schwidefsky4725c862013-10-15 16:08:34 +0200960 if (rc == 0 && target == current) {
961 restore_fp_ctl(&target->thread.fp_regs.fpc);
962 restore_fp_regs(target->thread.fp_regs.fprs);
963 }
Martin Schwidefsky63506c42008-07-14 09:58:54 +0200964
965 return rc;
966}
967
Martin Schwidefsky86f25522010-05-17 10:00:05 +0200968#ifdef CONFIG_64BIT
969
970static int s390_last_break_get(struct task_struct *target,
971 const struct user_regset *regset,
972 unsigned int pos, unsigned int count,
973 void *kbuf, void __user *ubuf)
974{
975 if (count > 0) {
976 if (kbuf) {
977 unsigned long *k = kbuf;
978 *k = task_thread_info(target)->last_break;
979 } else {
980 unsigned long __user *u = ubuf;
981 if (__put_user(task_thread_info(target)->last_break, u))
982 return -EFAULT;
983 }
984 }
985 return 0;
986}
987
Martin Schwidefskyb9340692011-12-01 13:32:17 +0100988static int s390_last_break_set(struct task_struct *target,
989 const struct user_regset *regset,
990 unsigned int pos, unsigned int count,
991 const void *kbuf, const void __user *ubuf)
992{
993 return 0;
994}
995
Martin Schwidefskyd35339a2012-07-31 11:03:04 +0200996static int s390_tdb_get(struct task_struct *target,
997 const struct user_regset *regset,
998 unsigned int pos, unsigned int count,
999 void *kbuf, void __user *ubuf)
1000{
1001 struct pt_regs *regs = task_pt_regs(target);
1002 unsigned char *data;
1003
1004 if (!(regs->int_code & 0x200))
1005 return -ENODATA;
1006 data = target->thread.trap_tdb;
1007 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, data, 0, 256);
1008}
1009
1010static int s390_tdb_set(struct task_struct *target,
1011 const struct user_regset *regset,
1012 unsigned int pos, unsigned int count,
1013 const void *kbuf, const void __user *ubuf)
1014{
1015 return 0;
1016}
1017
Martin Schwidefsky86f25522010-05-17 10:00:05 +02001018#endif
1019
Martin Schwidefsky20b40a72011-10-30 15:16:47 +01001020static int s390_system_call_get(struct task_struct *target,
1021 const struct user_regset *regset,
1022 unsigned int pos, unsigned int count,
1023 void *kbuf, void __user *ubuf)
1024{
1025 unsigned int *data = &task_thread_info(target)->system_call;
1026 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
1027 data, 0, sizeof(unsigned int));
1028}
1029
1030static int s390_system_call_set(struct task_struct *target,
1031 const struct user_regset *regset,
1032 unsigned int pos, unsigned int count,
1033 const void *kbuf, const void __user *ubuf)
1034{
1035 unsigned int *data = &task_thread_info(target)->system_call;
1036 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
1037 data, 0, sizeof(unsigned int));
1038}
1039
Martin Schwidefsky63506c42008-07-14 09:58:54 +02001040static const struct user_regset s390_regsets[] = {
1041 [REGSET_GENERAL] = {
1042 .core_note_type = NT_PRSTATUS,
1043 .n = sizeof(s390_regs) / sizeof(long),
1044 .size = sizeof(long),
1045 .align = sizeof(long),
1046 .get = s390_regs_get,
1047 .set = s390_regs_set,
1048 },
1049 [REGSET_FP] = {
1050 .core_note_type = NT_PRFPREG,
1051 .n = sizeof(s390_fp_regs) / sizeof(long),
1052 .size = sizeof(long),
1053 .align = sizeof(long),
1054 .get = s390_fpregs_get,
1055 .set = s390_fpregs_set,
1056 },
Martin Schwidefsky86f25522010-05-17 10:00:05 +02001057#ifdef CONFIG_64BIT
1058 [REGSET_LAST_BREAK] = {
1059 .core_note_type = NT_S390_LAST_BREAK,
1060 .n = 1,
1061 .size = sizeof(long),
1062 .align = sizeof(long),
1063 .get = s390_last_break_get,
Martin Schwidefskyb9340692011-12-01 13:32:17 +01001064 .set = s390_last_break_set,
Martin Schwidefsky86f25522010-05-17 10:00:05 +02001065 },
Martin Schwidefskyd35339a2012-07-31 11:03:04 +02001066 [REGSET_TDB] = {
1067 .core_note_type = NT_S390_TDB,
1068 .n = 1,
1069 .size = 256,
1070 .align = 1,
1071 .get = s390_tdb_get,
1072 .set = s390_tdb_set,
1073 },
Martin Schwidefsky86f25522010-05-17 10:00:05 +02001074#endif
Martin Schwidefsky20b40a72011-10-30 15:16:47 +01001075 [REGSET_SYSTEM_CALL] = {
1076 .core_note_type = NT_S390_SYSTEM_CALL,
1077 .n = 1,
1078 .size = sizeof(unsigned int),
1079 .align = sizeof(unsigned int),
1080 .get = s390_system_call_get,
1081 .set = s390_system_call_set,
1082 },
Martin Schwidefsky63506c42008-07-14 09:58:54 +02001083};
1084
1085static const struct user_regset_view user_s390_view = {
1086 .name = UTS_MACHINE,
1087 .e_machine = EM_S390,
1088 .regsets = s390_regsets,
1089 .n = ARRAY_SIZE(s390_regsets)
1090};
1091
1092#ifdef CONFIG_COMPAT
1093static int s390_compat_regs_get(struct task_struct *target,
1094 const struct user_regset *regset,
1095 unsigned int pos, unsigned int count,
1096 void *kbuf, void __user *ubuf)
1097{
1098 if (target == current)
1099 save_access_regs(target->thread.acrs);
1100
1101 if (kbuf) {
1102 compat_ulong_t *k = kbuf;
1103 while (count > 0) {
1104 *k++ = __peek_user_compat(target, pos);
1105 count -= sizeof(*k);
1106 pos += sizeof(*k);
1107 }
1108 } else {
1109 compat_ulong_t __user *u = ubuf;
1110 while (count > 0) {
1111 if (__put_user(__peek_user_compat(target, pos), u++))
1112 return -EFAULT;
1113 count -= sizeof(*u);
1114 pos += sizeof(*u);
1115 }
1116 }
1117 return 0;
1118}
1119
1120static int s390_compat_regs_set(struct task_struct *target,
1121 const struct user_regset *regset,
1122 unsigned int pos, unsigned int count,
1123 const void *kbuf, const void __user *ubuf)
1124{
1125 int rc = 0;
1126
1127 if (target == current)
1128 save_access_regs(target->thread.acrs);
1129
1130 if (kbuf) {
1131 const compat_ulong_t *k = kbuf;
1132 while (count > 0 && !rc) {
1133 rc = __poke_user_compat(target, pos, *k++);
1134 count -= sizeof(*k);
1135 pos += sizeof(*k);
1136 }
1137 } else {
1138 const compat_ulong_t __user *u = ubuf;
1139 while (count > 0 && !rc) {
1140 compat_ulong_t word;
1141 rc = __get_user(word, u++);
1142 if (rc)
1143 break;
1144 rc = __poke_user_compat(target, pos, word);
1145 count -= sizeof(*u);
1146 pos += sizeof(*u);
1147 }
1148 }
1149
1150 if (rc == 0 && target == current)
1151 restore_access_regs(target->thread.acrs);
1152
1153 return rc;
1154}
1155
Heiko Carstensea2a4d32009-10-06 10:34:13 +02001156static int s390_compat_regs_high_get(struct task_struct *target,
1157 const struct user_regset *regset,
1158 unsigned int pos, unsigned int count,
1159 void *kbuf, void __user *ubuf)
1160{
1161 compat_ulong_t *gprs_high;
1162
1163 gprs_high = (compat_ulong_t *)
1164 &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)];
1165 if (kbuf) {
1166 compat_ulong_t *k = kbuf;
1167 while (count > 0) {
1168 *k++ = *gprs_high;
1169 gprs_high += 2;
1170 count -= sizeof(*k);
1171 }
1172 } else {
1173 compat_ulong_t __user *u = ubuf;
1174 while (count > 0) {
1175 if (__put_user(*gprs_high, u++))
1176 return -EFAULT;
1177 gprs_high += 2;
1178 count -= sizeof(*u);
1179 }
1180 }
1181 return 0;
1182}
1183
1184static int s390_compat_regs_high_set(struct task_struct *target,
1185 const struct user_regset *regset,
1186 unsigned int pos, unsigned int count,
1187 const void *kbuf, const void __user *ubuf)
1188{
1189 compat_ulong_t *gprs_high;
1190 int rc = 0;
1191
1192 gprs_high = (compat_ulong_t *)
1193 &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)];
1194 if (kbuf) {
1195 const compat_ulong_t *k = kbuf;
1196 while (count > 0) {
1197 *gprs_high = *k++;
1198 *gprs_high += 2;
1199 count -= sizeof(*k);
1200 }
1201 } else {
1202 const compat_ulong_t __user *u = ubuf;
1203 while (count > 0 && !rc) {
1204 unsigned long word;
1205 rc = __get_user(word, u++);
1206 if (rc)
1207 break;
1208 *gprs_high = word;
1209 *gprs_high += 2;
1210 count -= sizeof(*u);
1211 }
1212 }
1213
1214 return rc;
1215}
1216
Martin Schwidefsky86f25522010-05-17 10:00:05 +02001217static int s390_compat_last_break_get(struct task_struct *target,
1218 const struct user_regset *regset,
1219 unsigned int pos, unsigned int count,
1220 void *kbuf, void __user *ubuf)
1221{
1222 compat_ulong_t last_break;
1223
1224 if (count > 0) {
1225 last_break = task_thread_info(target)->last_break;
1226 if (kbuf) {
1227 unsigned long *k = kbuf;
1228 *k = last_break;
1229 } else {
1230 unsigned long __user *u = ubuf;
1231 if (__put_user(last_break, u))
1232 return -EFAULT;
1233 }
1234 }
1235 return 0;
1236}
1237
Martin Schwidefskyb9340692011-12-01 13:32:17 +01001238static int s390_compat_last_break_set(struct task_struct *target,
1239 const struct user_regset *regset,
1240 unsigned int pos, unsigned int count,
1241 const void *kbuf, const void __user *ubuf)
1242{
1243 return 0;
1244}
1245
Martin Schwidefsky63506c42008-07-14 09:58:54 +02001246static const struct user_regset s390_compat_regsets[] = {
1247 [REGSET_GENERAL] = {
1248 .core_note_type = NT_PRSTATUS,
1249 .n = sizeof(s390_compat_regs) / sizeof(compat_long_t),
1250 .size = sizeof(compat_long_t),
1251 .align = sizeof(compat_long_t),
1252 .get = s390_compat_regs_get,
1253 .set = s390_compat_regs_set,
1254 },
1255 [REGSET_FP] = {
1256 .core_note_type = NT_PRFPREG,
1257 .n = sizeof(s390_fp_regs) / sizeof(compat_long_t),
1258 .size = sizeof(compat_long_t),
1259 .align = sizeof(compat_long_t),
1260 .get = s390_fpregs_get,
1261 .set = s390_fpregs_set,
1262 },
Martin Schwidefsky86f25522010-05-17 10:00:05 +02001263 [REGSET_LAST_BREAK] = {
1264 .core_note_type = NT_S390_LAST_BREAK,
1265 .n = 1,
1266 .size = sizeof(long),
1267 .align = sizeof(long),
1268 .get = s390_compat_last_break_get,
Martin Schwidefskyb9340692011-12-01 13:32:17 +01001269 .set = s390_compat_last_break_set,
Martin Schwidefsky86f25522010-05-17 10:00:05 +02001270 },
Martin Schwidefskyd35339a2012-07-31 11:03:04 +02001271 [REGSET_TDB] = {
1272 .core_note_type = NT_S390_TDB,
1273 .n = 1,
1274 .size = 256,
1275 .align = 1,
1276 .get = s390_tdb_get,
1277 .set = s390_tdb_set,
1278 },
Martin Schwidefsky20b40a72011-10-30 15:16:47 +01001279 [REGSET_SYSTEM_CALL] = {
1280 .core_note_type = NT_S390_SYSTEM_CALL,
1281 .n = 1,
1282 .size = sizeof(compat_uint_t),
1283 .align = sizeof(compat_uint_t),
1284 .get = s390_system_call_get,
1285 .set = s390_system_call_set,
1286 },
Heiko Carstensea2a4d32009-10-06 10:34:13 +02001287 [REGSET_GENERAL_EXTENDED] = {
Martin Schwidefsky622e99b2009-12-18 17:43:20 +01001288 .core_note_type = NT_S390_HIGH_GPRS,
Heiko Carstensea2a4d32009-10-06 10:34:13 +02001289 .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
1290 .size = sizeof(compat_long_t),
1291 .align = sizeof(compat_long_t),
1292 .get = s390_compat_regs_high_get,
1293 .set = s390_compat_regs_high_set,
1294 },
Martin Schwidefsky63506c42008-07-14 09:58:54 +02001295};
1296
1297static const struct user_regset_view user_s390_compat_view = {
1298 .name = "s390",
1299 .e_machine = EM_S390,
1300 .regsets = s390_compat_regsets,
1301 .n = ARRAY_SIZE(s390_compat_regsets)
1302};
1303#endif
1304
1305const struct user_regset_view *task_user_regset_view(struct task_struct *task)
1306{
1307#ifdef CONFIG_COMPAT
1308 if (test_tsk_thread_flag(task, TIF_31BIT))
1309 return &user_s390_compat_view;
1310#endif
1311 return &user_s390_view;
1312}
Heiko Carstens952974ac62010-02-12 13:38:40 +01001313
1314static const char *gpr_names[NUM_GPRS] = {
1315 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1316 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1317};
1318
1319unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset)
1320{
1321 if (offset >= NUM_GPRS)
1322 return 0;
1323 return regs->gprs[offset];
1324}
1325
1326int regs_query_register_offset(const char *name)
1327{
1328 unsigned long offset;
1329
1330 if (!name || *name != 'r')
1331 return -EINVAL;
Heiko Carstens958d9072013-07-22 06:43:57 +02001332 if (kstrtoul(name + 1, 10, &offset))
Heiko Carstens952974ac62010-02-12 13:38:40 +01001333 return -EINVAL;
1334 if (offset >= NUM_GPRS)
1335 return -EINVAL;
1336 return offset;
1337}
1338
1339const char *regs_query_register_name(unsigned int offset)
1340{
1341 if (offset >= NUM_GPRS)
1342 return NULL;
1343 return gpr_names[offset];
1344}
1345
1346static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
1347{
1348 unsigned long ksp = kernel_stack_pointer(regs);
1349
1350 return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1));
1351}
1352
1353/**
1354 * regs_get_kernel_stack_nth() - get Nth entry of the stack
1355 * @regs:pt_regs which contains kernel stack pointer.
1356 * @n:stack entry number.
1357 *
1358 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1359 * is specifined by @regs. If the @n th entry is NOT in the kernel stack,
1360 * this returns 0.
1361 */
1362unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
1363{
1364 unsigned long addr;
1365
1366 addr = kernel_stack_pointer(regs) + n * sizeof(long);
1367 if (!regs_within_kernel_stack(regs, addr))
1368 return 0;
1369 return *(unsigned long *)addr;
1370}