xref: /openbmc/linux/arch/sparc/kernel/ptrace_64.c (revision c8ed9fc9)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* ptrace.c: Sparc process tracing support.
3  *
4  * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
5  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6  *
7  * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
8  * and David Mosberger.
9  *
10  * Added Linux support -miguel (weird, eh?, the original code was meant
11  * to emulate SunOS).
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/sched/task_stack.h>
17 #include <linux/mm.h>
18 #include <linux/errno.h>
19 #include <linux/export.h>
20 #include <linux/ptrace.h>
21 #include <linux/user.h>
22 #include <linux/smp.h>
23 #include <linux/security.h>
24 #include <linux/seccomp.h>
25 #include <linux/audit.h>
26 #include <linux/signal.h>
27 #include <linux/regset.h>
28 #include <linux/tracehook.h>
29 #include <trace/syscall.h>
30 #include <linux/compat.h>
31 #include <linux/elf.h>
32 #include <linux/context_tracking.h>
33 
34 #include <asm/asi.h>
35 #include <linux/uaccess.h>
36 #include <asm/psrcompat.h>
37 #include <asm/visasm.h>
38 #include <asm/spitfire.h>
39 #include <asm/page.h>
40 #include <asm/cpudata.h>
41 #include <asm/cacheflush.h>
42 
43 #define CREATE_TRACE_POINTS
44 #include <trace/events/syscalls.h>
45 
46 #include "entry.h"
47 
48 /* #define ALLOW_INIT_TRACING */
49 
50 struct pt_regs_offset {
51 	const char *name;
52 	int offset;
53 };
54 
55 #define REG_OFFSET_NAME(n, r) \
56 	{.name = n, .offset = (PT_V9_##r)}
57 #define REG_OFFSET_END {.name = NULL, .offset = 0}
58 
59 static const struct pt_regs_offset regoffset_table[] = {
60 	REG_OFFSET_NAME("g0", G0),
61 	REG_OFFSET_NAME("g1", G1),
62 	REG_OFFSET_NAME("g2", G2),
63 	REG_OFFSET_NAME("g3", G3),
64 	REG_OFFSET_NAME("g4", G4),
65 	REG_OFFSET_NAME("g5", G5),
66 	REG_OFFSET_NAME("g6", G6),
67 	REG_OFFSET_NAME("g7", G7),
68 
69 	REG_OFFSET_NAME("i0", I0),
70 	REG_OFFSET_NAME("i1", I1),
71 	REG_OFFSET_NAME("i2", I2),
72 	REG_OFFSET_NAME("i3", I3),
73 	REG_OFFSET_NAME("i4", I4),
74 	REG_OFFSET_NAME("i5", I5),
75 	REG_OFFSET_NAME("i6", I6),
76 	REG_OFFSET_NAME("i7", I7),
77 
78 	REG_OFFSET_NAME("tstate", TSTATE),
79 	REG_OFFSET_NAME("pc", TPC),
80 	REG_OFFSET_NAME("npc", TNPC),
81 	REG_OFFSET_NAME("y", Y),
82 	REG_OFFSET_NAME("lr", I7),
83 
84 	REG_OFFSET_END,
85 };
86 
87 /*
88  * Called by kernel/ptrace.c when detaching..
89  *
90  * Make sure single step bits etc are not set.
91  */
92 void ptrace_disable(struct task_struct *child)
93 {
94 	/* nothing to do */
95 }
96 
97 /* To get the necessary page struct, access_process_vm() first calls
98  * get_user_pages().  This has done a flush_dcache_page() on the
99  * accessed page.  Then our caller (copy_{to,from}_user_page()) did
100  * to memcpy to read/write the data from that page.
101  *
102  * Now, the only thing we have to do is:
103  * 1) flush the D-cache if it's possible than an illegal alias
104  *    has been created
105  * 2) flush the I-cache if this is pre-cheetah and we did a write
106  */
107 void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
108 			 unsigned long uaddr, void *kaddr,
109 			 unsigned long len, int write)
110 {
111 	BUG_ON(len > PAGE_SIZE);
112 
113 	if (tlb_type == hypervisor)
114 		return;
115 
116 	preempt_disable();
117 
118 #ifdef DCACHE_ALIASING_POSSIBLE
119 	/* If bit 13 of the kernel address we used to access the
120 	 * user page is the same as the virtual address that page
121 	 * is mapped to in the user's address space, we can skip the
122 	 * D-cache flush.
123 	 */
124 	if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
125 		unsigned long start = __pa(kaddr);
126 		unsigned long end = start + len;
127 		unsigned long dcache_line_size;
128 
129 		dcache_line_size = local_cpu_data().dcache_line_size;
130 
131 		if (tlb_type == spitfire) {
132 			for (; start < end; start += dcache_line_size)
133 				spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
134 		} else {
135 			start &= ~(dcache_line_size - 1);
136 			for (; start < end; start += dcache_line_size)
137 				__asm__ __volatile__(
138 					"stxa %%g0, [%0] %1\n\t"
139 					"membar #Sync"
140 					: /* no outputs */
141 					: "r" (start),
142 					"i" (ASI_DCACHE_INVALIDATE));
143 		}
144 	}
145 #endif
146 	if (write && tlb_type == spitfire) {
147 		unsigned long start = (unsigned long) kaddr;
148 		unsigned long end = start + len;
149 		unsigned long icache_line_size;
150 
151 		icache_line_size = local_cpu_data().icache_line_size;
152 
153 		for (; start < end; start += icache_line_size)
154 			flushi(start);
155 	}
156 
157 	preempt_enable();
158 }
159 EXPORT_SYMBOL_GPL(flush_ptrace_access);
160 
161 static int get_from_target(struct task_struct *target, unsigned long uaddr,
162 			   void *kbuf, int len)
163 {
164 	if (target == current) {
165 		if (copy_from_user(kbuf, (void __user *) uaddr, len))
166 			return -EFAULT;
167 	} else {
168 		int len2 = access_process_vm(target, uaddr, kbuf, len,
169 				FOLL_FORCE);
170 		if (len2 != len)
171 			return -EFAULT;
172 	}
173 	return 0;
174 }
175 
176 static int set_to_target(struct task_struct *target, unsigned long uaddr,
177 			 void *kbuf, int len)
178 {
179 	if (target == current) {
180 		if (copy_to_user((void __user *) uaddr, kbuf, len))
181 			return -EFAULT;
182 	} else {
183 		int len2 = access_process_vm(target, uaddr, kbuf, len,
184 				FOLL_FORCE | FOLL_WRITE);
185 		if (len2 != len)
186 			return -EFAULT;
187 	}
188 	return 0;
189 }
190 
191 static int regwindow64_get(struct task_struct *target,
192 			   const struct pt_regs *regs,
193 			   struct reg_window *wbuf)
194 {
195 	unsigned long rw_addr = regs->u_regs[UREG_I6];
196 
197 	if (!test_thread_64bit_stack(rw_addr)) {
198 		struct reg_window32 win32;
199 		int i;
200 
201 		if (get_from_target(target, rw_addr, &win32, sizeof(win32)))
202 			return -EFAULT;
203 		for (i = 0; i < 8; i++)
204 			wbuf->locals[i] = win32.locals[i];
205 		for (i = 0; i < 8; i++)
206 			wbuf->ins[i] = win32.ins[i];
207 	} else {
208 		rw_addr += STACK_BIAS;
209 		if (get_from_target(target, rw_addr, wbuf, sizeof(*wbuf)))
210 			return -EFAULT;
211 	}
212 
213 	return 0;
214 }
215 
216 static int regwindow64_set(struct task_struct *target,
217 			   const struct pt_regs *regs,
218 			   struct reg_window *wbuf)
219 {
220 	unsigned long rw_addr = regs->u_regs[UREG_I6];
221 
222 	if (!test_thread_64bit_stack(rw_addr)) {
223 		struct reg_window32 win32;
224 		int i;
225 
226 		for (i = 0; i < 8; i++)
227 			win32.locals[i] = wbuf->locals[i];
228 		for (i = 0; i < 8; i++)
229 			win32.ins[i] = wbuf->ins[i];
230 
231 		if (set_to_target(target, rw_addr, &win32, sizeof(win32)))
232 			return -EFAULT;
233 	} else {
234 		rw_addr += STACK_BIAS;
235 		if (set_to_target(target, rw_addr, wbuf, sizeof(*wbuf)))
236 			return -EFAULT;
237 	}
238 
239 	return 0;
240 }
241 
242 enum sparc_regset {
243 	REGSET_GENERAL,
244 	REGSET_FP,
245 };
246 
247 static int genregs64_get(struct task_struct *target,
248 			 const struct user_regset *regset,
249 			 unsigned int pos, unsigned int count,
250 			 void *kbuf, void __user *ubuf)
251 {
252 	const struct pt_regs *regs = task_pt_regs(target);
253 	int ret;
254 
255 	if (target == current)
256 		flushw_user();
257 
258 	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
259 				  regs->u_regs,
260 				  0, 16 * sizeof(u64));
261 	if (!ret && count && pos < (32 * sizeof(u64))) {
262 		struct reg_window window;
263 
264 		if (regwindow64_get(target, regs, &window))
265 			return -EFAULT;
266 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
267 					  &window,
268 					  16 * sizeof(u64),
269 					  32 * sizeof(u64));
270 	}
271 
272 	if (!ret) {
273 		/* TSTATE, TPC, TNPC */
274 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
275 					  &regs->tstate,
276 					  32 * sizeof(u64),
277 					  35 * sizeof(u64));
278 	}
279 
280 	if (!ret) {
281 		unsigned long y = regs->y;
282 
283 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
284 					  &y,
285 					  35 * sizeof(u64),
286 					  36 * sizeof(u64));
287 	}
288 
289 	if (!ret) {
290 		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
291 					       36 * sizeof(u64), -1);
292 
293 	}
294 	return ret;
295 }
296 
297 static int genregs64_set(struct task_struct *target,
298 			 const struct user_regset *regset,
299 			 unsigned int pos, unsigned int count,
300 			 const void *kbuf, const void __user *ubuf)
301 {
302 	struct pt_regs *regs = task_pt_regs(target);
303 	int ret;
304 
305 	if (target == current)
306 		flushw_user();
307 
308 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
309 				 regs->u_regs,
310 				 0, 16 * sizeof(u64));
311 	if (!ret && count && pos < (32 * sizeof(u64))) {
312 		struct reg_window window;
313 
314 		if (regwindow64_get(target, regs, &window))
315 			return -EFAULT;
316 
317 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
318 					 &window,
319 					 16 * sizeof(u64),
320 					 32 * sizeof(u64));
321 
322 		if (!ret &&
323 		    regwindow64_set(target, regs, &window))
324 			return -EFAULT;
325 	}
326 
327 	if (!ret && count > 0) {
328 		unsigned long tstate;
329 
330 		/* TSTATE */
331 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
332 					 &tstate,
333 					 32 * sizeof(u64),
334 					 33 * sizeof(u64));
335 		if (!ret) {
336 			/* Only the condition codes and the "in syscall"
337 			 * state can be modified in the %tstate register.
338 			 */
339 			tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
340 			regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
341 			regs->tstate |= tstate;
342 		}
343 	}
344 
345 	if (!ret) {
346 		/* TPC, TNPC */
347 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
348 					 &regs->tpc,
349 					 33 * sizeof(u64),
350 					 35 * sizeof(u64));
351 	}
352 
353 	if (!ret) {
354 		unsigned long y = regs->y;
355 
356 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
357 					 &y,
358 					 35 * sizeof(u64),
359 					 36 * sizeof(u64));
360 		if (!ret)
361 			regs->y = y;
362 	}
363 
364 	if (!ret)
365 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
366 						36 * sizeof(u64), -1);
367 
368 	return ret;
369 }
370 
371 static int fpregs64_get(struct task_struct *target,
372 			const struct user_regset *regset,
373 			unsigned int pos, unsigned int count,
374 			void *kbuf, void __user *ubuf)
375 {
376 	const unsigned long *fpregs = task_thread_info(target)->fpregs;
377 	unsigned long fprs, fsr, gsr;
378 	int ret;
379 
380 	if (target == current)
381 		save_and_clear_fpu();
382 
383 	fprs = task_thread_info(target)->fpsaved[0];
384 
385 	if (fprs & FPRS_DL)
386 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
387 					  fpregs,
388 					  0, 16 * sizeof(u64));
389 	else
390 		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
391 					       0,
392 					       16 * sizeof(u64));
393 
394 	if (!ret) {
395 		if (fprs & FPRS_DU)
396 			ret = user_regset_copyout(&pos, &count,
397 						  &kbuf, &ubuf,
398 						  fpregs + 16,
399 						  16 * sizeof(u64),
400 						  32 * sizeof(u64));
401 		else
402 			ret = user_regset_copyout_zero(&pos, &count,
403 						       &kbuf, &ubuf,
404 						       16 * sizeof(u64),
405 						       32 * sizeof(u64));
406 	}
407 
408 	if (fprs & FPRS_FEF) {
409 		fsr = task_thread_info(target)->xfsr[0];
410 		gsr = task_thread_info(target)->gsr[0];
411 	} else {
412 		fsr = gsr = 0;
413 	}
414 
415 	if (!ret)
416 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
417 					  &fsr,
418 					  32 * sizeof(u64),
419 					  33 * sizeof(u64));
420 	if (!ret)
421 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
422 					  &gsr,
423 					  33 * sizeof(u64),
424 					  34 * sizeof(u64));
425 	if (!ret)
426 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
427 					  &fprs,
428 					  34 * sizeof(u64),
429 					  35 * sizeof(u64));
430 
431 	if (!ret)
432 		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
433 					       35 * sizeof(u64), -1);
434 
435 	return ret;
436 }
437 
438 static int fpregs64_set(struct task_struct *target,
439 			const struct user_regset *regset,
440 			unsigned int pos, unsigned int count,
441 			const void *kbuf, const void __user *ubuf)
442 {
443 	unsigned long *fpregs = task_thread_info(target)->fpregs;
444 	unsigned long fprs;
445 	int ret;
446 
447 	if (target == current)
448 		save_and_clear_fpu();
449 
450 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
451 				 fpregs,
452 				 0, 32 * sizeof(u64));
453 	if (!ret)
454 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
455 					 task_thread_info(target)->xfsr,
456 					 32 * sizeof(u64),
457 					 33 * sizeof(u64));
458 	if (!ret)
459 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
460 					 task_thread_info(target)->gsr,
461 					 33 * sizeof(u64),
462 					 34 * sizeof(u64));
463 
464 	fprs = task_thread_info(target)->fpsaved[0];
465 	if (!ret && count > 0) {
466 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
467 					 &fprs,
468 					 34 * sizeof(u64),
469 					 35 * sizeof(u64));
470 	}
471 
472 	fprs |= (FPRS_FEF | FPRS_DL | FPRS_DU);
473 	task_thread_info(target)->fpsaved[0] = fprs;
474 
475 	if (!ret)
476 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
477 						35 * sizeof(u64), -1);
478 	return ret;
479 }
480 
481 static const struct user_regset sparc64_regsets[] = {
482 	/* Format is:
483 	 * 	G0 --> G7
484 	 *	O0 --> O7
485 	 *	L0 --> L7
486 	 *	I0 --> I7
487 	 *	TSTATE, TPC, TNPC, Y
488 	 */
489 	[REGSET_GENERAL] = {
490 		.core_note_type = NT_PRSTATUS,
491 		.n = 36,
492 		.size = sizeof(u64), .align = sizeof(u64),
493 		.get = genregs64_get, .set = genregs64_set
494 	},
495 	/* Format is:
496 	 *	F0 --> F63
497 	 *	FSR
498 	 *	GSR
499 	 *	FPRS
500 	 */
501 	[REGSET_FP] = {
502 		.core_note_type = NT_PRFPREG,
503 		.n = 35,
504 		.size = sizeof(u64), .align = sizeof(u64),
505 		.get = fpregs64_get, .set = fpregs64_set
506 	},
507 };
508 
509 static const struct user_regset_view user_sparc64_view = {
510 	.name = "sparc64", .e_machine = EM_SPARCV9,
511 	.regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets)
512 };
513 
514 #ifdef CONFIG_COMPAT
515 static int genregs32_get(struct task_struct *target,
516 			 const struct user_regset *regset,
517 			 unsigned int pos, unsigned int count,
518 			 void *kbuf, void __user *ubuf)
519 {
520 	const struct pt_regs *regs = task_pt_regs(target);
521 	compat_ulong_t __user *reg_window;
522 	compat_ulong_t *k = kbuf;
523 	compat_ulong_t __user *u = ubuf;
524 	compat_ulong_t reg;
525 
526 	if (target == current)
527 		flushw_user();
528 
529 	pos /= sizeof(reg);
530 	count /= sizeof(reg);
531 
532 	if (kbuf) {
533 		for (; count > 0 && pos < 16; count--)
534 			*k++ = regs->u_regs[pos++];
535 
536 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
537 		reg_window -= 16;
538 		if (target == current) {
539 			for (; count > 0 && pos < 32; count--) {
540 				if (get_user(*k++, &reg_window[pos++]))
541 					return -EFAULT;
542 			}
543 		} else {
544 			for (; count > 0 && pos < 32; count--) {
545 				if (access_process_vm(target,
546 						      (unsigned long)
547 						      &reg_window[pos],
548 						      k, sizeof(*k),
549 						      FOLL_FORCE)
550 				    != sizeof(*k))
551 					return -EFAULT;
552 				k++;
553 				pos++;
554 			}
555 		}
556 	} else {
557 		for (; count > 0 && pos < 16; count--) {
558 			if (put_user((compat_ulong_t) regs->u_regs[pos++], u++))
559 				return -EFAULT;
560 		}
561 
562 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
563 		reg_window -= 16;
564 		if (target == current) {
565 			for (; count > 0 && pos < 32; count--) {
566 				if (get_user(reg, &reg_window[pos++]) ||
567 				    put_user(reg, u++))
568 					return -EFAULT;
569 			}
570 		} else {
571 			for (; count > 0 && pos < 32; count--) {
572 				if (access_process_vm(target,
573 						      (unsigned long)
574 						      &reg_window[pos++],
575 						      &reg, sizeof(reg),
576 						      FOLL_FORCE)
577 				    != sizeof(reg))
578 					return -EFAULT;
579 				if (put_user(reg, u++))
580 					return -EFAULT;
581 			}
582 		}
583 	}
584 	while (count > 0) {
585 		switch (pos) {
586 		case 32: /* PSR */
587 			reg = tstate_to_psr(regs->tstate);
588 			break;
589 		case 33: /* PC */
590 			reg = regs->tpc;
591 			break;
592 		case 34: /* NPC */
593 			reg = regs->tnpc;
594 			break;
595 		case 35: /* Y */
596 			reg = regs->y;
597 			break;
598 		case 36: /* WIM */
599 		case 37: /* TBR */
600 			reg = 0;
601 			break;
602 		default:
603 			goto finish;
604 		}
605 
606 		if (kbuf)
607 			*k++ = reg;
608 		else if (put_user(reg, u++))
609 			return -EFAULT;
610 		pos++;
611 		count--;
612 	}
613 finish:
614 	pos *= sizeof(reg);
615 	count *= sizeof(reg);
616 
617 	return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
618 					38 * sizeof(reg), -1);
619 }
620 
621 static int genregs32_set(struct task_struct *target,
622 			 const struct user_regset *regset,
623 			 unsigned int pos, unsigned int count,
624 			 const void *kbuf, const void __user *ubuf)
625 {
626 	struct pt_regs *regs = task_pt_regs(target);
627 	compat_ulong_t __user *reg_window;
628 	const compat_ulong_t *k = kbuf;
629 	const compat_ulong_t __user *u = ubuf;
630 	compat_ulong_t reg;
631 
632 	if (target == current)
633 		flushw_user();
634 
635 	pos /= sizeof(reg);
636 	count /= sizeof(reg);
637 
638 	if (kbuf) {
639 		for (; count > 0 && pos < 16; count--)
640 			regs->u_regs[pos++] = *k++;
641 
642 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
643 		reg_window -= 16;
644 		if (target == current) {
645 			for (; count > 0 && pos < 32; count--) {
646 				if (put_user(*k++, &reg_window[pos++]))
647 					return -EFAULT;
648 			}
649 		} else {
650 			for (; count > 0 && pos < 32; count--) {
651 				if (access_process_vm(target,
652 						      (unsigned long)
653 						      &reg_window[pos],
654 						      (void *) k,
655 						      sizeof(*k),
656 						      FOLL_FORCE | FOLL_WRITE)
657 				    != sizeof(*k))
658 					return -EFAULT;
659 				k++;
660 				pos++;
661 			}
662 		}
663 	} else {
664 		for (; count > 0 && pos < 16; count--) {
665 			if (get_user(reg, u++))
666 				return -EFAULT;
667 			regs->u_regs[pos++] = reg;
668 		}
669 
670 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
671 		reg_window -= 16;
672 		if (target == current) {
673 			for (; count > 0 && pos < 32; count--) {
674 				if (get_user(reg, u++) ||
675 				    put_user(reg, &reg_window[pos++]))
676 					return -EFAULT;
677 			}
678 		} else {
679 			for (; count > 0 && pos < 32; count--) {
680 				if (get_user(reg, u++))
681 					return -EFAULT;
682 				if (access_process_vm(target,
683 						      (unsigned long)
684 						      &reg_window[pos],
685 						      &reg, sizeof(reg),
686 						      FOLL_FORCE | FOLL_WRITE)
687 				    != sizeof(reg))
688 					return -EFAULT;
689 				pos++;
690 				u++;
691 			}
692 		}
693 	}
694 	while (count > 0) {
695 		unsigned long tstate;
696 
697 		if (kbuf)
698 			reg = *k++;
699 		else if (get_user(reg, u++))
700 			return -EFAULT;
701 
702 		switch (pos) {
703 		case 32: /* PSR */
704 			tstate = regs->tstate;
705 			tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
706 			tstate |= psr_to_tstate_icc(reg);
707 			if (reg & PSR_SYSCALL)
708 				tstate |= TSTATE_SYSCALL;
709 			regs->tstate = tstate;
710 			break;
711 		case 33: /* PC */
712 			regs->tpc = reg;
713 			break;
714 		case 34: /* NPC */
715 			regs->tnpc = reg;
716 			break;
717 		case 35: /* Y */
718 			regs->y = reg;
719 			break;
720 		case 36: /* WIM */
721 		case 37: /* TBR */
722 			break;
723 		default:
724 			goto finish;
725 		}
726 
727 		pos++;
728 		count--;
729 	}
730 finish:
731 	pos *= sizeof(reg);
732 	count *= sizeof(reg);
733 
734 	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
735 					 38 * sizeof(reg), -1);
736 }
737 
738 static int fpregs32_get(struct task_struct *target,
739 			const struct user_regset *regset,
740 			unsigned int pos, unsigned int count,
741 			void *kbuf, void __user *ubuf)
742 {
743 	const unsigned long *fpregs = task_thread_info(target)->fpregs;
744 	compat_ulong_t enabled;
745 	unsigned long fprs;
746 	compat_ulong_t fsr;
747 	int ret = 0;
748 
749 	if (target == current)
750 		save_and_clear_fpu();
751 
752 	fprs = task_thread_info(target)->fpsaved[0];
753 	if (fprs & FPRS_FEF) {
754 		fsr = task_thread_info(target)->xfsr[0];
755 		enabled = 1;
756 	} else {
757 		fsr = 0;
758 		enabled = 0;
759 	}
760 
761 	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
762 				  fpregs,
763 				  0, 32 * sizeof(u32));
764 
765 	if (!ret)
766 		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
767 					       32 * sizeof(u32),
768 					       33 * sizeof(u32));
769 	if (!ret)
770 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
771 					  &fsr,
772 					  33 * sizeof(u32),
773 					  34 * sizeof(u32));
774 
775 	if (!ret) {
776 		compat_ulong_t val;
777 
778 		val = (enabled << 8) | (8 << 16);
779 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
780 					  &val,
781 					  34 * sizeof(u32),
782 					  35 * sizeof(u32));
783 	}
784 
785 	if (!ret)
786 		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
787 					       35 * sizeof(u32), -1);
788 
789 	return ret;
790 }
791 
792 static int fpregs32_set(struct task_struct *target,
793 			const struct user_regset *regset,
794 			unsigned int pos, unsigned int count,
795 			const void *kbuf, const void __user *ubuf)
796 {
797 	unsigned long *fpregs = task_thread_info(target)->fpregs;
798 	unsigned long fprs;
799 	int ret;
800 
801 	if (target == current)
802 		save_and_clear_fpu();
803 
804 	fprs = task_thread_info(target)->fpsaved[0];
805 
806 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
807 				 fpregs,
808 				 0, 32 * sizeof(u32));
809 	if (!ret)
810 		user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
811 					  32 * sizeof(u32),
812 					  33 * sizeof(u32));
813 	if (!ret && count > 0) {
814 		compat_ulong_t fsr;
815 		unsigned long val;
816 
817 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
818 					 &fsr,
819 					 33 * sizeof(u32),
820 					 34 * sizeof(u32));
821 		if (!ret) {
822 			val = task_thread_info(target)->xfsr[0];
823 			val &= 0xffffffff00000000UL;
824 			val |= fsr;
825 			task_thread_info(target)->xfsr[0] = val;
826 		}
827 	}
828 
829 	fprs |= (FPRS_FEF | FPRS_DL);
830 	task_thread_info(target)->fpsaved[0] = fprs;
831 
832 	if (!ret)
833 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
834 						34 * sizeof(u32), -1);
835 	return ret;
836 }
837 
838 static const struct user_regset sparc32_regsets[] = {
839 	/* Format is:
840 	 * 	G0 --> G7
841 	 *	O0 --> O7
842 	 *	L0 --> L7
843 	 *	I0 --> I7
844 	 *	PSR, PC, nPC, Y, WIM, TBR
845 	 */
846 	[REGSET_GENERAL] = {
847 		.core_note_type = NT_PRSTATUS,
848 		.n = 38,
849 		.size = sizeof(u32), .align = sizeof(u32),
850 		.get = genregs32_get, .set = genregs32_set
851 	},
852 	/* Format is:
853 	 *	F0 --> F31
854 	 *	empty 32-bit word
855 	 *	FSR (32--bit word)
856 	 *	FPU QUEUE COUNT (8-bit char)
857 	 *	FPU QUEUE ENTRYSIZE (8-bit char)
858 	 *	FPU ENABLED (8-bit char)
859 	 *	empty 8-bit char
860 	 *	FPU QUEUE (64 32-bit ints)
861 	 */
862 	[REGSET_FP] = {
863 		.core_note_type = NT_PRFPREG,
864 		.n = 99,
865 		.size = sizeof(u32), .align = sizeof(u32),
866 		.get = fpregs32_get, .set = fpregs32_set
867 	},
868 };
869 
870 static const struct user_regset_view user_sparc32_view = {
871 	.name = "sparc", .e_machine = EM_SPARC,
872 	.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
873 };
874 #endif /* CONFIG_COMPAT */
875 
876 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
877 {
878 #ifdef CONFIG_COMPAT
879 	if (test_tsk_thread_flag(task, TIF_32BIT))
880 		return &user_sparc32_view;
881 #endif
882 	return &user_sparc64_view;
883 }
884 
885 #ifdef CONFIG_COMPAT
886 struct compat_fps {
887 	unsigned int regs[32];
888 	unsigned int fsr;
889 	unsigned int flags;
890 	unsigned int extra;
891 	unsigned int fpqd;
892 	struct compat_fq {
893 		unsigned int insnaddr;
894 		unsigned int insn;
895 	} fpq[16];
896 };
897 
898 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
899 			compat_ulong_t caddr, compat_ulong_t cdata)
900 {
901 	const struct user_regset_view *view = task_user_regset_view(current);
902 	compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
903 	struct pt_regs32 __user *pregs;
904 	struct compat_fps __user *fps;
905 	unsigned long addr2 = caddr2;
906 	unsigned long addr = caddr;
907 	unsigned long data = cdata;
908 	int ret;
909 
910 	pregs = (struct pt_regs32 __user *) addr;
911 	fps = (struct compat_fps __user *) addr;
912 
913 	switch (request) {
914 	case PTRACE_PEEKUSR:
915 		ret = (addr != 0) ? -EIO : 0;
916 		break;
917 
918 	case PTRACE_GETREGS:
919 		ret = copy_regset_to_user(child, view, REGSET_GENERAL,
920 					  32 * sizeof(u32),
921 					  4 * sizeof(u32),
922 					  &pregs->psr);
923 		if (!ret)
924 			ret = copy_regset_to_user(child, view, REGSET_GENERAL,
925 						  1 * sizeof(u32),
926 						  15 * sizeof(u32),
927 						  &pregs->u_regs[0]);
928 		break;
929 
930 	case PTRACE_SETREGS:
931 		ret = copy_regset_from_user(child, view, REGSET_GENERAL,
932 					    32 * sizeof(u32),
933 					    4 * sizeof(u32),
934 					    &pregs->psr);
935 		if (!ret)
936 			ret = copy_regset_from_user(child, view, REGSET_GENERAL,
937 						    1 * sizeof(u32),
938 						    15 * sizeof(u32),
939 						    &pregs->u_regs[0]);
940 		break;
941 
942 	case PTRACE_GETFPREGS:
943 		ret = copy_regset_to_user(child, view, REGSET_FP,
944 					  0 * sizeof(u32),
945 					  32 * sizeof(u32),
946 					  &fps->regs[0]);
947 		if (!ret)
948 			ret = copy_regset_to_user(child, view, REGSET_FP,
949 						  33 * sizeof(u32),
950 						  1 * sizeof(u32),
951 						  &fps->fsr);
952 		if (!ret) {
953 			if (__put_user(0, &fps->flags) ||
954 			    __put_user(0, &fps->extra) ||
955 			    __put_user(0, &fps->fpqd) ||
956 			    clear_user(&fps->fpq[0], 32 * sizeof(unsigned int)))
957 				ret = -EFAULT;
958 		}
959 		break;
960 
961 	case PTRACE_SETFPREGS:
962 		ret = copy_regset_from_user(child, view, REGSET_FP,
963 					    0 * sizeof(u32),
964 					    32 * sizeof(u32),
965 					    &fps->regs[0]);
966 		if (!ret)
967 			ret = copy_regset_from_user(child, view, REGSET_FP,
968 						    33 * sizeof(u32),
969 						    1 * sizeof(u32),
970 						    &fps->fsr);
971 		break;
972 
973 	case PTRACE_READTEXT:
974 	case PTRACE_READDATA:
975 		ret = ptrace_readdata(child, addr,
976 				      (char __user *)addr2, data);
977 		if (ret == data)
978 			ret = 0;
979 		else if (ret >= 0)
980 			ret = -EIO;
981 		break;
982 
983 	case PTRACE_WRITETEXT:
984 	case PTRACE_WRITEDATA:
985 		ret = ptrace_writedata(child, (char __user *) addr2,
986 				       addr, data);
987 		if (ret == data)
988 			ret = 0;
989 		else if (ret >= 0)
990 			ret = -EIO;
991 		break;
992 
993 	default:
994 		if (request == PTRACE_SPARC_DETACH)
995 			request = PTRACE_DETACH;
996 		ret = compat_ptrace_request(child, request, addr, data);
997 		break;
998 	}
999 
1000 	return ret;
1001 }
1002 #endif /* CONFIG_COMPAT */
1003 
1004 struct fps {
1005 	unsigned int regs[64];
1006 	unsigned long fsr;
1007 };
1008 
1009 long arch_ptrace(struct task_struct *child, long request,
1010 		 unsigned long addr, unsigned long data)
1011 {
1012 	const struct user_regset_view *view = task_user_regset_view(current);
1013 	unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
1014 	struct pt_regs __user *pregs;
1015 	struct fps __user *fps;
1016 	void __user *addr2p;
1017 	int ret;
1018 
1019 	pregs = (struct pt_regs __user *) addr;
1020 	fps = (struct fps __user *) addr;
1021 	addr2p = (void __user *) addr2;
1022 
1023 	switch (request) {
1024 	case PTRACE_PEEKUSR:
1025 		ret = (addr != 0) ? -EIO : 0;
1026 		break;
1027 
1028 	case PTRACE_GETREGS64:
1029 		ret = copy_regset_to_user(child, view, REGSET_GENERAL,
1030 					  1 * sizeof(u64),
1031 					  15 * sizeof(u64),
1032 					  &pregs->u_regs[0]);
1033 		if (!ret) {
1034 			/* XXX doesn't handle 'y' register correctly XXX */
1035 			ret = copy_regset_to_user(child, view, REGSET_GENERAL,
1036 						  32 * sizeof(u64),
1037 						  4 * sizeof(u64),
1038 						  &pregs->tstate);
1039 		}
1040 		break;
1041 
1042 	case PTRACE_SETREGS64:
1043 		ret = copy_regset_from_user(child, view, REGSET_GENERAL,
1044 					    1 * sizeof(u64),
1045 					    15 * sizeof(u64),
1046 					    &pregs->u_regs[0]);
1047 		if (!ret) {
1048 			/* XXX doesn't handle 'y' register correctly XXX */
1049 			ret = copy_regset_from_user(child, view, REGSET_GENERAL,
1050 						    32 * sizeof(u64),
1051 						    4 * sizeof(u64),
1052 						    &pregs->tstate);
1053 		}
1054 		break;
1055 
1056 	case PTRACE_GETFPREGS64:
1057 		ret = copy_regset_to_user(child, view, REGSET_FP,
1058 					  0 * sizeof(u64),
1059 					  33 * sizeof(u64),
1060 					  fps);
1061 		break;
1062 
1063 	case PTRACE_SETFPREGS64:
1064 		ret = copy_regset_from_user(child, view, REGSET_FP,
1065 					  0 * sizeof(u64),
1066 					  33 * sizeof(u64),
1067 					  fps);
1068 		break;
1069 
1070 	case PTRACE_READTEXT:
1071 	case PTRACE_READDATA:
1072 		ret = ptrace_readdata(child, addr, addr2p, data);
1073 		if (ret == data)
1074 			ret = 0;
1075 		else if (ret >= 0)
1076 			ret = -EIO;
1077 		break;
1078 
1079 	case PTRACE_WRITETEXT:
1080 	case PTRACE_WRITEDATA:
1081 		ret = ptrace_writedata(child, addr2p, addr, data);
1082 		if (ret == data)
1083 			ret = 0;
1084 		else if (ret >= 0)
1085 			ret = -EIO;
1086 		break;
1087 
1088 	default:
1089 		if (request == PTRACE_SPARC_DETACH)
1090 			request = PTRACE_DETACH;
1091 		ret = ptrace_request(child, request, addr, data);
1092 		break;
1093 	}
1094 
1095 	return ret;
1096 }
1097 
1098 asmlinkage int syscall_trace_enter(struct pt_regs *regs)
1099 {
1100 	int ret = 0;
1101 
1102 	/* do the secure computing check first */
1103 	secure_computing_strict(regs->u_regs[UREG_G1]);
1104 
1105 	if (test_thread_flag(TIF_NOHZ))
1106 		user_exit();
1107 
1108 	if (test_thread_flag(TIF_SYSCALL_TRACE))
1109 		ret = tracehook_report_syscall_entry(regs);
1110 
1111 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1112 		trace_sys_enter(regs, regs->u_regs[UREG_G1]);
1113 
1114 	audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0],
1115 			    regs->u_regs[UREG_I1], regs->u_regs[UREG_I2],
1116 			    regs->u_regs[UREG_I3]);
1117 
1118 	return ret;
1119 }
1120 
1121 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
1122 {
1123 	if (test_thread_flag(TIF_NOHZ))
1124 		user_exit();
1125 
1126 	audit_syscall_exit(regs);
1127 
1128 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1129 		trace_sys_exit(regs, regs->u_regs[UREG_I0]);
1130 
1131 	if (test_thread_flag(TIF_SYSCALL_TRACE))
1132 		tracehook_report_syscall_exit(regs, 0);
1133 
1134 	if (test_thread_flag(TIF_NOHZ))
1135 		user_enter();
1136 }
1137 
1138 /**
1139  * regs_query_register_offset() - query register offset from its name
1140  * @name:	the name of a register
1141  *
1142  * regs_query_register_offset() returns the offset of a register in struct
1143  * pt_regs from its name. If the name is invalid, this returns -EINVAL;
1144  */
1145 int regs_query_register_offset(const char *name)
1146 {
1147 	const struct pt_regs_offset *roff;
1148 
1149 	for (roff = regoffset_table; roff->name != NULL; roff++)
1150 		if (!strcmp(roff->name, name))
1151 			return roff->offset;
1152 	return -EINVAL;
1153 }
1154 
1155 /**
1156  * regs_within_kernel_stack() - check the address in the stack
1157  * @regs:	pt_regs which contains kernel stack pointer.
1158  * @addr:	address which is checked.
1159  *
1160  * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
1161  * If @addr is within the kernel stack, it returns true. If not, returns false.
1162  */
1163 static inline int regs_within_kernel_stack(struct pt_regs *regs,
1164 					   unsigned long addr)
1165 {
1166 	unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
1167 	return ((addr & ~(THREAD_SIZE - 1))  ==
1168 		(ksp & ~(THREAD_SIZE - 1)));
1169 }
1170 
1171 /**
1172  * regs_get_kernel_stack_nth() - get Nth entry of the stack
1173  * @regs:	pt_regs which contains kernel stack pointer.
1174  * @n:		stack entry number.
1175  *
1176  * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1177  * is specified by @regs. If the @n th entry is NOT in the kernel stack,
1178  * this returns 0.
1179  */
1180 unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
1181 {
1182 	unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
1183 	unsigned long *addr = (unsigned long *)ksp;
1184 	addr += n;
1185 	if (regs_within_kernel_stack(regs, (unsigned long)addr))
1186 		return *addr;
1187 	else
1188 		return 0;
1189 }
1190