xref: /linux/arch/alpha/kernel/ptrace.c (revision 742f62b63904cdc20a364a49d2861e32464a0af7)
1 // SPDX-License-Identifier: GPL-2.0
2 /* ptrace.c */
3 /* By Ross Biro 1/23/92 */
4 /* edited by Linus Torvalds */
5 /* mangled further by Bob Manson (manson@santafe.edu) */
6 /* more mutilation by David Mosberger (davidm@azstarnet.com) */
7 
8 #include <linux/kernel.h>
9 #include <linux/sched.h>
10 #include <linux/sched/task_stack.h>
11 #include <linux/mm.h>
12 #include <linux/smp.h>
13 #include <linux/errno.h>
14 #include <linux/ptrace.h>
15 #include <linux/user.h>
16 #include <linux/security.h>
17 #include <linux/signal.h>
18 #include <linux/audit.h>
19 #include <linux/seccomp.h>
20 #include <asm/syscall.h>
21 
22 #include <linux/uaccess.h>
23 #include <asm/fpu.h>
24 
25 #include "proto.h"
26 #include <linux/uio.h>
27 #include <linux/regset.h>
28 
29 #define DEBUG	DBG_MEM
30 #undef DEBUG
31 
32 #ifndef NT_FPREGSET
33 #define NT_FPREGSET NT_PRFPREG
34 #endif
35 
36 #ifdef DEBUG
37 enum {
38 	DBG_MEM		= (1<<0),
39 	DBG_BPT		= (1<<1),
40 	DBG_MEM_ALL	= (1<<2)
41 };
42 #define DBG(fac,args)	{if ((fac) & DEBUG) printk args;}
43 #else
44 #define DBG(fac,args)
45 #endif
46 
47 #define BREAKINST	0x00000080	/* call_pal bpt */
48 
49 /*
50  * does not yet catch signals sent when the child dies.
51  * in exit.c or in signal.c.
52  */
53 
54 /*
55  * Processes always block with the following stack-layout:
56  *
57  *  +================================+ <---- task + 2*PAGE_SIZE
58  *  | PALcode saved frame (ps, pc,   | ^
59  *  | gp, a0, a1, a2)		     | |
60  *  +================================+ | struct pt_regs
61  *  |	        		     | |
62  *  | frame generated by SAVE_ALL    | |
63  *  |	        		     | v
64  *  +================================+
65  *  |	        		     | ^
66  *  | frame saved by do_switch_stack | | struct switch_stack
67  *  |	        		     | v
68  *  +================================+
69  */
70 
71 /*
72  * The following table maps a register index into the stack offset at
73  * which the register is saved.  Register indices are 0-31 for integer
74  * regs, 32-63 for fp regs, and 64 for the pc.  Notice that sp and
75  * zero have no stack-slot and need to be treated specially (see
76  * get_reg/put_reg below).
77  */
78 enum {
79 	REG_R0 = 0, REG_F0 = 32, REG_FPCR = 63, REG_PC = 64
80 };
81 
82 #define PT_REG(reg) \
83   (PAGE_SIZE*2 - sizeof(struct pt_regs) + offsetof(struct pt_regs, reg))
84 
85 #define SW_REG(reg) \
86  (PAGE_SIZE*2 - sizeof(struct pt_regs) - sizeof(struct switch_stack) \
87   + offsetof(struct switch_stack, reg))
88 
89 #define FP_REG(reg) (offsetof(struct thread_info, reg))
90 
91 static int regoff[] = {
92 	PT_REG(	   r0), PT_REG(	   r1), PT_REG(	   r2), PT_REG(	  r3),
93 	PT_REG(	   r4), PT_REG(	   r5), PT_REG(	   r6), PT_REG(	  r7),
94 	PT_REG(	   r8), SW_REG(	   r9), SW_REG(	  r10), SW_REG(	 r11),
95 	SW_REG(	  r12), SW_REG(	  r13), SW_REG(	  r14), SW_REG(	 r15),
96 	PT_REG(	  r16), PT_REG(	  r17), PT_REG(	  r18), PT_REG(	 r19),
97 	PT_REG(	  r20), PT_REG(	  r21), PT_REG(	  r22), PT_REG(	 r23),
98 	PT_REG(	  r24), PT_REG(	  r25), PT_REG(	  r26), PT_REG(	 r27),
99 	PT_REG(	  r28), PT_REG(	   gp),		   -1,		   -1,
100 	FP_REG(fp[ 0]), FP_REG(fp[ 1]), FP_REG(fp[ 2]), FP_REG(fp[ 3]),
101 	FP_REG(fp[ 4]), FP_REG(fp[ 5]), FP_REG(fp[ 6]), FP_REG(fp[ 7]),
102 	FP_REG(fp[ 8]), FP_REG(fp[ 9]), FP_REG(fp[10]), FP_REG(fp[11]),
103 	FP_REG(fp[12]), FP_REG(fp[13]), FP_REG(fp[14]), FP_REG(fp[15]),
104 	FP_REG(fp[16]), FP_REG(fp[17]), FP_REG(fp[18]), FP_REG(fp[19]),
105 	FP_REG(fp[20]), FP_REG(fp[21]), FP_REG(fp[22]), FP_REG(fp[23]),
106 	FP_REG(fp[24]), FP_REG(fp[25]), FP_REG(fp[26]), FP_REG(fp[27]),
107 	FP_REG(fp[28]), FP_REG(fp[29]), FP_REG(fp[30]), FP_REG(fp[31]),
108 	PT_REG(	   pc)
109 };
110 
111 static unsigned long zero;
112 
113 /*
114  * Get address of register REGNO in task TASK.
115  */
116 static unsigned long *
get_reg_addr(struct task_struct * task,unsigned long regno)117 get_reg_addr(struct task_struct * task, unsigned long regno)
118 {
119 	unsigned long *addr;
120 
121 	if (regno == 30) {
122 		addr = &task_thread_info(task)->pcb.usp;
123 	} else if (regno == 65) {
124 		addr = &task_thread_info(task)->pcb.unique;
125 	} else if (regno == 31 || regno > 65) {
126 		zero = 0;
127 		addr = &zero;
128 	} else {
129 		addr = task_stack_page(task) + regoff[regno];
130 	}
131 	return addr;
132 }
133 
134 /*
135  * Get contents of register REGNO in task TASK.
136  */
137 
138 static bool
valid_regno(unsigned long regno)139 valid_regno(unsigned long regno)
140 {
141 	return regno <= 65;
142 }
143 
144 static long
get_reg(struct task_struct * task,unsigned long regno)145 get_reg(struct task_struct *task, unsigned long regno)
146 {
147 	unsigned long *addr;
148 
149 	if (!valid_regno(regno))
150 		return -EIO;
151 
152 	/*
153 	 * Special hack for fpcr -- combine hardware and software bits.
154 	 */
155 	if (regno == 63) {
156 		unsigned long fpcr;
157 		unsigned long swcr;
158 
159 		addr = get_reg_addr(task, regno);
160 		if (!addr)
161 			return -EIO;
162 
163 		fpcr = *addr;
164 		swcr = task_thread_info(task)->ieee_state & IEEE_SW_MASK;
165 		swcr = swcr_update_status(swcr, fpcr);
166 
167 		return fpcr | swcr;
168 	}
169 
170 	addr = get_reg_addr(task, regno);
171 	if (!addr)
172 		return -EIO;
173 
174 	return *addr;
175 }
176 
alpha_elf_fpregs_get(struct task_struct * target,elf_fpreg_t * fpregs)177 static void alpha_elf_fpregs_get(struct task_struct *target,
178 			 elf_fpreg_t *fpregs)  /* points to ELF_NFPREG entries */
179 {
180 	memcpy(fpregs, task_thread_info(target)->fp, sizeof(elf_fpregset_t));
181 }
182 
alpha_elf_fpregs_set(struct task_struct * target,const elf_fpreg_t * fpregs,size_t nwords)183 static void alpha_elf_fpregs_set(struct task_struct *target,
184 			 const elf_fpreg_t *fpregs,
185 			 size_t nwords)
186 {
187 	size_t n = min_t(size_t, nwords, ELF_NFPREG);
188 
189 	memcpy(task_thread_info(target)->fp, fpregs, n * sizeof(elf_fpreg_t));
190 }
191 
alpha_elf_gregs_set(struct task_struct * child,const elf_greg_t * src,size_t nwords)192 static void alpha_elf_gregs_set(struct task_struct *child,
193 			const elf_greg_t *src,
194 			size_t nwords)
195 {
196 	struct pt_regs *pt = task_pt_regs(child);
197 	struct thread_info *ti = task_thread_info(child);
198 	struct switch_stack *sw = ((struct switch_stack *)pt) - 1;
199 
200 	/* GPRs r0..r8 live in pt_regs */
201 	if (nwords > 0)
202 		pt->r0 = src[0];
203 	if (nwords > 1)
204 		pt->r1 = src[1];
205 	if (nwords > 2)
206 		pt->r2 = src[2];
207 	if (nwords > 3)
208 		pt->r3 = src[3];
209 	if (nwords > 4)
210 		pt->r4 = src[4];
211 	if (nwords > 5)
212 		pt->r5 = src[5];
213 	if (nwords > 6)
214 		pt->r6 = src[6];
215 	if (nwords > 7)
216 		pt->r7 = src[7];
217 	if (nwords > 8)
218 		pt->r8 = src[8];
219 
220 	/* r9..r15 live in switch_stack */
221 	if (nwords > 9)
222 		sw->r9 = src[9];
223 	if (nwords > 10)
224 		sw->r10 = src[10];
225 	if (nwords > 11)
226 		sw->r11 = src[11];
227 	if (nwords > 12)
228 		sw->r12 = src[12];
229 	if (nwords > 13)
230 		sw->r13 = src[13];
231 	if (nwords > 14)
232 		sw->r14 = src[14];
233 	if (nwords > 15)
234 		sw->r15 = src[15];
235 
236 	/* r16..r28 live in pt_regs */
237 	if (nwords > 16)
238 		pt->r16 = src[16];
239 	if (nwords > 17)
240 		pt->r17 = src[17];
241 	if (nwords > 18)
242 		pt->r18 = src[18];
243 	if (nwords > 19)
244 		pt->r19 = src[19];
245 	if (nwords > 20)
246 		pt->r20 = src[20];
247 	if (nwords > 21)
248 		pt->r21 = src[21];
249 	if (nwords > 22)
250 		pt->r22 = src[22];
251 	if (nwords > 23)
252 		pt->r23 = src[23];
253 	if (nwords > 24)
254 		pt->r24 = src[24];
255 	if (nwords > 25)
256 		pt->r25 = src[25];
257 	if (nwords > 26)
258 		pt->r26 = src[26];
259 	if (nwords > 27)
260 		pt->r27 = src[27];
261 	if (nwords > 28)
262 		pt->r28 = src[28];
263 
264 	/* gp, usp, pc, unique */
265 	if (nwords > 29)
266 		pt->gp = src[29];
267 
268 	if (nwords > 30) {
269 		ti->pcb.usp = src[30];
270 		/*
271 		 * If someone ever does this to current (rare), keep the
272 		 * hardware usp consistent.
273 		 */
274 		if (child == current)
275 			wrusp(src[30]);
276 	}
277 
278 	if (nwords > 31)
279 		pt->pc = src[31];
280 
281 	if (nwords > 32)
282 		ti->pcb.unique = src[32];
283 
284 /*
285  * PTRACE_SETREGSET can be used at a syscall-entry stop to skip the
286  * syscall by setting the syscall number to -1.  The seccomp/ptrace
287  * selftests use this to synthesize errno returns.
288  *
289  * Alpha uses r19/a3 as the error flag, so a skipped syscall with a
290  * small positive r0 and a clear r19 must be normalized to an error
291  * return.
292  */
293 	if (pt->r1 == (unsigned long)-1 &&
294 	    pt->r19 == 0 &&
295 	    pt->r0 > 0 &&
296 	    pt->r0 < MAX_ERRNO)
297 		pt->r19 = 1;
298 }
299 
300 static int
put_reg(struct task_struct * task,unsigned long regno,unsigned long data)301 put_reg(struct task_struct *task, unsigned long regno, unsigned long data)
302 {
303 	struct pt_regs *regs = task_pt_regs(task);
304 	unsigned long *addr;
305 	unsigned long old_r0 = regs->r0;
306 
307 	if (regno == 31)
308 		return 0;
309 	if (!valid_regno(regno))
310 		return -EIO;
311 
312 	if (regno == 63) {
313 		task_thread_info(task)->ieee_state
314 		  = ((task_thread_info(task)->ieee_state & ~IEEE_SW_MASK)
315 		     | (data & IEEE_SW_MASK));
316 		data = (data & FPCR_DYN_MASK) | ieee_swcr_to_fpcr(data);
317 	}
318 
319 	addr = get_reg_addr(task, regno);
320 	if (!addr)
321 		return -EIO;
322 
323 	*addr = data;
324 
325 	/*
326 	 * Alpha historically exposes r0/v0 as the syscall number at a
327 	 * syscall-entry stop.  The generic-entry conversion keeps the
328 	 * mutable syscall number in regs->r1.
329 	 */
330 
331 	if (regno == 0 && regs->r1 == old_r0 &&
332 		(data == (unsigned long)-1 ||
333 		(regs->r19 == 0 && data < NR_syscalls))) {
334 		regs->r1 = data;
335 
336 	/*
337 	 * Keep the skip path looking like a clean entry-side syscall
338 	 * rewrite.  Do not touch r19 for ordinary syscall substitution.
339 	 */
340 		if (data == (unsigned long)-1)
341 			regs->r19 = 0;
342 	}
343 	return 0;
344 }
345 
346 static inline int
read_int(struct task_struct * task,unsigned long addr,int * data)347 read_int(struct task_struct *task, unsigned long addr, int * data)
348 {
349 	int copied = access_process_vm(task, addr, data, sizeof(int),
350 			FOLL_FORCE);
351 	return (copied == sizeof(int)) ? 0 : -EIO;
352 }
353 
354 static inline int
write_int(struct task_struct * task,unsigned long addr,int data)355 write_int(struct task_struct *task, unsigned long addr, int data)
356 {
357 	int copied = access_process_vm(task, addr, &data, sizeof(int),
358 			FOLL_FORCE | FOLL_WRITE);
359 	return (copied == sizeof(int)) ? 0 : -EIO;
360 }
361 
362 /*
363  * Set breakpoint.
364  */
365 int
ptrace_set_bpt(struct task_struct * child)366 ptrace_set_bpt(struct task_struct * child)
367 {
368 	int displ, i, res, reg_b, nsaved = 0;
369 	unsigned int insn, op_code;
370 	unsigned long pc;
371 
372 	pc  = get_reg(child, REG_PC);
373 	res = read_int(child, pc, (int *) &insn);
374 	if (res < 0)
375 		return res;
376 
377 	op_code = insn >> 26;
378 	if (op_code >= 0x30) {
379 		/*
380 		 * It's a branch: instead of trying to figure out
381 		 * whether the branch will be taken or not, we'll put
382 		 * a breakpoint at either location.  This is simpler,
383 		 * more reliable, and probably not a whole lot slower
384 		 * than the alternative approach of emulating the
385 		 * branch (emulation can be tricky for fp branches).
386 		 */
387 		displ = ((s32)(insn << 11)) >> 9;
388 		task_thread_info(child)->bpt_addr[nsaved++] = pc + 4;
389 		if (displ)		/* guard against unoptimized code */
390 			task_thread_info(child)->bpt_addr[nsaved++]
391 			  = pc + 4 + displ;
392 		DBG(DBG_BPT, ("execing branch\n"));
393 	} else if (op_code == 0x1a) {
394 		reg_b = (insn >> 16) & 0x1f;
395 		task_thread_info(child)->bpt_addr[nsaved++] = get_reg(child, reg_b);
396 		DBG(DBG_BPT, ("execing jump\n"));
397 	} else {
398 		task_thread_info(child)->bpt_addr[nsaved++] = pc + 4;
399 		DBG(DBG_BPT, ("execing normal insn\n"));
400 	}
401 
402 	/* install breakpoints: */
403 	for (i = 0; i < nsaved; ++i) {
404 		res = read_int(child, task_thread_info(child)->bpt_addr[i],
405 			       (int *) &insn);
406 		if (res < 0)
407 			return res;
408 		task_thread_info(child)->bpt_insn[i] = insn;
409 		DBG(DBG_BPT, ("    -> next_pc=%lx\n",
410 			      task_thread_info(child)->bpt_addr[i]));
411 		res = write_int(child, task_thread_info(child)->bpt_addr[i],
412 				BREAKINST);
413 		if (res < 0)
414 			return res;
415 	}
416 	task_thread_info(child)->bpt_nsaved = nsaved;
417 	return 0;
418 }
419 
420 /*
421  * Ensure no single-step breakpoint is pending.  Returns non-zero
422  * value if child was being single-stepped.
423  */
424 int
ptrace_cancel_bpt(struct task_struct * child)425 ptrace_cancel_bpt(struct task_struct * child)
426 {
427 	int i, nsaved = task_thread_info(child)->bpt_nsaved;
428 
429 	task_thread_info(child)->bpt_nsaved = 0;
430 
431 	if (nsaved > 2) {
432 		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
433 		nsaved = 2;
434 	}
435 
436 	for (i = 0; i < nsaved; ++i) {
437 		write_int(child, task_thread_info(child)->bpt_addr[i],
438 			  task_thread_info(child)->bpt_insn[i]);
439 	}
440 	return (nsaved != 0);
441 }
442 
443 /*
444  * PALcode keeps the user stack pointer in the PCB, not the trap frame.
445  * A user-mode pt_regs sits at the top of its task's stack, so the
446  * thread_info is at the base.
447  */
user_stack_pointer(struct pt_regs * regs)448 unsigned long user_stack_pointer(struct pt_regs *regs)
449 {
450 	struct thread_info *ti = (void *)((unsigned long)regs & -THREAD_SIZE);
451 
452 	return ti == current_thread_info() ? rdusp() : ti->pcb.usp;
453 }
454 
user_enable_single_step(struct task_struct * child)455 void user_enable_single_step(struct task_struct *child)
456 {
457 	/* Mark single stepping.  */
458 	task_thread_info(child)->bpt_nsaved = -1;
459 }
460 
user_disable_single_step(struct task_struct * child)461 void user_disable_single_step(struct task_struct *child)
462 {
463 	ptrace_cancel_bpt(child);
464 }
465 
466 /*
467  * Called by kernel/ptrace.c when detaching..
468  *
469  * Make sure the single step bit is not set.
470  */
ptrace_disable(struct task_struct * child)471 void ptrace_disable(struct task_struct *child)
472 {
473 	user_disable_single_step(child);
474 }
475 
arch_ptrace(struct task_struct * child,long request,unsigned long addr,unsigned long data)476 long arch_ptrace(struct task_struct *child, long request,
477 		 unsigned long addr, unsigned long data)
478 {
479 	unsigned long tmp;
480 	size_t copied;
481 	long ret;
482 
483 	switch (request) {
484 	/* When I and D space are separate, these will need to be fixed.  */
485 	case PTRACE_PEEKTEXT:
486 	case PTRACE_PEEKDATA:
487 		copied = ptrace_access_vm(child, addr, &tmp, sizeof(tmp),
488 				FOLL_FORCE);
489 		ret = -EIO;
490 		if (copied != sizeof(tmp))
491 			break;
492 		force_successful_syscall_return();
493 		ret = tmp;
494 		break;
495 
496 	case PTRACE_PEEKUSR:
497 		ret = get_reg(child, addr);
498 		if (ret == -EIO)
499 			break;
500 
501 		force_successful_syscall_return();
502 		break;
503 	/* When I and D space are separate, this will have to be fixed.  */
504 	case PTRACE_POKETEXT: /* write the word at location addr. */
505 	case PTRACE_POKEDATA:
506 		ret = generic_ptrace_pokedata(child, addr, data);
507 		break;
508 
509 	case PTRACE_POKEUSR: /* write the specified register */
510 		DBG(DBG_MEM, ("poke $%lu<-%#lx\n", addr, data));
511 		ret = put_reg(child, addr, data);
512 		break;
513 	default:
514 		ret = ptrace_request(child, request, addr, data);
515 		break;
516 	}
517 	return ret;
518 }
519 
520 /*
521  * Minimal regset support for Alpha.
522  *
523  * Alpha-specific notes:
524  *  - Do NOT use ELF_CORE_COPY_REGS(): it uses current_thread_info(),
525  *    which is wrong for non-current tasks.
526  *  - dump_elf_task() returns 1 unconditionally in this tree, while
527  *    regset_get should return 0 on success. So call dump_elf_thread()
528  *    directly and return membuf_write()'s result.
529  */
alpha_regset_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)530 static int alpha_regset_set(struct task_struct *target,
531 			    const struct user_regset *regset,
532 			    unsigned int pos, unsigned int count,
533 			    const void *kbuf,
534 			    const void __user *ubuf)
535 {
536 	elf_gregset_t gregs;
537 	unsigned int nwords;
538 
539 	if (pos + count > sizeof(gregs))
540 		return -EIO;
541 
542 	/*
543 	 * Preserve registers outside the written range.
544 	 */
545 	dump_elf_thread(gregs, task_pt_regs(target),
546 			task_thread_info(target));
547 
548 	if (user_regset_copyin(&pos, &count, &kbuf, &ubuf,
549 				gregs, 0, sizeof(gregs)))
550 		return -EFAULT;
551 
552 	nwords = sizeof(gregs) / sizeof(elf_greg_t);
553 	alpha_elf_gregs_set(target, gregs, nwords);
554 
555 	return 0;
556 }
557 
alpha_fpregset_set(struct task_struct * target,const struct user_regset * regset,unsigned int pos,unsigned int count,const void * kbuf,const void __user * ubuf)558 static int alpha_fpregset_set(struct task_struct *target,
559 			      const struct user_regset *regset,
560 			      unsigned int pos, unsigned int count,
561 			      const void *kbuf,
562 			      const void __user *ubuf)
563 {
564 	elf_fpregset_t fpregs;
565 	unsigned int nwords;
566 
567 	if (pos + count > sizeof(fpregs))
568 		return -EIO;
569 
570 	alpha_elf_fpregs_get(target, fpregs);
571 
572 	if (user_regset_copyin(&pos, &count, &kbuf, &ubuf,
573 				fpregs, 0, sizeof(fpregs)))
574 		return -EFAULT;
575 
576 	nwords = sizeof(fpregs) / sizeof(elf_fpreg_t);
577 	alpha_elf_fpregs_set(target, fpregs, nwords);
578 
579 	return 0;
580 }
581 
alpha_regset_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)582 static int alpha_regset_get(struct task_struct *target,
583 			    const struct user_regset *regset,
584 			    struct membuf to)
585 {
586 	struct pt_regs *pt = task_pt_regs(target);
587 	struct thread_info *ti = task_thread_info(target);
588 	elf_gregset_t gregs;
589 
590 	dump_elf_thread(gregs, pt, ti);
591 	return membuf_write(&to, gregs, sizeof(gregs));
592 }
593 
alpha_fpregset_get(struct task_struct * target,const struct user_regset * regset,struct membuf to)594 static int alpha_fpregset_get(struct task_struct *target,
595 			      const struct user_regset *regset,
596 			      struct membuf to)
597 {
598 	elf_fpregset_t fpregs;
599 
600 	alpha_elf_fpregs_get(target, fpregs);
601 	return membuf_write(&to, fpregs, sizeof(fpregs));
602 }
603 
604 enum alpha_regset {
605 	REGSET_GPR,
606 	REGSET_FPR,
607 };
608 
609 static const struct user_regset alpha_user_regsets[] = {
610 	[REGSET_GPR] = {
611 		.core_note_type	= NT_PRSTATUS,
612 		.n		= ELF_NGREG,
613 		.size		= sizeof(elf_greg_t),
614 		.align		= sizeof(elf_greg_t),
615 		.regset_get	= alpha_regset_get,
616 		.set		= alpha_regset_set,
617 	},
618 	[REGSET_FPR] = {
619 		.core_note_type	= NT_PRFPREG,
620 		.core_note_name	= "CORE",
621 		.n		= ELF_NFPREG,
622 		.size		= sizeof(elf_fpreg_t),
623 		.align		= sizeof(elf_fpreg_t),
624 		.regset_get	= alpha_fpregset_get,
625 		.set		= alpha_fpregset_set,
626 	},
627 };
628 
629 static const struct user_regset_view user_alpha_view = {
630 	.name		= "alpha",
631 	.e_machine	= EM_ALPHA,
632 	.ei_osabi	= ELF_OSABI,
633 	.regsets	= alpha_user_regsets,
634 	.n		= ARRAY_SIZE(alpha_user_regsets),
635 };
636 
task_user_regset_view(struct task_struct * task)637 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
638 {
639 	return &user_alpha_view;
640 }
641