xref: /openbmc/linux/arch/sparc/kernel/ptrace_64.c (revision 5ff32883)
1 /* ptrace.c: Sparc process tracing support.
2  *
3  * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
4  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5  *
6  * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
7  * and David Mosberger.
8  *
9  * Added Linux support -miguel (weird, eh?, the original code was meant
10  * to emulate SunOS).
11  */
12 
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/sched/task_stack.h>
16 #include <linux/mm.h>
17 #include <linux/errno.h>
18 #include <linux/export.h>
19 #include <linux/ptrace.h>
20 #include <linux/user.h>
21 #include <linux/smp.h>
22 #include <linux/security.h>
23 #include <linux/seccomp.h>
24 #include <linux/audit.h>
25 #include <linux/signal.h>
26 #include <linux/regset.h>
27 #include <linux/tracehook.h>
28 #include <trace/syscall.h>
29 #include <linux/compat.h>
30 #include <linux/elf.h>
31 #include <linux/context_tracking.h>
32 
33 #include <asm/asi.h>
34 #include <asm/pgtable.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 (access_process_vm(target,
580 						      (unsigned long) u,
581 						      &reg, sizeof(reg),
582 						      FOLL_FORCE | FOLL_WRITE)
583 				    != sizeof(reg))
584 					return -EFAULT;
585 				pos++;
586 				u++;
587 			}
588 		}
589 	}
590 	while (count > 0) {
591 		switch (pos) {
592 		case 32: /* PSR */
593 			reg = tstate_to_psr(regs->tstate);
594 			break;
595 		case 33: /* PC */
596 			reg = regs->tpc;
597 			break;
598 		case 34: /* NPC */
599 			reg = regs->tnpc;
600 			break;
601 		case 35: /* Y */
602 			reg = regs->y;
603 			break;
604 		case 36: /* WIM */
605 		case 37: /* TBR */
606 			reg = 0;
607 			break;
608 		default:
609 			goto finish;
610 		}
611 
612 		if (kbuf)
613 			*k++ = reg;
614 		else if (put_user(reg, u++))
615 			return -EFAULT;
616 		pos++;
617 		count--;
618 	}
619 finish:
620 	pos *= sizeof(reg);
621 	count *= sizeof(reg);
622 
623 	return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
624 					38 * sizeof(reg), -1);
625 }
626 
627 static int genregs32_set(struct task_struct *target,
628 			 const struct user_regset *regset,
629 			 unsigned int pos, unsigned int count,
630 			 const void *kbuf, const void __user *ubuf)
631 {
632 	struct pt_regs *regs = task_pt_regs(target);
633 	compat_ulong_t __user *reg_window;
634 	const compat_ulong_t *k = kbuf;
635 	const compat_ulong_t __user *u = ubuf;
636 	compat_ulong_t reg;
637 
638 	if (target == current)
639 		flushw_user();
640 
641 	pos /= sizeof(reg);
642 	count /= sizeof(reg);
643 
644 	if (kbuf) {
645 		for (; count > 0 && pos < 16; count--)
646 			regs->u_regs[pos++] = *k++;
647 
648 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
649 		reg_window -= 16;
650 		if (target == current) {
651 			for (; count > 0 && pos < 32; count--) {
652 				if (put_user(*k++, &reg_window[pos++]))
653 					return -EFAULT;
654 			}
655 		} else {
656 			for (; count > 0 && pos < 32; count--) {
657 				if (access_process_vm(target,
658 						      (unsigned long)
659 						      &reg_window[pos],
660 						      (void *) k,
661 						      sizeof(*k),
662 						      FOLL_FORCE | FOLL_WRITE)
663 				    != sizeof(*k))
664 					return -EFAULT;
665 				k++;
666 				pos++;
667 			}
668 		}
669 	} else {
670 		for (; count > 0 && pos < 16; count--) {
671 			if (get_user(reg, u++))
672 				return -EFAULT;
673 			regs->u_regs[pos++] = reg;
674 		}
675 
676 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
677 		reg_window -= 16;
678 		if (target == current) {
679 			for (; count > 0 && pos < 32; count--) {
680 				if (get_user(reg, u++) ||
681 				    put_user(reg, &reg_window[pos++]))
682 					return -EFAULT;
683 			}
684 		} else {
685 			for (; count > 0 && pos < 32; count--) {
686 				if (access_process_vm(target,
687 						      (unsigned long)
688 						      u,
689 						      &reg, sizeof(reg),
690 						      FOLL_FORCE)
691 				    != sizeof(reg))
692 					return -EFAULT;
693 				if (access_process_vm(target,
694 						      (unsigned long)
695 						      &reg_window[pos],
696 						      &reg, sizeof(reg),
697 						      FOLL_FORCE | FOLL_WRITE)
698 				    != sizeof(reg))
699 					return -EFAULT;
700 				pos++;
701 				u++;
702 			}
703 		}
704 	}
705 	while (count > 0) {
706 		unsigned long tstate;
707 
708 		if (kbuf)
709 			reg = *k++;
710 		else if (get_user(reg, u++))
711 			return -EFAULT;
712 
713 		switch (pos) {
714 		case 32: /* PSR */
715 			tstate = regs->tstate;
716 			tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
717 			tstate |= psr_to_tstate_icc(reg);
718 			if (reg & PSR_SYSCALL)
719 				tstate |= TSTATE_SYSCALL;
720 			regs->tstate = tstate;
721 			break;
722 		case 33: /* PC */
723 			regs->tpc = reg;
724 			break;
725 		case 34: /* NPC */
726 			regs->tnpc = reg;
727 			break;
728 		case 35: /* Y */
729 			regs->y = reg;
730 			break;
731 		case 36: /* WIM */
732 		case 37: /* TBR */
733 			break;
734 		default:
735 			goto finish;
736 		}
737 
738 		pos++;
739 		count--;
740 	}
741 finish:
742 	pos *= sizeof(reg);
743 	count *= sizeof(reg);
744 
745 	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
746 					 38 * sizeof(reg), -1);
747 }
748 
749 static int fpregs32_get(struct task_struct *target,
750 			const struct user_regset *regset,
751 			unsigned int pos, unsigned int count,
752 			void *kbuf, void __user *ubuf)
753 {
754 	const unsigned long *fpregs = task_thread_info(target)->fpregs;
755 	compat_ulong_t enabled;
756 	unsigned long fprs;
757 	compat_ulong_t fsr;
758 	int ret = 0;
759 
760 	if (target == current)
761 		save_and_clear_fpu();
762 
763 	fprs = task_thread_info(target)->fpsaved[0];
764 	if (fprs & FPRS_FEF) {
765 		fsr = task_thread_info(target)->xfsr[0];
766 		enabled = 1;
767 	} else {
768 		fsr = 0;
769 		enabled = 0;
770 	}
771 
772 	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
773 				  fpregs,
774 				  0, 32 * sizeof(u32));
775 
776 	if (!ret)
777 		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
778 					       32 * sizeof(u32),
779 					       33 * sizeof(u32));
780 	if (!ret)
781 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
782 					  &fsr,
783 					  33 * sizeof(u32),
784 					  34 * sizeof(u32));
785 
786 	if (!ret) {
787 		compat_ulong_t val;
788 
789 		val = (enabled << 8) | (8 << 16);
790 		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
791 					  &val,
792 					  34 * sizeof(u32),
793 					  35 * sizeof(u32));
794 	}
795 
796 	if (!ret)
797 		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
798 					       35 * sizeof(u32), -1);
799 
800 	return ret;
801 }
802 
803 static int fpregs32_set(struct task_struct *target,
804 			const struct user_regset *regset,
805 			unsigned int pos, unsigned int count,
806 			const void *kbuf, const void __user *ubuf)
807 {
808 	unsigned long *fpregs = task_thread_info(target)->fpregs;
809 	unsigned long fprs;
810 	int ret;
811 
812 	if (target == current)
813 		save_and_clear_fpu();
814 
815 	fprs = task_thread_info(target)->fpsaved[0];
816 
817 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
818 				 fpregs,
819 				 0, 32 * sizeof(u32));
820 	if (!ret)
821 		user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
822 					  32 * sizeof(u32),
823 					  33 * sizeof(u32));
824 	if (!ret && count > 0) {
825 		compat_ulong_t fsr;
826 		unsigned long val;
827 
828 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
829 					 &fsr,
830 					 33 * sizeof(u32),
831 					 34 * sizeof(u32));
832 		if (!ret) {
833 			val = task_thread_info(target)->xfsr[0];
834 			val &= 0xffffffff00000000UL;
835 			val |= fsr;
836 			task_thread_info(target)->xfsr[0] = val;
837 		}
838 	}
839 
840 	fprs |= (FPRS_FEF | FPRS_DL);
841 	task_thread_info(target)->fpsaved[0] = fprs;
842 
843 	if (!ret)
844 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
845 						34 * sizeof(u32), -1);
846 	return ret;
847 }
848 
849 static const struct user_regset sparc32_regsets[] = {
850 	/* Format is:
851 	 * 	G0 --> G7
852 	 *	O0 --> O7
853 	 *	L0 --> L7
854 	 *	I0 --> I7
855 	 *	PSR, PC, nPC, Y, WIM, TBR
856 	 */
857 	[REGSET_GENERAL] = {
858 		.core_note_type = NT_PRSTATUS,
859 		.n = 38,
860 		.size = sizeof(u32), .align = sizeof(u32),
861 		.get = genregs32_get, .set = genregs32_set
862 	},
863 	/* Format is:
864 	 *	F0 --> F31
865 	 *	empty 32-bit word
866 	 *	FSR (32--bit word)
867 	 *	FPU QUEUE COUNT (8-bit char)
868 	 *	FPU QUEUE ENTRYSIZE (8-bit char)
869 	 *	FPU ENABLED (8-bit char)
870 	 *	empty 8-bit char
871 	 *	FPU QUEUE (64 32-bit ints)
872 	 */
873 	[REGSET_FP] = {
874 		.core_note_type = NT_PRFPREG,
875 		.n = 99,
876 		.size = sizeof(u32), .align = sizeof(u32),
877 		.get = fpregs32_get, .set = fpregs32_set
878 	},
879 };
880 
881 static const struct user_regset_view user_sparc32_view = {
882 	.name = "sparc", .e_machine = EM_SPARC,
883 	.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
884 };
885 #endif /* CONFIG_COMPAT */
886 
887 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
888 {
889 #ifdef CONFIG_COMPAT
890 	if (test_tsk_thread_flag(task, TIF_32BIT))
891 		return &user_sparc32_view;
892 #endif
893 	return &user_sparc64_view;
894 }
895 
896 #ifdef CONFIG_COMPAT
897 struct compat_fps {
898 	unsigned int regs[32];
899 	unsigned int fsr;
900 	unsigned int flags;
901 	unsigned int extra;
902 	unsigned int fpqd;
903 	struct compat_fq {
904 		unsigned int insnaddr;
905 		unsigned int insn;
906 	} fpq[16];
907 };
908 
909 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
910 			compat_ulong_t caddr, compat_ulong_t cdata)
911 {
912 	const struct user_regset_view *view = task_user_regset_view(current);
913 	compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
914 	struct pt_regs32 __user *pregs;
915 	struct compat_fps __user *fps;
916 	unsigned long addr2 = caddr2;
917 	unsigned long addr = caddr;
918 	unsigned long data = cdata;
919 	int ret;
920 
921 	pregs = (struct pt_regs32 __user *) addr;
922 	fps = (struct compat_fps __user *) addr;
923 
924 	switch (request) {
925 	case PTRACE_PEEKUSR:
926 		ret = (addr != 0) ? -EIO : 0;
927 		break;
928 
929 	case PTRACE_GETREGS:
930 		ret = copy_regset_to_user(child, view, REGSET_GENERAL,
931 					  32 * sizeof(u32),
932 					  4 * sizeof(u32),
933 					  &pregs->psr);
934 		if (!ret)
935 			ret = copy_regset_to_user(child, view, REGSET_GENERAL,
936 						  1 * sizeof(u32),
937 						  15 * sizeof(u32),
938 						  &pregs->u_regs[0]);
939 		break;
940 
941 	case PTRACE_SETREGS:
942 		ret = copy_regset_from_user(child, view, REGSET_GENERAL,
943 					    32 * sizeof(u32),
944 					    4 * sizeof(u32),
945 					    &pregs->psr);
946 		if (!ret)
947 			ret = copy_regset_from_user(child, view, REGSET_GENERAL,
948 						    1 * sizeof(u32),
949 						    15 * sizeof(u32),
950 						    &pregs->u_regs[0]);
951 		break;
952 
953 	case PTRACE_GETFPREGS:
954 		ret = copy_regset_to_user(child, view, REGSET_FP,
955 					  0 * sizeof(u32),
956 					  32 * sizeof(u32),
957 					  &fps->regs[0]);
958 		if (!ret)
959 			ret = copy_regset_to_user(child, view, REGSET_FP,
960 						  33 * sizeof(u32),
961 						  1 * sizeof(u32),
962 						  &fps->fsr);
963 		if (!ret) {
964 			if (__put_user(0, &fps->flags) ||
965 			    __put_user(0, &fps->extra) ||
966 			    __put_user(0, &fps->fpqd) ||
967 			    clear_user(&fps->fpq[0], 32 * sizeof(unsigned int)))
968 				ret = -EFAULT;
969 		}
970 		break;
971 
972 	case PTRACE_SETFPREGS:
973 		ret = copy_regset_from_user(child, view, REGSET_FP,
974 					    0 * sizeof(u32),
975 					    32 * sizeof(u32),
976 					    &fps->regs[0]);
977 		if (!ret)
978 			ret = copy_regset_from_user(child, view, REGSET_FP,
979 						    33 * sizeof(u32),
980 						    1 * sizeof(u32),
981 						    &fps->fsr);
982 		break;
983 
984 	case PTRACE_READTEXT:
985 	case PTRACE_READDATA:
986 		ret = ptrace_readdata(child, addr,
987 				      (char __user *)addr2, data);
988 		if (ret == data)
989 			ret = 0;
990 		else if (ret >= 0)
991 			ret = -EIO;
992 		break;
993 
994 	case PTRACE_WRITETEXT:
995 	case PTRACE_WRITEDATA:
996 		ret = ptrace_writedata(child, (char __user *) addr2,
997 				       addr, data);
998 		if (ret == data)
999 			ret = 0;
1000 		else if (ret >= 0)
1001 			ret = -EIO;
1002 		break;
1003 
1004 	default:
1005 		if (request == PTRACE_SPARC_DETACH)
1006 			request = PTRACE_DETACH;
1007 		ret = compat_ptrace_request(child, request, addr, data);
1008 		break;
1009 	}
1010 
1011 	return ret;
1012 }
1013 #endif /* CONFIG_COMPAT */
1014 
1015 struct fps {
1016 	unsigned int regs[64];
1017 	unsigned long fsr;
1018 };
1019 
1020 long arch_ptrace(struct task_struct *child, long request,
1021 		 unsigned long addr, unsigned long data)
1022 {
1023 	const struct user_regset_view *view = task_user_regset_view(current);
1024 	unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
1025 	struct pt_regs __user *pregs;
1026 	struct fps __user *fps;
1027 	void __user *addr2p;
1028 	int ret;
1029 
1030 	pregs = (struct pt_regs __user *) addr;
1031 	fps = (struct fps __user *) addr;
1032 	addr2p = (void __user *) addr2;
1033 
1034 	switch (request) {
1035 	case PTRACE_PEEKUSR:
1036 		ret = (addr != 0) ? -EIO : 0;
1037 		break;
1038 
1039 	case PTRACE_GETREGS64:
1040 		ret = copy_regset_to_user(child, view, REGSET_GENERAL,
1041 					  1 * sizeof(u64),
1042 					  15 * sizeof(u64),
1043 					  &pregs->u_regs[0]);
1044 		if (!ret) {
1045 			/* XXX doesn't handle 'y' register correctly XXX */
1046 			ret = copy_regset_to_user(child, view, REGSET_GENERAL,
1047 						  32 * sizeof(u64),
1048 						  4 * sizeof(u64),
1049 						  &pregs->tstate);
1050 		}
1051 		break;
1052 
1053 	case PTRACE_SETREGS64:
1054 		ret = copy_regset_from_user(child, view, REGSET_GENERAL,
1055 					    1 * sizeof(u64),
1056 					    15 * sizeof(u64),
1057 					    &pregs->u_regs[0]);
1058 		if (!ret) {
1059 			/* XXX doesn't handle 'y' register correctly XXX */
1060 			ret = copy_regset_from_user(child, view, REGSET_GENERAL,
1061 						    32 * sizeof(u64),
1062 						    4 * sizeof(u64),
1063 						    &pregs->tstate);
1064 		}
1065 		break;
1066 
1067 	case PTRACE_GETFPREGS64:
1068 		ret = copy_regset_to_user(child, view, REGSET_FP,
1069 					  0 * sizeof(u64),
1070 					  33 * sizeof(u64),
1071 					  fps);
1072 		break;
1073 
1074 	case PTRACE_SETFPREGS64:
1075 		ret = copy_regset_from_user(child, view, REGSET_FP,
1076 					  0 * sizeof(u64),
1077 					  33 * sizeof(u64),
1078 					  fps);
1079 		break;
1080 
1081 	case PTRACE_READTEXT:
1082 	case PTRACE_READDATA:
1083 		ret = ptrace_readdata(child, addr, addr2p, data);
1084 		if (ret == data)
1085 			ret = 0;
1086 		else if (ret >= 0)
1087 			ret = -EIO;
1088 		break;
1089 
1090 	case PTRACE_WRITETEXT:
1091 	case PTRACE_WRITEDATA:
1092 		ret = ptrace_writedata(child, addr2p, addr, data);
1093 		if (ret == data)
1094 			ret = 0;
1095 		else if (ret >= 0)
1096 			ret = -EIO;
1097 		break;
1098 
1099 	default:
1100 		if (request == PTRACE_SPARC_DETACH)
1101 			request = PTRACE_DETACH;
1102 		ret = ptrace_request(child, request, addr, data);
1103 		break;
1104 	}
1105 
1106 	return ret;
1107 }
1108 
1109 asmlinkage int syscall_trace_enter(struct pt_regs *regs)
1110 {
1111 	int ret = 0;
1112 
1113 	/* do the secure computing check first */
1114 	secure_computing_strict(regs->u_regs[UREG_G1]);
1115 
1116 	if (test_thread_flag(TIF_NOHZ))
1117 		user_exit();
1118 
1119 	if (test_thread_flag(TIF_SYSCALL_TRACE))
1120 		ret = tracehook_report_syscall_entry(regs);
1121 
1122 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1123 		trace_sys_enter(regs, regs->u_regs[UREG_G1]);
1124 
1125 	audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0],
1126 			    regs->u_regs[UREG_I1], regs->u_regs[UREG_I2],
1127 			    regs->u_regs[UREG_I3]);
1128 
1129 	return ret;
1130 }
1131 
1132 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
1133 {
1134 	if (test_thread_flag(TIF_NOHZ))
1135 		user_exit();
1136 
1137 	audit_syscall_exit(regs);
1138 
1139 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1140 		trace_sys_exit(regs, regs->u_regs[UREG_I0]);
1141 
1142 	if (test_thread_flag(TIF_SYSCALL_TRACE))
1143 		tracehook_report_syscall_exit(regs, 0);
1144 
1145 	if (test_thread_flag(TIF_NOHZ))
1146 		user_enter();
1147 }
1148 
1149 /**
1150  * regs_query_register_offset() - query register offset from its name
1151  * @name:	the name of a register
1152  *
1153  * regs_query_register_offset() returns the offset of a register in struct
1154  * pt_regs from its name. If the name is invalid, this returns -EINVAL;
1155  */
1156 int regs_query_register_offset(const char *name)
1157 {
1158 	const struct pt_regs_offset *roff;
1159 
1160 	for (roff = regoffset_table; roff->name != NULL; roff++)
1161 		if (!strcmp(roff->name, name))
1162 			return roff->offset;
1163 	return -EINVAL;
1164 }
1165 
1166 /**
1167  * regs_within_kernel_stack() - check the address in the stack
1168  * @regs:	pt_regs which contains kernel stack pointer.
1169  * @addr:	address which is checked.
1170  *
1171  * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
1172  * If @addr is within the kernel stack, it returns true. If not, returns false.
1173  */
1174 static inline int regs_within_kernel_stack(struct pt_regs *regs,
1175 					   unsigned long addr)
1176 {
1177 	unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
1178 	return ((addr & ~(THREAD_SIZE - 1))  ==
1179 		(ksp & ~(THREAD_SIZE - 1)));
1180 }
1181 
1182 /**
1183  * regs_get_kernel_stack_nth() - get Nth entry of the stack
1184  * @regs:	pt_regs which contains kernel stack pointer.
1185  * @n:		stack entry number.
1186  *
1187  * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1188  * is specified by @regs. If the @n th entry is NOT in the kernel stack,
1189  * this returns 0.
1190  */
1191 unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
1192 {
1193 	unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
1194 	unsigned long *addr = (unsigned long *)ksp;
1195 	addr += n;
1196 	if (regs_within_kernel_stack(regs, (unsigned long)addr))
1197 		return *addr;
1198 	else
1199 		return 0;
1200 }
1201