xref: /openbmc/linux/arch/mips/kernel/ptrace.c (revision 64c70b1c)
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1992 Ross Biro
7  * Copyright (C) Linus Torvalds
8  * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
9  * Copyright (C) 1996 David S. Miller
10  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
11  * Copyright (C) 1999 MIPS Technologies, Inc.
12  * Copyright (C) 2000 Ulf Carlsson
13  *
14  * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
15  * binaries.
16  */
17 #include <linux/compiler.h>
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/mm.h>
21 #include <linux/errno.h>
22 #include <linux/ptrace.h>
23 #include <linux/audit.h>
24 #include <linux/smp.h>
25 #include <linux/user.h>
26 #include <linux/security.h>
27 #include <linux/signal.h>
28 
29 #include <asm/byteorder.h>
30 #include <asm/cpu.h>
31 #include <asm/dsp.h>
32 #include <asm/fpu.h>
33 #include <asm/mipsregs.h>
34 #include <asm/mipsmtregs.h>
35 #include <asm/pgtable.h>
36 #include <asm/page.h>
37 #include <asm/system.h>
38 #include <asm/uaccess.h>
39 #include <asm/bootinfo.h>
40 #include <asm/reg.h>
41 
42 /*
43  * Called by kernel/ptrace.c when detaching..
44  *
45  * Make sure single step bits etc are not set.
46  */
47 void ptrace_disable(struct task_struct *child)
48 {
49 	/* Nothing to do.. */
50 }
51 
52 /*
53  * Read a general register set.  We always use the 64-bit format, even
54  * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
55  * Registers are sign extended to fill the available space.
56  */
57 int ptrace_getregs (struct task_struct *child, __s64 __user *data)
58 {
59 	struct pt_regs *regs;
60 	int i;
61 
62 	if (!access_ok(VERIFY_WRITE, data, 38 * 8))
63 		return -EIO;
64 
65 	regs = task_pt_regs(child);
66 
67 	for (i = 0; i < 32; i++)
68 		__put_user (regs->regs[i], data + i);
69 	__put_user (regs->lo, data + EF_LO - EF_R0);
70 	__put_user (regs->hi, data + EF_HI - EF_R0);
71 	__put_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
72 	__put_user (regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
73 	__put_user (regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
74 	__put_user (regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
75 
76 	return 0;
77 }
78 
79 /*
80  * Write a general register set.  As for PTRACE_GETREGS, we always use
81  * the 64-bit format.  On a 32-bit kernel only the lower order half
82  * (according to endianness) will be used.
83  */
84 int ptrace_setregs (struct task_struct *child, __s64 __user *data)
85 {
86 	struct pt_regs *regs;
87 	int i;
88 
89 	if (!access_ok(VERIFY_READ, data, 38 * 8))
90 		return -EIO;
91 
92 	regs = task_pt_regs(child);
93 
94 	for (i = 0; i < 32; i++)
95 		__get_user (regs->regs[i], data + i);
96 	__get_user (regs->lo, data + EF_LO - EF_R0);
97 	__get_user (regs->hi, data + EF_HI - EF_R0);
98 	__get_user (regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
99 
100 	/* badvaddr, status, and cause may not be written.  */
101 
102 	return 0;
103 }
104 
105 int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
106 {
107 	int i;
108 	unsigned int tmp;
109 
110 	if (!access_ok(VERIFY_WRITE, data, 33 * 8))
111 		return -EIO;
112 
113 	if (tsk_used_math(child)) {
114 		fpureg_t *fregs = get_fpu_regs(child);
115 		for (i = 0; i < 32; i++)
116 			__put_user (fregs[i], i + (__u64 __user *) data);
117 	} else {
118 		for (i = 0; i < 32; i++)
119 			__put_user ((__u64) -1, i + (__u64 __user *) data);
120 	}
121 
122 	__put_user (child->thread.fpu.fcr31, data + 64);
123 
124 	preempt_disable();
125 	if (cpu_has_fpu) {
126 		unsigned int flags;
127 
128 		if (cpu_has_mipsmt) {
129 			unsigned int vpflags = dvpe();
130 			flags = read_c0_status();
131 			__enable_fpu();
132 			__asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
133 			write_c0_status(flags);
134 			evpe(vpflags);
135 		} else {
136 			flags = read_c0_status();
137 			__enable_fpu();
138 			__asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
139 			write_c0_status(flags);
140 		}
141 	} else {
142 		tmp = 0;
143 	}
144 	preempt_enable();
145 	__put_user (tmp, data + 65);
146 
147 	return 0;
148 }
149 
150 int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
151 {
152 	fpureg_t *fregs;
153 	int i;
154 
155 	if (!access_ok(VERIFY_READ, data, 33 * 8))
156 		return -EIO;
157 
158 	fregs = get_fpu_regs(child);
159 
160 	for (i = 0; i < 32; i++)
161 		__get_user (fregs[i], i + (__u64 __user *) data);
162 
163 	__get_user (child->thread.fpu.fcr31, data + 64);
164 
165 	/* FIR may not be written.  */
166 
167 	return 0;
168 }
169 
170 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
171 {
172 	int ret;
173 
174 	switch (request) {
175 	/* when I and D space are separate, these will need to be fixed. */
176 	case PTRACE_PEEKTEXT: /* read word at location addr. */
177 	case PTRACE_PEEKDATA: {
178 		unsigned long tmp;
179 		int copied;
180 
181 		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
182 		ret = -EIO;
183 		if (copied != sizeof(tmp))
184 			break;
185 		ret = put_user(tmp,(unsigned long __user *) data);
186 		break;
187 	}
188 
189 	/* Read the word at location addr in the USER area. */
190 	case PTRACE_PEEKUSR: {
191 		struct pt_regs *regs;
192 		unsigned long tmp = 0;
193 
194 		regs = task_pt_regs(child);
195 		ret = 0;  /* Default return value. */
196 
197 		switch (addr) {
198 		case 0 ... 31:
199 			tmp = regs->regs[addr];
200 			break;
201 		case FPR_BASE ... FPR_BASE + 31:
202 			if (tsk_used_math(child)) {
203 				fpureg_t *fregs = get_fpu_regs(child);
204 
205 #ifdef CONFIG_32BIT
206 				/*
207 				 * The odd registers are actually the high
208 				 * order bits of the values stored in the even
209 				 * registers - unless we're using r2k_switch.S.
210 				 */
211 				if (addr & 1)
212 					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
213 				else
214 					tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
215 #endif
216 #ifdef CONFIG_64BIT
217 				tmp = fregs[addr - FPR_BASE];
218 #endif
219 			} else {
220 				tmp = -1;	/* FP not yet used  */
221 			}
222 			break;
223 		case PC:
224 			tmp = regs->cp0_epc;
225 			break;
226 		case CAUSE:
227 			tmp = regs->cp0_cause;
228 			break;
229 		case BADVADDR:
230 			tmp = regs->cp0_badvaddr;
231 			break;
232 		case MMHI:
233 			tmp = regs->hi;
234 			break;
235 		case MMLO:
236 			tmp = regs->lo;
237 			break;
238 #ifdef CONFIG_CPU_HAS_SMARTMIPS
239 		case ACX:
240 			tmp = regs->acx;
241 			break;
242 #endif
243 		case FPC_CSR:
244 			tmp = child->thread.fpu.fcr31;
245 			break;
246 		case FPC_EIR: {	/* implementation / version register */
247 			unsigned int flags;
248 #ifdef CONFIG_MIPS_MT_SMTC
249 			unsigned int irqflags;
250 			unsigned int mtflags;
251 #endif /* CONFIG_MIPS_MT_SMTC */
252 
253 			preempt_disable();
254 			if (!cpu_has_fpu) {
255 				preempt_enable();
256 				break;
257 			}
258 
259 #ifdef CONFIG_MIPS_MT_SMTC
260 			/* Read-modify-write of Status must be atomic */
261 			local_irq_save(irqflags);
262 			mtflags = dmt();
263 #endif /* CONFIG_MIPS_MT_SMTC */
264 			if (cpu_has_mipsmt) {
265 				unsigned int vpflags = dvpe();
266 				flags = read_c0_status();
267 				__enable_fpu();
268 				__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
269 				write_c0_status(flags);
270 				evpe(vpflags);
271 			} else {
272 				flags = read_c0_status();
273 				__enable_fpu();
274 				__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
275 				write_c0_status(flags);
276 			}
277 #ifdef CONFIG_MIPS_MT_SMTC
278 			emt(mtflags);
279 			local_irq_restore(irqflags);
280 #endif /* CONFIG_MIPS_MT_SMTC */
281 			preempt_enable();
282 			break;
283 		}
284 		case DSP_BASE ... DSP_BASE + 5: {
285 			dspreg_t *dregs;
286 
287 			if (!cpu_has_dsp) {
288 				tmp = 0;
289 				ret = -EIO;
290 				goto out;
291 			}
292 			dregs = __get_dsp_regs(child);
293 			tmp = (unsigned long) (dregs[addr - DSP_BASE]);
294 			break;
295 		}
296 		case DSP_CONTROL:
297 			if (!cpu_has_dsp) {
298 				tmp = 0;
299 				ret = -EIO;
300 				goto out;
301 			}
302 			tmp = child->thread.dsp.dspcontrol;
303 			break;
304 		default:
305 			tmp = 0;
306 			ret = -EIO;
307 			goto out;
308 		}
309 		ret = put_user(tmp, (unsigned long __user *) data);
310 		break;
311 	}
312 
313 	/* when I and D space are separate, this will have to be fixed. */
314 	case PTRACE_POKETEXT: /* write the word at location addr. */
315 	case PTRACE_POKEDATA:
316 		ret = 0;
317 		if (access_process_vm(child, addr, &data, sizeof(data), 1)
318 		    == sizeof(data))
319 			break;
320 		ret = -EIO;
321 		break;
322 
323 	case PTRACE_POKEUSR: {
324 		struct pt_regs *regs;
325 		ret = 0;
326 		regs = task_pt_regs(child);
327 
328 		switch (addr) {
329 		case 0 ... 31:
330 			regs->regs[addr] = data;
331 			break;
332 		case FPR_BASE ... FPR_BASE + 31: {
333 			fpureg_t *fregs = get_fpu_regs(child);
334 
335 			if (!tsk_used_math(child)) {
336 				/* FP not yet used  */
337 				memset(&child->thread.fpu, ~0,
338 				       sizeof(child->thread.fpu));
339 				child->thread.fpu.fcr31 = 0;
340 			}
341 #ifdef CONFIG_32BIT
342 			/*
343 			 * The odd registers are actually the high order bits
344 			 * of the values stored in the even registers - unless
345 			 * we're using r2k_switch.S.
346 			 */
347 			if (addr & 1) {
348 				fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
349 				fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
350 			} else {
351 				fregs[addr - FPR_BASE] &= ~0xffffffffLL;
352 				fregs[addr - FPR_BASE] |= data;
353 			}
354 #endif
355 #ifdef CONFIG_64BIT
356 			fregs[addr - FPR_BASE] = data;
357 #endif
358 			break;
359 		}
360 		case PC:
361 			regs->cp0_epc = data;
362 			break;
363 		case MMHI:
364 			regs->hi = data;
365 			break;
366 		case MMLO:
367 			regs->lo = data;
368 			break;
369 #ifdef CONFIG_CPU_HAS_SMARTMIPS
370 		case ACX:
371 			regs->acx = data;
372 			break;
373 #endif
374 		case FPC_CSR:
375 			child->thread.fpu.fcr31 = data;
376 			break;
377 		case DSP_BASE ... DSP_BASE + 5: {
378 			dspreg_t *dregs;
379 
380 			if (!cpu_has_dsp) {
381 				ret = -EIO;
382 				break;
383 			}
384 
385 			dregs = __get_dsp_regs(child);
386 			dregs[addr - DSP_BASE] = data;
387 			break;
388 		}
389 		case DSP_CONTROL:
390 			if (!cpu_has_dsp) {
391 				ret = -EIO;
392 				break;
393 			}
394 			child->thread.dsp.dspcontrol = data;
395 			break;
396 		default:
397 			/* The rest are not allowed. */
398 			ret = -EIO;
399 			break;
400 		}
401 		break;
402 		}
403 
404 	case PTRACE_GETREGS:
405 		ret = ptrace_getregs (child, (__u64 __user *) data);
406 		break;
407 
408 	case PTRACE_SETREGS:
409 		ret = ptrace_setregs (child, (__u64 __user *) data);
410 		break;
411 
412 	case PTRACE_GETFPREGS:
413 		ret = ptrace_getfpregs (child, (__u32 __user *) data);
414 		break;
415 
416 	case PTRACE_SETFPREGS:
417 		ret = ptrace_setfpregs (child, (__u32 __user *) data);
418 		break;
419 
420 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
421 	case PTRACE_CONT: { /* restart after signal. */
422 		ret = -EIO;
423 		if (!valid_signal(data))
424 			break;
425 		if (request == PTRACE_SYSCALL) {
426 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
427 		}
428 		else {
429 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
430 		}
431 		child->exit_code = data;
432 		wake_up_process(child);
433 		ret = 0;
434 		break;
435 	}
436 
437 	/*
438 	 * make the child exit.  Best I can do is send it a sigkill.
439 	 * perhaps it should be put in the status that it wants to
440 	 * exit.
441 	 */
442 	case PTRACE_KILL:
443 		ret = 0;
444 		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
445 			break;
446 		child->exit_code = SIGKILL;
447 		wake_up_process(child);
448 		break;
449 
450 	case PTRACE_DETACH: /* detach a process that was attached. */
451 		ret = ptrace_detach(child, data);
452 		break;
453 
454 	case PTRACE_GET_THREAD_AREA:
455 		ret = put_user(task_thread_info(child)->tp_value,
456 				(unsigned long __user *) data);
457 		break;
458 
459 	default:
460 		ret = ptrace_request(child, request, addr, data);
461 		break;
462 	}
463  out:
464 	return ret;
465 }
466 
467 static inline int audit_arch(void)
468 {
469 	int arch = EM_MIPS;
470 #ifdef CONFIG_64BIT
471 	arch |=  __AUDIT_ARCH_64BIT;
472 #endif
473 #if defined(__LITTLE_ENDIAN)
474 	arch |=  __AUDIT_ARCH_LE;
475 #endif
476 	return arch;
477 }
478 
479 /*
480  * Notification of system call entry/exit
481  * - triggered by current->work.syscall_trace
482  */
483 asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
484 {
485 	if (unlikely(current->audit_context) && entryexit)
486 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
487 		                   regs->regs[2]);
488 
489 	if (!(current->ptrace & PT_PTRACED))
490 		goto out;
491 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
492 		goto out;
493 
494 	/* The 0x80 provides a way for the tracing parent to distinguish
495 	   between a syscall stop and SIGTRAP delivery */
496 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
497 	                         0x80 : 0));
498 
499 	/*
500 	 * this isn't the same as continuing with a signal, but it will do
501 	 * for normal use.  strace only continues with a signal if the
502 	 * stopping signal is not SIGTRAP.  -brl
503 	 */
504 	if (current->exit_code) {
505 		send_sig(current->exit_code, current, 1);
506 		current->exit_code = 0;
507 	}
508  out:
509 	if (unlikely(current->audit_context) && !entryexit)
510 		audit_syscall_entry(audit_arch(), regs->regs[2],
511 				    regs->regs[4], regs->regs[5],
512 				    regs->regs[6], regs->regs[7]);
513 }
514