xref: /openbmc/linux/arch/sparc/kernel/ptrace_64.c (revision a24d22b2)
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 			 struct membuf to)
250 {
251 	const struct pt_regs *regs = task_pt_regs(target);
252 	struct reg_window window;
253 
254 	if (target == current)
255 		flushw_user();
256 
257 	membuf_write(&to, regs->u_regs, 16 * sizeof(u64));
258 	if (!to.left)
259 		return 0;
260 	if (regwindow64_get(target, regs, &window))
261 		return -EFAULT;
262 	membuf_write(&to, &window, 16 * sizeof(u64));
263 	/* TSTATE, TPC, TNPC */
264 	membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
265 	return membuf_store(&to, (u64)regs->y);
266 }
267 
268 static int genregs64_set(struct task_struct *target,
269 			 const struct user_regset *regset,
270 			 unsigned int pos, unsigned int count,
271 			 const void *kbuf, const void __user *ubuf)
272 {
273 	struct pt_regs *regs = task_pt_regs(target);
274 	int ret;
275 
276 	if (target == current)
277 		flushw_user();
278 
279 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
280 				 regs->u_regs,
281 				 0, 16 * sizeof(u64));
282 	if (!ret && count && pos < (32 * sizeof(u64))) {
283 		struct reg_window window;
284 
285 		if (regwindow64_get(target, regs, &window))
286 			return -EFAULT;
287 
288 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
289 					 &window,
290 					 16 * sizeof(u64),
291 					 32 * sizeof(u64));
292 
293 		if (!ret &&
294 		    regwindow64_set(target, regs, &window))
295 			return -EFAULT;
296 	}
297 
298 	if (!ret && count > 0) {
299 		unsigned long tstate;
300 
301 		/* TSTATE */
302 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
303 					 &tstate,
304 					 32 * sizeof(u64),
305 					 33 * sizeof(u64));
306 		if (!ret) {
307 			/* Only the condition codes and the "in syscall"
308 			 * state can be modified in the %tstate register.
309 			 */
310 			tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
311 			regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
312 			regs->tstate |= tstate;
313 		}
314 	}
315 
316 	if (!ret) {
317 		/* TPC, TNPC */
318 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
319 					 &regs->tpc,
320 					 33 * sizeof(u64),
321 					 35 * sizeof(u64));
322 	}
323 
324 	if (!ret) {
325 		unsigned long y = regs->y;
326 
327 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
328 					 &y,
329 					 35 * sizeof(u64),
330 					 36 * sizeof(u64));
331 		if (!ret)
332 			regs->y = y;
333 	}
334 
335 	if (!ret)
336 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
337 						36 * sizeof(u64), -1);
338 
339 	return ret;
340 }
341 
342 static int fpregs64_get(struct task_struct *target,
343 			const struct user_regset *regset,
344 			struct membuf to)
345 {
346 	struct thread_info *t = task_thread_info(target);
347 	unsigned long fprs;
348 
349 	if (target == current)
350 		save_and_clear_fpu();
351 
352 	fprs = t->fpsaved[0];
353 
354 	if (fprs & FPRS_DL)
355 		membuf_write(&to, t->fpregs, 16 * sizeof(u64));
356 	else
357 		membuf_zero(&to, 16 * sizeof(u64));
358 
359 	if (fprs & FPRS_DU)
360 		membuf_write(&to, t->fpregs + 16, 16 * sizeof(u64));
361 	else
362 		membuf_zero(&to, 16 * sizeof(u64));
363 	if (fprs & FPRS_FEF) {
364 		membuf_store(&to, t->xfsr[0]);
365 		membuf_store(&to, t->gsr[0]);
366 	} else {
367 		membuf_zero(&to, 2 * sizeof(u64));
368 	}
369 	return membuf_store(&to, fprs);
370 }
371 
372 static int fpregs64_set(struct task_struct *target,
373 			const struct user_regset *regset,
374 			unsigned int pos, unsigned int count,
375 			const void *kbuf, const void __user *ubuf)
376 {
377 	unsigned long *fpregs = task_thread_info(target)->fpregs;
378 	unsigned long fprs;
379 	int ret;
380 
381 	if (target == current)
382 		save_and_clear_fpu();
383 
384 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
385 				 fpregs,
386 				 0, 32 * sizeof(u64));
387 	if (!ret)
388 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
389 					 task_thread_info(target)->xfsr,
390 					 32 * sizeof(u64),
391 					 33 * sizeof(u64));
392 	if (!ret)
393 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
394 					 task_thread_info(target)->gsr,
395 					 33 * sizeof(u64),
396 					 34 * sizeof(u64));
397 
398 	fprs = task_thread_info(target)->fpsaved[0];
399 	if (!ret && count > 0) {
400 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
401 					 &fprs,
402 					 34 * sizeof(u64),
403 					 35 * sizeof(u64));
404 	}
405 
406 	fprs |= (FPRS_FEF | FPRS_DL | FPRS_DU);
407 	task_thread_info(target)->fpsaved[0] = fprs;
408 
409 	if (!ret)
410 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
411 						35 * sizeof(u64), -1);
412 	return ret;
413 }
414 
415 static const struct user_regset sparc64_regsets[] = {
416 	/* Format is:
417 	 * 	G0 --> G7
418 	 *	O0 --> O7
419 	 *	L0 --> L7
420 	 *	I0 --> I7
421 	 *	TSTATE, TPC, TNPC, Y
422 	 */
423 	[REGSET_GENERAL] = {
424 		.core_note_type = NT_PRSTATUS,
425 		.n = 36,
426 		.size = sizeof(u64), .align = sizeof(u64),
427 		.regset_get = genregs64_get, .set = genregs64_set
428 	},
429 	/* Format is:
430 	 *	F0 --> F63
431 	 *	FSR
432 	 *	GSR
433 	 *	FPRS
434 	 */
435 	[REGSET_FP] = {
436 		.core_note_type = NT_PRFPREG,
437 		.n = 35,
438 		.size = sizeof(u64), .align = sizeof(u64),
439 		.regset_get = fpregs64_get, .set = fpregs64_set
440 	},
441 };
442 
443 static int getregs64_get(struct task_struct *target,
444 			 const struct user_regset *regset,
445 			 struct membuf to)
446 {
447 	const struct pt_regs *regs = task_pt_regs(target);
448 
449 	if (target == current)
450 		flushw_user();
451 
452 	membuf_write(&to, regs->u_regs + 1, 15 * sizeof(u64));
453 	membuf_store(&to, (u64)0);
454 	membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
455 	return membuf_store(&to, (u64)regs->y);
456 }
457 
458 static int setregs64_set(struct task_struct *target,
459 			 const struct user_regset *regset,
460 			 unsigned int pos, unsigned int count,
461 			 const void *kbuf, const void __user *ubuf)
462 {
463 	struct pt_regs *regs = task_pt_regs(target);
464 	unsigned long y = regs->y;
465 	unsigned long tstate;
466 	int ret;
467 
468 	if (target == current)
469 		flushw_user();
470 
471 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
472 				 regs->u_regs + 1,
473 				 0 * sizeof(u64),
474 				 15 * sizeof(u64));
475 	if (ret)
476 		return ret;
477 	ret =user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
478 				 15 * sizeof(u64), 16 * sizeof(u64));
479 	if (ret)
480 		return ret;
481 	/* TSTATE */
482 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
483 				 &tstate,
484 				 16 * sizeof(u64),
485 				 17 * sizeof(u64));
486 	if (ret)
487 		return ret;
488 	/* Only the condition codes and the "in syscall"
489 	 * state can be modified in the %tstate register.
490 	 */
491 	tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
492 	regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
493 	regs->tstate |= tstate;
494 
495 	/* TPC, TNPC */
496 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
497 				 &regs->tpc,
498 				 17 * sizeof(u64),
499 				 19 * sizeof(u64));
500 	if (ret)
501 		return ret;
502 	/* Y */
503 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
504 				 &y,
505 				 19 * sizeof(u64),
506 				 20 * sizeof(u64));
507 	if (!ret)
508 		regs->y = y;
509 	return ret;
510 }
511 
512 static const struct user_regset ptrace64_regsets[] = {
513 	/* Format is:
514 	 *      G1 --> G7
515 	 *      O0 --> O7
516 	 *	0
517 	 *      TSTATE, TPC, TNPC, Y
518 	 */
519 	[REGSET_GENERAL] = {
520 		.n = 20, .size = sizeof(u64),
521 		.regset_get = getregs64_get, .set = setregs64_set,
522 	},
523 };
524 
525 static const struct user_regset_view ptrace64_view = {
526 	.regsets = ptrace64_regsets, .n = ARRAY_SIZE(ptrace64_regsets)
527 };
528 
529 static const struct user_regset_view user_sparc64_view = {
530 	.name = "sparc64", .e_machine = EM_SPARCV9,
531 	.regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets)
532 };
533 
534 #ifdef CONFIG_COMPAT
535 static int genregs32_get(struct task_struct *target,
536 			 const struct user_regset *regset,
537 			 struct membuf to)
538 {
539 	const struct pt_regs *regs = task_pt_regs(target);
540 	u32 uregs[16];
541 	int i;
542 
543 	if (target == current)
544 		flushw_user();
545 
546 	for (i = 0; i < 16; i++)
547 		membuf_store(&to, (u32)regs->u_regs[i]);
548 	if (!to.left)
549 		return 0;
550 	if (get_from_target(target, regs->u_regs[UREG_I6],
551 			    uregs, sizeof(uregs)))
552 		return -EFAULT;
553 	membuf_write(&to, uregs, 16 * sizeof(u32));
554 	membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
555 	membuf_store(&to, (u32)(regs->tpc));
556 	membuf_store(&to, (u32)(regs->tnpc));
557 	membuf_store(&to, (u32)(regs->y));
558 	return membuf_zero(&to, 2 * sizeof(u32));
559 }
560 
561 static int genregs32_set(struct task_struct *target,
562 			 const struct user_regset *regset,
563 			 unsigned int pos, unsigned int count,
564 			 const void *kbuf, const void __user *ubuf)
565 {
566 	struct pt_regs *regs = task_pt_regs(target);
567 	compat_ulong_t __user *reg_window;
568 	const compat_ulong_t *k = kbuf;
569 	const compat_ulong_t __user *u = ubuf;
570 	compat_ulong_t reg;
571 
572 	if (target == current)
573 		flushw_user();
574 
575 	pos /= sizeof(reg);
576 	count /= sizeof(reg);
577 
578 	if (kbuf) {
579 		for (; count > 0 && pos < 16; count--)
580 			regs->u_regs[pos++] = *k++;
581 
582 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
583 		reg_window -= 16;
584 		if (target == current) {
585 			for (; count > 0 && pos < 32; count--) {
586 				if (put_user(*k++, &reg_window[pos++]))
587 					return -EFAULT;
588 			}
589 		} else {
590 			for (; count > 0 && pos < 32; count--) {
591 				if (access_process_vm(target,
592 						      (unsigned long)
593 						      &reg_window[pos],
594 						      (void *) k,
595 						      sizeof(*k),
596 						      FOLL_FORCE | FOLL_WRITE)
597 				    != sizeof(*k))
598 					return -EFAULT;
599 				k++;
600 				pos++;
601 			}
602 		}
603 	} else {
604 		for (; count > 0 && pos < 16; count--) {
605 			if (get_user(reg, u++))
606 				return -EFAULT;
607 			regs->u_regs[pos++] = reg;
608 		}
609 
610 		reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
611 		reg_window -= 16;
612 		if (target == current) {
613 			for (; count > 0 && pos < 32; count--) {
614 				if (get_user(reg, u++) ||
615 				    put_user(reg, &reg_window[pos++]))
616 					return -EFAULT;
617 			}
618 		} else {
619 			for (; count > 0 && pos < 32; count--) {
620 				if (get_user(reg, u++))
621 					return -EFAULT;
622 				if (access_process_vm(target,
623 						      (unsigned long)
624 						      &reg_window[pos],
625 						      &reg, sizeof(reg),
626 						      FOLL_FORCE | FOLL_WRITE)
627 				    != sizeof(reg))
628 					return -EFAULT;
629 				pos++;
630 				u++;
631 			}
632 		}
633 	}
634 	while (count > 0) {
635 		unsigned long tstate;
636 
637 		if (kbuf)
638 			reg = *k++;
639 		else if (get_user(reg, u++))
640 			return -EFAULT;
641 
642 		switch (pos) {
643 		case 32: /* PSR */
644 			tstate = regs->tstate;
645 			tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
646 			tstate |= psr_to_tstate_icc(reg);
647 			if (reg & PSR_SYSCALL)
648 				tstate |= TSTATE_SYSCALL;
649 			regs->tstate = tstate;
650 			break;
651 		case 33: /* PC */
652 			regs->tpc = reg;
653 			break;
654 		case 34: /* NPC */
655 			regs->tnpc = reg;
656 			break;
657 		case 35: /* Y */
658 			regs->y = reg;
659 			break;
660 		case 36: /* WIM */
661 		case 37: /* TBR */
662 			break;
663 		default:
664 			goto finish;
665 		}
666 
667 		pos++;
668 		count--;
669 	}
670 finish:
671 	pos *= sizeof(reg);
672 	count *= sizeof(reg);
673 
674 	return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
675 					 38 * sizeof(reg), -1);
676 }
677 
678 static int fpregs32_get(struct task_struct *target,
679 			const struct user_regset *regset,
680 			struct membuf to)
681 {
682 	struct thread_info *t = task_thread_info(target);
683 	bool enabled;
684 
685 	if (target == current)
686 		save_and_clear_fpu();
687 
688 	enabled = t->fpsaved[0] & FPRS_FEF;
689 
690 	membuf_write(&to, t->fpregs, 32 * sizeof(u32));
691 	membuf_zero(&to, sizeof(u32));
692 	if (enabled)
693 		membuf_store(&to, (u32)t->xfsr[0]);
694 	else
695 		membuf_zero(&to, sizeof(u32));
696 	membuf_store(&to, (u32)((enabled << 8) | (8 << 16)));
697 	return membuf_zero(&to, 64 * sizeof(u32));
698 }
699 
700 static int fpregs32_set(struct task_struct *target,
701 			const struct user_regset *regset,
702 			unsigned int pos, unsigned int count,
703 			const void *kbuf, const void __user *ubuf)
704 {
705 	unsigned long *fpregs = task_thread_info(target)->fpregs;
706 	unsigned long fprs;
707 	int ret;
708 
709 	if (target == current)
710 		save_and_clear_fpu();
711 
712 	fprs = task_thread_info(target)->fpsaved[0];
713 
714 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
715 				 fpregs,
716 				 0, 32 * sizeof(u32));
717 	if (!ret)
718 		user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
719 					  32 * sizeof(u32),
720 					  33 * sizeof(u32));
721 	if (!ret && count > 0) {
722 		compat_ulong_t fsr;
723 		unsigned long val;
724 
725 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
726 					 &fsr,
727 					 33 * sizeof(u32),
728 					 34 * sizeof(u32));
729 		if (!ret) {
730 			val = task_thread_info(target)->xfsr[0];
731 			val &= 0xffffffff00000000UL;
732 			val |= fsr;
733 			task_thread_info(target)->xfsr[0] = val;
734 		}
735 	}
736 
737 	fprs |= (FPRS_FEF | FPRS_DL);
738 	task_thread_info(target)->fpsaved[0] = fprs;
739 
740 	if (!ret)
741 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
742 						34 * sizeof(u32), -1);
743 	return ret;
744 }
745 
746 static const struct user_regset sparc32_regsets[] = {
747 	/* Format is:
748 	 * 	G0 --> G7
749 	 *	O0 --> O7
750 	 *	L0 --> L7
751 	 *	I0 --> I7
752 	 *	PSR, PC, nPC, Y, WIM, TBR
753 	 */
754 	[REGSET_GENERAL] = {
755 		.core_note_type = NT_PRSTATUS,
756 		.n = 38,
757 		.size = sizeof(u32), .align = sizeof(u32),
758 		.regset_get = genregs32_get, .set = genregs32_set
759 	},
760 	/* Format is:
761 	 *	F0 --> F31
762 	 *	empty 32-bit word
763 	 *	FSR (32--bit word)
764 	 *	FPU QUEUE COUNT (8-bit char)
765 	 *	FPU QUEUE ENTRYSIZE (8-bit char)
766 	 *	FPU ENABLED (8-bit char)
767 	 *	empty 8-bit char
768 	 *	FPU QUEUE (64 32-bit ints)
769 	 */
770 	[REGSET_FP] = {
771 		.core_note_type = NT_PRFPREG,
772 		.n = 99,
773 		.size = sizeof(u32), .align = sizeof(u32),
774 		.regset_get = fpregs32_get, .set = fpregs32_set
775 	},
776 };
777 
778 static int getregs_get(struct task_struct *target,
779 			 const struct user_regset *regset,
780 			 struct membuf to)
781 {
782 	const struct pt_regs *regs = task_pt_regs(target);
783 	int i;
784 
785 	if (target == current)
786 		flushw_user();
787 
788 	membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
789 	membuf_store(&to, (u32)(regs->tpc));
790 	membuf_store(&to, (u32)(regs->tnpc));
791 	membuf_store(&to, (u32)(regs->y));
792 	for (i = 1; i < 16; i++)
793 		membuf_store(&to, (u32)regs->u_regs[i]);
794 	return to.left;
795 }
796 
797 static int setregs_set(struct task_struct *target,
798 			 const struct user_regset *regset,
799 			 unsigned int pos, unsigned int count,
800 			 const void *kbuf, const void __user *ubuf)
801 {
802 	struct pt_regs *regs = task_pt_regs(target);
803 	unsigned long tstate;
804 	u32 uregs[19];
805 	int i, ret;
806 
807 	if (target == current)
808 		flushw_user();
809 
810 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
811 				 uregs,
812 				 0, 19 * sizeof(u32));
813 	if (ret)
814 		return ret;
815 
816 	tstate = regs->tstate;
817 	tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
818 	tstate |= psr_to_tstate_icc(uregs[0]);
819 	if (uregs[0] & PSR_SYSCALL)
820 		tstate |= TSTATE_SYSCALL;
821 	regs->tstate = tstate;
822 	regs->tpc = uregs[1];
823 	regs->tnpc = uregs[2];
824 	regs->y = uregs[3];
825 
826 	for (i = 1; i < 15; i++)
827 		regs->u_regs[i] = uregs[3 + i];
828 	return 0;
829 }
830 
831 static int getfpregs_get(struct task_struct *target,
832 			const struct user_regset *regset,
833 			struct membuf to)
834 {
835 	struct thread_info *t = task_thread_info(target);
836 
837 	if (target == current)
838 		save_and_clear_fpu();
839 
840 	membuf_write(&to, t->fpregs, 32 * sizeof(u32));
841 	if (t->fpsaved[0] & FPRS_FEF)
842 		membuf_store(&to, (u32)t->xfsr[0]);
843 	else
844 		membuf_zero(&to, sizeof(u32));
845 	return membuf_zero(&to, 35 * sizeof(u32));
846 }
847 
848 static int setfpregs_set(struct task_struct *target,
849 			const struct user_regset *regset,
850 			unsigned int pos, unsigned int count,
851 			const void *kbuf, const void __user *ubuf)
852 {
853 	unsigned long *fpregs = task_thread_info(target)->fpregs;
854 	unsigned long fprs;
855 	int ret;
856 
857 	if (target == current)
858 		save_and_clear_fpu();
859 
860 	fprs = task_thread_info(target)->fpsaved[0];
861 
862 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
863 				 fpregs,
864 				 0, 32 * sizeof(u32));
865 	if (!ret) {
866 		compat_ulong_t fsr;
867 		unsigned long val;
868 
869 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
870 					 &fsr,
871 					 32 * sizeof(u32),
872 					 33 * sizeof(u32));
873 		if (!ret) {
874 			val = task_thread_info(target)->xfsr[0];
875 			val &= 0xffffffff00000000UL;
876 			val |= fsr;
877 			task_thread_info(target)->xfsr[0] = val;
878 		}
879 	}
880 
881 	fprs |= (FPRS_FEF | FPRS_DL);
882 	task_thread_info(target)->fpsaved[0] = fprs;
883 	return ret;
884 }
885 
886 static const struct user_regset ptrace32_regsets[] = {
887 	[REGSET_GENERAL] = {
888 		.n = 19, .size = sizeof(u32),
889 		.regset_get = getregs_get, .set = setregs_set,
890 	},
891 	[REGSET_FP] = {
892 		.n = 68, .size = sizeof(u32),
893 		.regset_get = getfpregs_get, .set = setfpregs_set,
894 	},
895 };
896 
897 static const struct user_regset_view ptrace32_view = {
898 	.regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets)
899 };
900 
901 static const struct user_regset_view user_sparc32_view = {
902 	.name = "sparc", .e_machine = EM_SPARC,
903 	.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
904 };
905 #endif /* CONFIG_COMPAT */
906 
907 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
908 {
909 #ifdef CONFIG_COMPAT
910 	if (test_tsk_thread_flag(task, TIF_32BIT))
911 		return &user_sparc32_view;
912 #endif
913 	return &user_sparc64_view;
914 }
915 
916 #ifdef CONFIG_COMPAT
917 struct compat_fps {
918 	unsigned int regs[32];
919 	unsigned int fsr;
920 	unsigned int flags;
921 	unsigned int extra;
922 	unsigned int fpqd;
923 	struct compat_fq {
924 		unsigned int insnaddr;
925 		unsigned int insn;
926 	} fpq[16];
927 };
928 
929 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
930 			compat_ulong_t caddr, compat_ulong_t cdata)
931 {
932 	compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
933 	struct pt_regs32 __user *pregs;
934 	struct compat_fps __user *fps;
935 	unsigned long addr2 = caddr2;
936 	unsigned long addr = caddr;
937 	unsigned long data = cdata;
938 	int ret;
939 
940 	pregs = (struct pt_regs32 __user *) addr;
941 	fps = (struct compat_fps __user *) addr;
942 
943 	switch (request) {
944 	case PTRACE_PEEKUSR:
945 		ret = (addr != 0) ? -EIO : 0;
946 		break;
947 
948 	case PTRACE_GETREGS:
949 		ret = copy_regset_to_user(child, &ptrace32_view,
950 					  REGSET_GENERAL, 0,
951 					  19 * sizeof(u32),
952 					  pregs);
953 		break;
954 
955 	case PTRACE_SETREGS:
956 		ret = copy_regset_from_user(child, &ptrace32_view,
957 					  REGSET_GENERAL, 0,
958 					  19 * sizeof(u32),
959 					  pregs);
960 		break;
961 
962 	case PTRACE_GETFPREGS:
963 		ret = copy_regset_to_user(child, &ptrace32_view,
964 					  REGSET_FP, 0,
965 					  68 * sizeof(u32),
966 					  fps);
967 		break;
968 
969 	case PTRACE_SETFPREGS:
970 		ret = copy_regset_from_user(child, &ptrace32_view,
971 					  REGSET_FP, 0,
972 					  33 * sizeof(u32),
973 					  fps);
974 		break;
975 
976 	case PTRACE_READTEXT:
977 	case PTRACE_READDATA:
978 		ret = ptrace_readdata(child, addr,
979 				      (char __user *)addr2, data);
980 		if (ret == data)
981 			ret = 0;
982 		else if (ret >= 0)
983 			ret = -EIO;
984 		break;
985 
986 	case PTRACE_WRITETEXT:
987 	case PTRACE_WRITEDATA:
988 		ret = ptrace_writedata(child, (char __user *) addr2,
989 				       addr, data);
990 		if (ret == data)
991 			ret = 0;
992 		else if (ret >= 0)
993 			ret = -EIO;
994 		break;
995 
996 	default:
997 		if (request == PTRACE_SPARC_DETACH)
998 			request = PTRACE_DETACH;
999 		ret = compat_ptrace_request(child, request, addr, data);
1000 		break;
1001 	}
1002 
1003 	return ret;
1004 }
1005 #endif /* CONFIG_COMPAT */
1006 
1007 struct fps {
1008 	unsigned int regs[64];
1009 	unsigned long fsr;
1010 };
1011 
1012 long arch_ptrace(struct task_struct *child, long request,
1013 		 unsigned long addr, unsigned long data)
1014 {
1015 	const struct user_regset_view *view = task_user_regset_view(current);
1016 	unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
1017 	struct pt_regs __user *pregs;
1018 	struct fps __user *fps;
1019 	void __user *addr2p;
1020 	int ret;
1021 
1022 	pregs = (struct pt_regs __user *) addr;
1023 	fps = (struct fps __user *) addr;
1024 	addr2p = (void __user *) addr2;
1025 
1026 	switch (request) {
1027 	case PTRACE_PEEKUSR:
1028 		ret = (addr != 0) ? -EIO : 0;
1029 		break;
1030 
1031 	case PTRACE_GETREGS64:
1032 		ret = copy_regset_to_user(child, &ptrace64_view,
1033 					  REGSET_GENERAL, 0,
1034 					  19 * sizeof(u64),
1035 					  pregs);
1036 		break;
1037 
1038 	case PTRACE_SETREGS64:
1039 		ret = copy_regset_from_user(child, &ptrace64_view,
1040 					  REGSET_GENERAL, 0,
1041 					  19 * sizeof(u64),
1042 					  pregs);
1043 		break;
1044 
1045 	case PTRACE_GETFPREGS64:
1046 		ret = copy_regset_to_user(child, view, REGSET_FP,
1047 					  0 * sizeof(u64),
1048 					  33 * sizeof(u64),
1049 					  fps);
1050 		break;
1051 
1052 	case PTRACE_SETFPREGS64:
1053 		ret = copy_regset_from_user(child, view, REGSET_FP,
1054 					  0 * sizeof(u64),
1055 					  33 * sizeof(u64),
1056 					  fps);
1057 		break;
1058 
1059 	case PTRACE_READTEXT:
1060 	case PTRACE_READDATA:
1061 		ret = ptrace_readdata(child, addr, addr2p, data);
1062 		if (ret == data)
1063 			ret = 0;
1064 		else if (ret >= 0)
1065 			ret = -EIO;
1066 		break;
1067 
1068 	case PTRACE_WRITETEXT:
1069 	case PTRACE_WRITEDATA:
1070 		ret = ptrace_writedata(child, addr2p, addr, data);
1071 		if (ret == data)
1072 			ret = 0;
1073 		else if (ret >= 0)
1074 			ret = -EIO;
1075 		break;
1076 
1077 	default:
1078 		if (request == PTRACE_SPARC_DETACH)
1079 			request = PTRACE_DETACH;
1080 		ret = ptrace_request(child, request, addr, data);
1081 		break;
1082 	}
1083 
1084 	return ret;
1085 }
1086 
1087 asmlinkage int syscall_trace_enter(struct pt_regs *regs)
1088 {
1089 	int ret = 0;
1090 
1091 	/* do the secure computing check first */
1092 	secure_computing_strict(regs->u_regs[UREG_G1]);
1093 
1094 	if (test_thread_flag(TIF_NOHZ))
1095 		user_exit();
1096 
1097 	if (test_thread_flag(TIF_SYSCALL_TRACE))
1098 		ret = tracehook_report_syscall_entry(regs);
1099 
1100 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1101 		trace_sys_enter(regs, regs->u_regs[UREG_G1]);
1102 
1103 	audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0],
1104 			    regs->u_regs[UREG_I1], regs->u_regs[UREG_I2],
1105 			    regs->u_regs[UREG_I3]);
1106 
1107 	return ret;
1108 }
1109 
1110 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
1111 {
1112 	if (test_thread_flag(TIF_NOHZ))
1113 		user_exit();
1114 
1115 	audit_syscall_exit(regs);
1116 
1117 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1118 		trace_sys_exit(regs, regs->u_regs[UREG_I0]);
1119 
1120 	if (test_thread_flag(TIF_SYSCALL_TRACE))
1121 		tracehook_report_syscall_exit(regs, 0);
1122 
1123 	if (test_thread_flag(TIF_NOHZ))
1124 		user_enter();
1125 }
1126 
1127 /**
1128  * regs_query_register_offset() - query register offset from its name
1129  * @name:	the name of a register
1130  *
1131  * regs_query_register_offset() returns the offset of a register in struct
1132  * pt_regs from its name. If the name is invalid, this returns -EINVAL;
1133  */
1134 int regs_query_register_offset(const char *name)
1135 {
1136 	const struct pt_regs_offset *roff;
1137 
1138 	for (roff = regoffset_table; roff->name != NULL; roff++)
1139 		if (!strcmp(roff->name, name))
1140 			return roff->offset;
1141 	return -EINVAL;
1142 }
1143 
1144 /**
1145  * regs_within_kernel_stack() - check the address in the stack
1146  * @regs:	pt_regs which contains kernel stack pointer.
1147  * @addr:	address which is checked.
1148  *
1149  * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
1150  * If @addr is within the kernel stack, it returns true. If not, returns false.
1151  */
1152 static inline int regs_within_kernel_stack(struct pt_regs *regs,
1153 					   unsigned long addr)
1154 {
1155 	unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
1156 	return ((addr & ~(THREAD_SIZE - 1))  ==
1157 		(ksp & ~(THREAD_SIZE - 1)));
1158 }
1159 
1160 /**
1161  * regs_get_kernel_stack_nth() - get Nth entry of the stack
1162  * @regs:	pt_regs which contains kernel stack pointer.
1163  * @n:		stack entry number.
1164  *
1165  * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1166  * is specified by @regs. If the @n th entry is NOT in the kernel stack,
1167  * this returns 0.
1168  */
1169 unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
1170 {
1171 	unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
1172 	unsigned long *addr = (unsigned long *)ksp;
1173 	addr += n;
1174 	if (regs_within_kernel_stack(regs, (unsigned long)addr))
1175 		return *addr;
1176 	else
1177 		return 0;
1178 }
1179