xref: /openbmc/linux/arch/mips/kernel/ptrace.c (revision a1e58bbd)
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/smp.h>
24 #include <linux/user.h>
25 #include <linux/security.h>
26 #include <linux/audit.h>
27 #include <linux/seccomp.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((long)regs->regs[i], data + i);
69 	__put_user((long)regs->lo, data + EF_LO - EF_R0);
70 	__put_user((long)regs->hi, data + EF_HI - EF_R0);
71 	__put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
72 	__put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
73 	__put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
74 	__put_user((long)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 		ret = generic_ptrace_peekdata(child, addr, data);
179 		break;
180 
181 	/* Read the word at location addr in the USER area. */
182 	case PTRACE_PEEKUSR: {
183 		struct pt_regs *regs;
184 		unsigned long tmp = 0;
185 
186 		regs = task_pt_regs(child);
187 		ret = 0;  /* Default return value. */
188 
189 		switch (addr) {
190 		case 0 ... 31:
191 			tmp = regs->regs[addr];
192 			break;
193 		case FPR_BASE ... FPR_BASE + 31:
194 			if (tsk_used_math(child)) {
195 				fpureg_t *fregs = get_fpu_regs(child);
196 
197 #ifdef CONFIG_32BIT
198 				/*
199 				 * The odd registers are actually the high
200 				 * order bits of the values stored in the even
201 				 * registers - unless we're using r2k_switch.S.
202 				 */
203 				if (addr & 1)
204 					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
205 				else
206 					tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
207 #endif
208 #ifdef CONFIG_64BIT
209 				tmp = fregs[addr - FPR_BASE];
210 #endif
211 			} else {
212 				tmp = -1;	/* FP not yet used  */
213 			}
214 			break;
215 		case PC:
216 			tmp = regs->cp0_epc;
217 			break;
218 		case CAUSE:
219 			tmp = regs->cp0_cause;
220 			break;
221 		case BADVADDR:
222 			tmp = regs->cp0_badvaddr;
223 			break;
224 		case MMHI:
225 			tmp = regs->hi;
226 			break;
227 		case MMLO:
228 			tmp = regs->lo;
229 			break;
230 #ifdef CONFIG_CPU_HAS_SMARTMIPS
231 		case ACX:
232 			tmp = regs->acx;
233 			break;
234 #endif
235 		case FPC_CSR:
236 			tmp = child->thread.fpu.fcr31;
237 			break;
238 		case FPC_EIR: {	/* implementation / version register */
239 			unsigned int flags;
240 #ifdef CONFIG_MIPS_MT_SMTC
241 			unsigned int irqflags;
242 			unsigned int mtflags;
243 #endif /* CONFIG_MIPS_MT_SMTC */
244 
245 			preempt_disable();
246 			if (!cpu_has_fpu) {
247 				preempt_enable();
248 				break;
249 			}
250 
251 #ifdef CONFIG_MIPS_MT_SMTC
252 			/* Read-modify-write of Status must be atomic */
253 			local_irq_save(irqflags);
254 			mtflags = dmt();
255 #endif /* CONFIG_MIPS_MT_SMTC */
256 			if (cpu_has_mipsmt) {
257 				unsigned int vpflags = dvpe();
258 				flags = read_c0_status();
259 				__enable_fpu();
260 				__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
261 				write_c0_status(flags);
262 				evpe(vpflags);
263 			} else {
264 				flags = read_c0_status();
265 				__enable_fpu();
266 				__asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
267 				write_c0_status(flags);
268 			}
269 #ifdef CONFIG_MIPS_MT_SMTC
270 			emt(mtflags);
271 			local_irq_restore(irqflags);
272 #endif /* CONFIG_MIPS_MT_SMTC */
273 			preempt_enable();
274 			break;
275 		}
276 		case DSP_BASE ... DSP_BASE + 5: {
277 			dspreg_t *dregs;
278 
279 			if (!cpu_has_dsp) {
280 				tmp = 0;
281 				ret = -EIO;
282 				goto out;
283 			}
284 			dregs = __get_dsp_regs(child);
285 			tmp = (unsigned long) (dregs[addr - DSP_BASE]);
286 			break;
287 		}
288 		case DSP_CONTROL:
289 			if (!cpu_has_dsp) {
290 				tmp = 0;
291 				ret = -EIO;
292 				goto out;
293 			}
294 			tmp = child->thread.dsp.dspcontrol;
295 			break;
296 		default:
297 			tmp = 0;
298 			ret = -EIO;
299 			goto out;
300 		}
301 		ret = put_user(tmp, (unsigned long __user *) data);
302 		break;
303 	}
304 
305 	/* when I and D space are separate, this will have to be fixed. */
306 	case PTRACE_POKETEXT: /* write the word at location addr. */
307 	case PTRACE_POKEDATA:
308 		ret = generic_ptrace_pokedata(child, addr, data);
309 		break;
310 
311 	case PTRACE_POKEUSR: {
312 		struct pt_regs *regs;
313 		ret = 0;
314 		regs = task_pt_regs(child);
315 
316 		switch (addr) {
317 		case 0 ... 31:
318 			regs->regs[addr] = data;
319 			break;
320 		case FPR_BASE ... FPR_BASE + 31: {
321 			fpureg_t *fregs = get_fpu_regs(child);
322 
323 			if (!tsk_used_math(child)) {
324 				/* FP not yet used  */
325 				memset(&child->thread.fpu, ~0,
326 				       sizeof(child->thread.fpu));
327 				child->thread.fpu.fcr31 = 0;
328 			}
329 #ifdef CONFIG_32BIT
330 			/*
331 			 * The odd registers are actually the high order bits
332 			 * of the values stored in the even registers - unless
333 			 * we're using r2k_switch.S.
334 			 */
335 			if (addr & 1) {
336 				fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
337 				fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
338 			} else {
339 				fregs[addr - FPR_BASE] &= ~0xffffffffLL;
340 				fregs[addr - FPR_BASE] |= data;
341 			}
342 #endif
343 #ifdef CONFIG_64BIT
344 			fregs[addr - FPR_BASE] = data;
345 #endif
346 			break;
347 		}
348 		case PC:
349 			regs->cp0_epc = data;
350 			break;
351 		case MMHI:
352 			regs->hi = data;
353 			break;
354 		case MMLO:
355 			regs->lo = data;
356 			break;
357 #ifdef CONFIG_CPU_HAS_SMARTMIPS
358 		case ACX:
359 			regs->acx = data;
360 			break;
361 #endif
362 		case FPC_CSR:
363 			child->thread.fpu.fcr31 = data;
364 			break;
365 		case DSP_BASE ... DSP_BASE + 5: {
366 			dspreg_t *dregs;
367 
368 			if (!cpu_has_dsp) {
369 				ret = -EIO;
370 				break;
371 			}
372 
373 			dregs = __get_dsp_regs(child);
374 			dregs[addr - DSP_BASE] = data;
375 			break;
376 		}
377 		case DSP_CONTROL:
378 			if (!cpu_has_dsp) {
379 				ret = -EIO;
380 				break;
381 			}
382 			child->thread.dsp.dspcontrol = data;
383 			break;
384 		default:
385 			/* The rest are not allowed. */
386 			ret = -EIO;
387 			break;
388 		}
389 		break;
390 		}
391 
392 	case PTRACE_GETREGS:
393 		ret = ptrace_getregs(child, (__s64 __user *) data);
394 		break;
395 
396 	case PTRACE_SETREGS:
397 		ret = ptrace_setregs(child, (__s64 __user *) data);
398 		break;
399 
400 	case PTRACE_GETFPREGS:
401 		ret = ptrace_getfpregs(child, (__u32 __user *) data);
402 		break;
403 
404 	case PTRACE_SETFPREGS:
405 		ret = ptrace_setfpregs(child, (__u32 __user *) data);
406 		break;
407 
408 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
409 	case PTRACE_CONT: { /* restart after signal. */
410 		ret = -EIO;
411 		if (!valid_signal(data))
412 			break;
413 		if (request == PTRACE_SYSCALL) {
414 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
415 		}
416 		else {
417 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
418 		}
419 		child->exit_code = data;
420 		wake_up_process(child);
421 		ret = 0;
422 		break;
423 	}
424 
425 	/*
426 	 * make the child exit.  Best I can do is send it a sigkill.
427 	 * perhaps it should be put in the status that it wants to
428 	 * exit.
429 	 */
430 	case PTRACE_KILL:
431 		ret = 0;
432 		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
433 			break;
434 		child->exit_code = SIGKILL;
435 		wake_up_process(child);
436 		break;
437 
438 	case PTRACE_GET_THREAD_AREA:
439 		ret = put_user(task_thread_info(child)->tp_value,
440 				(unsigned long __user *) data);
441 		break;
442 
443 	default:
444 		ret = ptrace_request(child, request, addr, data);
445 		break;
446 	}
447  out:
448 	return ret;
449 }
450 
451 static inline int audit_arch(void)
452 {
453 	int arch = EM_MIPS;
454 #ifdef CONFIG_64BIT
455 	arch |=  __AUDIT_ARCH_64BIT;
456 #endif
457 #if defined(__LITTLE_ENDIAN)
458 	arch |=  __AUDIT_ARCH_LE;
459 #endif
460 	return arch;
461 }
462 
463 /*
464  * Notification of system call entry/exit
465  * - triggered by current->work.syscall_trace
466  */
467 asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
468 {
469 	/* do the secure computing check first */
470 	if (!entryexit)
471 		secure_computing(regs->regs[0]);
472 
473 	if (unlikely(current->audit_context) && entryexit)
474 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
475 		                   regs->regs[2]);
476 
477 	if (!(current->ptrace & PT_PTRACED))
478 		goto out;
479 
480 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
481 		goto out;
482 
483 	/* The 0x80 provides a way for the tracing parent to distinguish
484 	   between a syscall stop and SIGTRAP delivery */
485 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
486 	                         0x80 : 0));
487 
488 	/*
489 	 * this isn't the same as continuing with a signal, but it will do
490 	 * for normal use.  strace only continues with a signal if the
491 	 * stopping signal is not SIGTRAP.  -brl
492 	 */
493 	if (current->exit_code) {
494 		send_sig(current->exit_code, current, 1);
495 		current->exit_code = 0;
496 	}
497 
498 out:
499 	if (unlikely(current->audit_context) && !entryexit)
500 		audit_syscall_entry(audit_arch(), regs->regs[0],
501 				    regs->regs[4], regs->regs[5],
502 				    regs->regs[6], regs->regs[7]);
503 }
504