]> err.no Git - linux-2.6/blob - arch/powerpc/kernel/ptrace.c
[POWERPC] Use user_regset accessors for SPE regs
[linux-2.6] / arch / powerpc / kernel / ptrace.c
1 /*
2  *  PowerPC version
3  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4  *
5  *  Derived from "arch/m68k/kernel/ptrace.c"
6  *  Copyright (C) 1994 by Hamish Macdonald
7  *  Taken from linux/kernel/ptrace.c and modified for M680x0.
8  *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
9  *
10  * Modified by Cort Dougan (cort@hq.fsmlabs.com)
11  * and Paul Mackerras (paulus@samba.org).
12  *
13  * This file is subject to the terms and conditions of the GNU General
14  * Public License.  See the file README.legal in the main directory of
15  * this archive for more details.
16  */
17
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/mm.h>
21 #include <linux/smp.h>
22 #include <linux/errno.h>
23 #include <linux/ptrace.h>
24 #include <linux/regset.h>
25 #include <linux/elf.h>
26 #include <linux/user.h>
27 #include <linux/security.h>
28 #include <linux/signal.h>
29 #include <linux/seccomp.h>
30 #include <linux/audit.h>
31 #ifdef CONFIG_PPC32
32 #include <linux/module.h>
33 #endif
34
35 #include <asm/uaccess.h>
36 #include <asm/page.h>
37 #include <asm/pgtable.h>
38 #include <asm/system.h>
39
40 /*
41  * does not yet catch signals sent when the child dies.
42  * in exit.c or in signal.c.
43  */
44
45 /*
46  * Set of msr bits that gdb can change on behalf of a process.
47  */
48 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
49 #define MSR_DEBUGCHANGE 0
50 #else
51 #define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
52 #endif
53
54 /*
55  * Max register writeable via put_reg
56  */
57 #ifdef CONFIG_PPC32
58 #define PT_MAX_PUT_REG  PT_MQ
59 #else
60 #define PT_MAX_PUT_REG  PT_CCR
61 #endif
62
63 /*
64  * Get contents of register REGNO in task TASK.
65  */
66 unsigned long ptrace_get_reg(struct task_struct *task, int regno)
67 {
68         unsigned long tmp = 0;
69
70         if (task->thread.regs == NULL)
71                 return -EIO;
72
73         if (regno == PT_MSR) {
74                 tmp = ((unsigned long *)task->thread.regs)[PT_MSR];
75                 return tmp | task->thread.fpexc_mode;
76         }
77
78         if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
79                 return ((unsigned long *)task->thread.regs)[regno];
80
81         return -EIO;
82 }
83
84 /*
85  * Write contents of register REGNO in task TASK.
86  */
87 int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
88 {
89         if (task->thread.regs == NULL)
90                 return -EIO;
91
92         if (regno <= PT_MAX_PUT_REG || regno == PT_TRAP) {
93                 if (regno == PT_MSR)
94                         data = (data & MSR_DEBUGCHANGE)
95                                 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
96                 /* We prevent mucking around with the reserved area of trap
97                  * which are used internally by the kernel
98                  */
99                 if (regno == PT_TRAP)
100                         data &= 0xfff0;
101                 ((unsigned long *)task->thread.regs)[regno] = data;
102                 return 0;
103         }
104         return -EIO;
105 }
106
107
108 static int fpr_get(struct task_struct *target, const struct user_regset *regset,
109                    unsigned int pos, unsigned int count,
110                    void *kbuf, void __user *ubuf)
111 {
112         flush_fp_to_thread(target);
113
114         BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
115                      offsetof(struct thread_struct, fpr[32]));
116
117         return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
118                                    &target->thread.fpr, 0, -1);
119 }
120
121 static int fpr_set(struct task_struct *target, const struct user_regset *regset,
122                    unsigned int pos, unsigned int count,
123                    const void *kbuf, const void __user *ubuf)
124 {
125         flush_fp_to_thread(target);
126
127         BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
128                      offsetof(struct thread_struct, fpr[32]));
129
130         return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
131                                   &target->thread.fpr, 0, -1);
132 }
133
134 static int get_fpregs(void __user *data, struct task_struct *task,
135                       int has_fpscr)
136 {
137         unsigned int count = has_fpscr ? 33 : 32;
138         if (!access_ok(VERIFY_WRITE, data, count * sizeof(double)))
139                 return -EFAULT;
140         return fpr_get(task, NULL, 0, count * sizeof(double), NULL, data);
141 }
142
143 static int set_fpregs(void __user *data, struct task_struct *task,
144                       int has_fpscr)
145 {
146         unsigned int count = has_fpscr ? 33 : 32;
147         if (!access_ok(VERIFY_READ, data, count * sizeof(double)))
148                 return -EFAULT;
149         return fpr_set(task, NULL, 0, count * sizeof(double), NULL, data);
150 }
151
152
153 #ifdef CONFIG_ALTIVEC
154 /*
155  * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
156  * The transfer totals 34 quadword.  Quadwords 0-31 contain the
157  * corresponding vector registers.  Quadword 32 contains the vscr as the
158  * last word (offset 12) within that quadword.  Quadword 33 contains the
159  * vrsave as the first word (offset 0) within the quadword.
160  *
161  * This definition of the VMX state is compatible with the current PPC32
162  * ptrace interface.  This allows signal handling and ptrace to use the
163  * same structures.  This also simplifies the implementation of a bi-arch
164  * (combined (32- and 64-bit) gdb.
165  */
166
167 static int vr_active(struct task_struct *target,
168                      const struct user_regset *regset)
169 {
170         flush_altivec_to_thread(target);
171         return target->thread.used_vr ? regset->n : 0;
172 }
173
174 static int vr_get(struct task_struct *target, const struct user_regset *regset,
175                   unsigned int pos, unsigned int count,
176                   void *kbuf, void __user *ubuf)
177 {
178         int ret;
179
180         flush_altivec_to_thread(target);
181
182         BUILD_BUG_ON(offsetof(struct thread_struct, vscr) !=
183                      offsetof(struct thread_struct, vr[32]));
184
185         ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
186                                   &target->thread.vr, 0,
187                                   33 * sizeof(vector128));
188         if (!ret) {
189                 /*
190                  * Copy out only the low-order word of vrsave.
191                  */
192                 union {
193                         elf_vrreg_t reg;
194                         u32 word;
195                 } vrsave;
196                 memset(&vrsave, 0, sizeof(vrsave));
197                 vrsave.word = target->thread.vrsave;
198                 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
199                                           33 * sizeof(vector128), -1);
200         }
201
202         return ret;
203 }
204
205 static int vr_set(struct task_struct *target, const struct user_regset *regset,
206                   unsigned int pos, unsigned int count,
207                   const void *kbuf, const void __user *ubuf)
208 {
209         int ret;
210
211         flush_altivec_to_thread(target);
212
213         BUILD_BUG_ON(offsetof(struct thread_struct, vscr) !=
214                      offsetof(struct thread_struct, vr[32]));
215
216         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
217                                  &target->thread.vr, 0, 33 * sizeof(vector128));
218         if (!ret && count > 0) {
219                 /*
220                  * We use only the first word of vrsave.
221                  */
222                 union {
223                         elf_vrreg_t reg;
224                         u32 word;
225                 } vrsave;
226                 memset(&vrsave, 0, sizeof(vrsave));
227                 vrsave.word = target->thread.vrsave;
228                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
229                                          33 * sizeof(vector128), -1);
230                 if (!ret)
231                         target->thread.vrsave = vrsave.word;
232         }
233
234         return ret;
235 }
236
237 /*
238  * Get contents of AltiVec register state in task TASK
239  */
240 static int get_vrregs(unsigned long __user *data, struct task_struct *task)
241 {
242         if (!access_ok(VERIFY_WRITE, data,
243                        33 * sizeof(vector128) + sizeof(u32)))
244                 return -EFAULT;
245
246         return vr_get(task, NULL, 0, 33 * sizeof(vector128) + sizeof(u32),
247                       NULL, data);
248 }
249
250 /*
251  * Write contents of AltiVec register state into task TASK.
252  */
253 static int set_vrregs(struct task_struct *task, unsigned long __user *data)
254 {
255         if (!access_ok(VERIFY_READ, data, 33 * sizeof(vector128) + sizeof(u32)))
256                 return -EFAULT;
257
258         return vr_set(task, NULL, 0, 33 * sizeof(vector128) + sizeof(u32),
259                       NULL, data);
260 }
261 #endif /* CONFIG_ALTIVEC */
262
263 #ifdef CONFIG_SPE
264
265 /*
266  * For get_evrregs/set_evrregs functions 'data' has the following layout:
267  *
268  * struct {
269  *   u32 evr[32];
270  *   u64 acc;
271  *   u32 spefscr;
272  * }
273  */
274
275 static int evr_active(struct task_struct *target,
276                       const struct user_regset *regset)
277 {
278         flush_spe_to_thread(target);
279         return target->thread.used_spe ? regset->n : 0;
280 }
281
282 static int evr_get(struct task_struct *target, const struct user_regset *regset,
283                    unsigned int pos, unsigned int count,
284                    void *kbuf, void __user *ubuf)
285 {
286         int ret;
287
288         flush_spe_to_thread(target);
289
290         ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
291                                   &target->thread.evr,
292                                   0, sizeof(target->thread.evr));
293
294         BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) !=
295                      offsetof(struct thread_struct, spefscr));
296
297         if (!ret)
298                 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
299                                           &target->thread.acc,
300                                           sizeof(target->thread.evr), -1);
301
302         return ret;
303 }
304
305 static int evr_set(struct task_struct *target, const struct user_regset *regset,
306                    unsigned int pos, unsigned int count,
307                    const void *kbuf, const void __user *ubuf)
308 {
309         int ret;
310
311         flush_spe_to_thread(target);
312
313         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
314                                  &target->thread.evr,
315                                  0, sizeof(target->thread.evr));
316
317         BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) !=
318                      offsetof(struct thread_struct, spefscr));
319
320         if (!ret)
321                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
322                                          &target->thread.acc,
323                                          sizeof(target->thread.evr), -1);
324
325         return ret;
326 }
327
328 /*
329  * Get contents of SPE register state in task TASK.
330  */
331 static int get_evrregs(unsigned long __user *data, struct task_struct *task)
332 {
333         if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(u32)))
334                 return -EFAULT;
335
336         return evr_get(task, NULL, 0, 35 * sizeof(u32), NULL, data);
337 }
338
339 /*
340  * Write contents of SPE register state into task TASK.
341  */
342 static int set_evrregs(struct task_struct *task, unsigned long *data)
343 {
344         if (!access_ok(VERIFY_READ, data, 35 * sizeof(u32)))
345                 return -EFAULT;
346
347         return evr_set(task, NULL, 0, 35 * sizeof(u32), NULL, data);
348 }
349 #endif /* CONFIG_SPE */
350
351
352 void user_enable_single_step(struct task_struct *task)
353 {
354         struct pt_regs *regs = task->thread.regs;
355
356         if (regs != NULL) {
357 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
358                 task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
359                 regs->msr |= MSR_DE;
360 #else
361                 regs->msr |= MSR_SE;
362 #endif
363         }
364         set_tsk_thread_flag(task, TIF_SINGLESTEP);
365 }
366
367 void user_disable_single_step(struct task_struct *task)
368 {
369         struct pt_regs *regs = task->thread.regs;
370
371         if (regs != NULL) {
372 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
373                 task->thread.dbcr0 = 0;
374                 regs->msr &= ~MSR_DE;
375 #else
376                 regs->msr &= ~MSR_SE;
377 #endif
378         }
379         clear_tsk_thread_flag(task, TIF_SINGLESTEP);
380 }
381
382 static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
383                                unsigned long data)
384 {
385         /* We only support one DABR and no IABRS at the moment */
386         if (addr > 0)
387                 return -EINVAL;
388
389         /* The bottom 3 bits are flags */
390         if ((data & ~0x7UL) >= TASK_SIZE)
391                 return -EIO;
392
393         /* Ensure translation is on */
394         if (data && !(data & DABR_TRANSLATION))
395                 return -EIO;
396
397         task->thread.dabr = data;
398         return 0;
399 }
400
401 /*
402  * Called by kernel/ptrace.c when detaching..
403  *
404  * Make sure single step bits etc are not set.
405  */
406 void ptrace_disable(struct task_struct *child)
407 {
408         /* make sure the single step bit is not set. */
409         user_disable_single_step(child);
410 }
411
412 /*
413  * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
414  * we mark them as obsolete now, they will be removed in a future version
415  */
416 static long arch_ptrace_old(struct task_struct *child, long request, long addr,
417                             long data)
418 {
419         int ret = -EPERM;
420
421         switch(request) {
422         case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
423                 int i;
424                 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
425                 unsigned long __user *tmp = (unsigned long __user *)addr;
426
427                 CHECK_FULL_REGS(child->thread.regs);
428                 for (i = 0; i < 32; i++) {
429                         ret = put_user(*reg, tmp);
430                         if (ret)
431                                 break;
432                         reg++;
433                         tmp++;
434                 }
435                 break;
436         }
437
438         case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
439                 int i;
440                 unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
441                 unsigned long __user *tmp = (unsigned long __user *)addr;
442
443                 CHECK_FULL_REGS(child->thread.regs);
444                 for (i = 0; i < 32; i++) {
445                         ret = get_user(*reg, tmp);
446                         if (ret)
447                                 break;
448                         reg++;
449                         tmp++;
450                 }
451                 break;
452         }
453
454         case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
455                 flush_fp_to_thread(child);
456                 ret = get_fpregs((void __user *)addr, child, 0);
457                 break;
458         }
459
460         case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
461                 flush_fp_to_thread(child);
462                 ret = set_fpregs((void __user *)addr, child, 0);
463                 break;
464         }
465
466         }
467         return ret;
468 }
469
470 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
471 {
472         int ret = -EPERM;
473
474         switch (request) {
475         /* when I and D space are separate, these will need to be fixed. */
476         case PTRACE_PEEKTEXT: /* read word at location addr. */
477         case PTRACE_PEEKDATA:
478                 ret = generic_ptrace_peekdata(child, addr, data);
479                 break;
480
481         /* read the word at location addr in the USER area. */
482         case PTRACE_PEEKUSR: {
483                 unsigned long index, tmp;
484
485                 ret = -EIO;
486                 /* convert to index and check */
487 #ifdef CONFIG_PPC32
488                 index = (unsigned long) addr >> 2;
489                 if ((addr & 3) || (index > PT_FPSCR)
490                     || (child->thread.regs == NULL))
491 #else
492                 index = (unsigned long) addr >> 3;
493                 if ((addr & 7) || (index > PT_FPSCR))
494 #endif
495                         break;
496
497                 CHECK_FULL_REGS(child->thread.regs);
498                 if (index < PT_FPR0) {
499                         tmp = ptrace_get_reg(child, (int) index);
500                 } else {
501                         flush_fp_to_thread(child);
502                         tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
503                 }
504                 ret = put_user(tmp,(unsigned long __user *) data);
505                 break;
506         }
507
508         /* If I and D space are separate, this will have to be fixed. */
509         case PTRACE_POKETEXT: /* write the word at location addr. */
510         case PTRACE_POKEDATA:
511                 ret = generic_ptrace_pokedata(child, addr, data);
512                 break;
513
514         /* write the word at location addr in the USER area */
515         case PTRACE_POKEUSR: {
516                 unsigned long index;
517
518                 ret = -EIO;
519                 /* convert to index and check */
520 #ifdef CONFIG_PPC32
521                 index = (unsigned long) addr >> 2;
522                 if ((addr & 3) || (index > PT_FPSCR)
523                     || (child->thread.regs == NULL))
524 #else
525                 index = (unsigned long) addr >> 3;
526                 if ((addr & 7) || (index > PT_FPSCR))
527 #endif
528                         break;
529
530                 CHECK_FULL_REGS(child->thread.regs);
531                 if (index < PT_FPR0) {
532                         ret = ptrace_put_reg(child, index, data);
533                 } else {
534                         flush_fp_to_thread(child);
535                         ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
536                         ret = 0;
537                 }
538                 break;
539         }
540
541         case PTRACE_GET_DEBUGREG: {
542                 ret = -EINVAL;
543                 /* We only support one DABR and no IABRS at the moment */
544                 if (addr > 0)
545                         break;
546                 ret = put_user(child->thread.dabr,
547                                (unsigned long __user *)data);
548                 break;
549         }
550
551         case PTRACE_SET_DEBUGREG:
552                 ret = ptrace_set_debugreg(child, addr, data);
553                 break;
554
555 #ifdef CONFIG_PPC64
556         case PTRACE_GETREGS64:
557 #endif
558         case PTRACE_GETREGS: { /* Get all pt_regs from the child. */
559                 int ui;
560                 if (!access_ok(VERIFY_WRITE, (void __user *)data,
561                                sizeof(struct pt_regs))) {
562                         ret = -EIO;
563                         break;
564                 }
565                 CHECK_FULL_REGS(child->thread.regs);
566                 ret = 0;
567                 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
568                         ret |= __put_user(ptrace_get_reg(child, ui),
569                                           (unsigned long __user *) data);
570                         data += sizeof(long);
571                 }
572                 break;
573         }
574
575 #ifdef CONFIG_PPC64
576         case PTRACE_SETREGS64:
577 #endif
578         case PTRACE_SETREGS: { /* Set all gp regs in the child. */
579                 unsigned long tmp;
580                 int ui;
581                 if (!access_ok(VERIFY_READ, (void __user *)data,
582                                sizeof(struct pt_regs))) {
583                         ret = -EIO;
584                         break;
585                 }
586                 CHECK_FULL_REGS(child->thread.regs);
587                 ret = 0;
588                 for (ui = 0; ui < PT_REGS_COUNT; ui ++) {
589                         ret = __get_user(tmp, (unsigned long __user *) data);
590                         if (ret)
591                                 break;
592                         ptrace_put_reg(child, ui, tmp);
593                         data += sizeof(long);
594                 }
595                 break;
596         }
597
598         case PTRACE_GETFPREGS: { /* Get the child FPU state (FPR0...31 + FPSCR) */
599                 flush_fp_to_thread(child);
600                 ret = get_fpregs((void __user *)data, child, 1);
601                 break;
602         }
603
604         case PTRACE_SETFPREGS: { /* Set the child FPU state (FPR0...31 + FPSCR) */
605                 flush_fp_to_thread(child);
606                 ret = set_fpregs((void __user *)data, child, 1);
607                 break;
608         }
609
610 #ifdef CONFIG_ALTIVEC
611         case PTRACE_GETVRREGS:
612                 /* Get the child altivec register state. */
613                 flush_altivec_to_thread(child);
614                 ret = get_vrregs((unsigned long __user *)data, child);
615                 break;
616
617         case PTRACE_SETVRREGS:
618                 /* Set the child altivec register state. */
619                 flush_altivec_to_thread(child);
620                 ret = set_vrregs(child, (unsigned long __user *)data);
621                 break;
622 #endif
623 #ifdef CONFIG_SPE
624         case PTRACE_GETEVRREGS:
625                 /* Get the child spe register state. */
626                 flush_spe_to_thread(child);
627                 ret = get_evrregs((unsigned long __user *)data, child);
628                 break;
629
630         case PTRACE_SETEVRREGS:
631                 /* Set the child spe register state. */
632                 /* this is to clear the MSR_SPE bit to force a reload
633                  * of register state from memory */
634                 flush_spe_to_thread(child);
635                 ret = set_evrregs(child, (unsigned long __user *)data);
636                 break;
637 #endif
638
639         /* Old reverse args ptrace callss */
640         case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */
641         case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */
642         case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */
643         case PPC_PTRACE_SETFPREGS: /* Get FPRs 0 - 31. */
644                 ret = arch_ptrace_old(child, request, addr, data);
645                 break;
646
647         default:
648                 ret = ptrace_request(child, request, addr, data);
649                 break;
650         }
651         return ret;
652 }
653
654 static void do_syscall_trace(void)
655 {
656         /* the 0x80 provides a way for the tracing parent to distinguish
657            between a syscall stop and SIGTRAP delivery */
658         ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
659                                  ? 0x80 : 0));
660
661         /*
662          * this isn't the same as continuing with a signal, but it will do
663          * for normal use.  strace only continues with a signal if the
664          * stopping signal is not SIGTRAP.  -brl
665          */
666         if (current->exit_code) {
667                 send_sig(current->exit_code, current, 1);
668                 current->exit_code = 0;
669         }
670 }
671
672 void do_syscall_trace_enter(struct pt_regs *regs)
673 {
674         secure_computing(regs->gpr[0]);
675
676         if (test_thread_flag(TIF_SYSCALL_TRACE)
677             && (current->ptrace & PT_PTRACED))
678                 do_syscall_trace();
679
680         if (unlikely(current->audit_context)) {
681 #ifdef CONFIG_PPC64
682                 if (!test_thread_flag(TIF_32BIT))
683                         audit_syscall_entry(AUDIT_ARCH_PPC64,
684                                             regs->gpr[0],
685                                             regs->gpr[3], regs->gpr[4],
686                                             regs->gpr[5], regs->gpr[6]);
687                 else
688 #endif
689                         audit_syscall_entry(AUDIT_ARCH_PPC,
690                                             regs->gpr[0],
691                                             regs->gpr[3] & 0xffffffff,
692                                             regs->gpr[4] & 0xffffffff,
693                                             regs->gpr[5] & 0xffffffff,
694                                             regs->gpr[6] & 0xffffffff);
695         }
696 }
697
698 void do_syscall_trace_leave(struct pt_regs *regs)
699 {
700         if (unlikely(current->audit_context))
701                 audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
702                                    regs->result);
703
704         if ((test_thread_flag(TIF_SYSCALL_TRACE)
705              || test_thread_flag(TIF_SINGLESTEP))
706             && (current->ptrace & PT_PTRACED))
707                 do_syscall_trace();
708 }