vserver 2.0 rc7
[linux-2.6.git] / arch / sparc64 / kernel / ptrace.c
1 /* ptrace.c: Sparc process tracing support.
2  *
3  * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
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/mm.h>
16 #include <linux/errno.h>
17 #include <linux/ptrace.h>
18 #include <linux/user.h>
19 #include <linux/smp.h>
20 #include <linux/smp_lock.h>
21 #include <linux/security.h>
22 #include <linux/signal.h>
23
24 #include <asm/asi.h>
25 #include <asm/pgtable.h>
26 #include <asm/system.h>
27 #include <asm/uaccess.h>
28 #include <asm/psrcompat.h>
29 #include <asm/visasm.h>
30 #include <asm/spitfire.h>
31
32 /* Returning from ptrace is a bit tricky because the syscall return
33  * low level code assumes any value returned which is negative and
34  * is a valid errno will mean setting the condition codes to indicate
35  * an error return.  This doesn't work, so we have this hook.
36  */
37 static inline void pt_error_return(struct pt_regs *regs, unsigned long error)
38 {
39         regs->u_regs[UREG_I0] = error;
40         regs->tstate |= (TSTATE_ICARRY | TSTATE_XCARRY);
41         regs->tpc = regs->tnpc;
42         regs->tnpc += 4;
43 }
44
45 static inline void pt_succ_return(struct pt_regs *regs, unsigned long value)
46 {
47         regs->u_regs[UREG_I0] = value;
48         regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY);
49         regs->tpc = regs->tnpc;
50         regs->tnpc += 4;
51 }
52
53 static inline void
54 pt_succ_return_linux(struct pt_regs *regs, unsigned long value, void __user *addr)
55 {
56         if (test_thread_flag(TIF_32BIT)) {
57                 if (put_user(value, (unsigned int __user *) addr)) {
58                         pt_error_return(regs, EFAULT);
59                         return;
60                 }
61         } else {
62                 if (put_user(value, (long __user *) addr)) {
63                         pt_error_return(regs, EFAULT);
64                         return;
65                 }
66         }
67         regs->u_regs[UREG_I0] = 0;
68         regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY);
69         regs->tpc = regs->tnpc;
70         regs->tnpc += 4;
71 }
72
73 static void
74 pt_os_succ_return (struct pt_regs *regs, unsigned long val, void __user *addr)
75 {
76         if (current->personality == PER_SUNOS)
77                 pt_succ_return (regs, val);
78         else
79                 pt_succ_return_linux (regs, val, addr);
80 }
81
82 /* #define ALLOW_INIT_TRACING */
83 /* #define DEBUG_PTRACE */
84
85 #ifdef DEBUG_PTRACE
86 char *pt_rq [] = {
87         /* 0  */ "TRACEME", "PEEKTEXT", "PEEKDATA", "PEEKUSR",
88         /* 4  */ "POKETEXT", "POKEDATA", "POKEUSR", "CONT",
89         /* 8  */ "KILL", "SINGLESTEP", "SUNATTACH", "SUNDETACH",
90         /* 12 */ "GETREGS", "SETREGS", "GETFPREGS", "SETFPREGS",
91         /* 16 */ "READDATA", "WRITEDATA", "READTEXT", "WRITETEXT",
92         /* 20 */ "GETFPAREGS", "SETFPAREGS", "unknown", "unknown",
93         /* 24 */ "SYSCALL", ""
94 };
95 #endif
96
97 /*
98  * Called by kernel/ptrace.c when detaching..
99  *
100  * Make sure single step bits etc are not set.
101  */
102 void ptrace_disable(struct task_struct *child)
103 {
104         /* nothing to do */
105 }
106
107 /* To get the necessary page struct, access_process_vm() first calls
108  * get_user_pages().  This has done a flush_dcache_page() on the
109  * accessed page.  Then our caller (copy_{to,from}_user_page()) did
110  * to memcpy to read/write the data from that page.
111  *
112  * Now, the only thing we have to do is:
113  * 1) flush the D-cache if it's possible than an illegal alias
114  *    has been created
115  * 2) flush the I-cache if this is pre-cheetah and we did a write
116  */
117 void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
118                          unsigned long uaddr, void *kaddr,
119                          unsigned long len, int write)
120 {
121         BUG_ON(len > PAGE_SIZE);
122
123 #ifdef DCACHE_ALIASING_POSSIBLE
124         /* If bit 13 of the kernel address we used to access the
125          * user page is the same as the virtual address that page
126          * is mapped to in the user's address space, we can skip the
127          * D-cache flush.
128          */
129         if ((uaddr ^ kaddr) & (1UL << 13)) {
130                 unsigned long start = __pa(kaddr);
131                 unsigned long end = start + len;
132
133                 if (tlb_type == spitfire) {
134                         for (; start < end; start += 32)
135                                 spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
136                 } else {
137                         for (; start < end; start += 32)
138                                 __asm__ __volatile__(
139                                         "stxa %%g0, [%0] %1\n\t"
140                                         "membar #Sync"
141                                         : /* no outputs */
142                                         : "r" (va),
143                                         "i" (ASI_DCACHE_INVALIDATE));
144                 }
145         }
146 #endif
147         if (write && tlb_type == spitfire) {
148                 unsigned long start = (unsigned long) kaddr;
149                 unsigned long end = start + len;
150
151                 for (; start < end; start += 32)
152                         flushi(start);
153         }
154 }
155
156 asmlinkage void do_ptrace(struct pt_regs *regs)
157 {
158         int request = regs->u_regs[UREG_I0];
159         pid_t pid = regs->u_regs[UREG_I1];
160         unsigned long addr = regs->u_regs[UREG_I2];
161         unsigned long data = regs->u_regs[UREG_I3];
162         unsigned long addr2 = regs->u_regs[UREG_I4];
163         struct task_struct *child;
164         int ret;
165
166         if (test_thread_flag(TIF_32BIT)) {
167                 addr &= 0xffffffffUL;
168                 data &= 0xffffffffUL;
169                 addr2 &= 0xffffffffUL;
170         }
171         lock_kernel();
172 #ifdef DEBUG_PTRACE
173         {
174                 char *s;
175
176                 if ((request >= 0) && (request <= 24))
177                         s = pt_rq [request];
178                 else
179                         s = "unknown";
180
181                 if (request == PTRACE_POKEDATA && data == 0x91d02001){
182                         printk ("do_ptrace: breakpoint pid=%d, addr=%016lx addr2=%016lx\n",
183                                 pid, addr, addr2);
184                 } else 
185                         printk("do_ptrace: rq=%s(%d) pid=%d addr=%016lx data=%016lx addr2=%016lx\n",
186                                s, request, pid, addr, data, addr2);
187         }
188 #endif
189         if (request == PTRACE_TRACEME) {
190                 int ret;
191
192                 /* are we already being traced? */
193                 if (current->ptrace & PT_PTRACED) {
194                         pt_error_return(regs, EPERM);
195                         goto out;
196                 }
197                 ret = security_ptrace(current->parent, current);
198                 if (ret) {
199                         pt_error_return(regs, -ret);
200                         goto out;
201                 }
202
203                 /* set the ptrace bit in the process flags. */
204                 current->ptrace |= PT_PTRACED;
205                 pt_succ_return(regs, 0);
206                 goto out;
207         }
208 #ifndef ALLOW_INIT_TRACING
209         if (pid == 1) {
210                 /* Can't dork with init. */
211                 pt_error_return(regs, EPERM);
212                 goto out;
213         }
214 #endif
215         read_lock(&tasklist_lock);
216         child = find_task_by_pid(pid);
217         if (child)
218                 get_task_struct(child);
219         read_unlock(&tasklist_lock);
220
221         if (!child) {
222                 pt_error_return(regs, ESRCH);
223                 goto out;
224         }
225         if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) {
226                 pt_error_return(regs, ESRCH);
227                 goto out_tsk;
228         }
229
230         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
231             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
232                 if (ptrace_attach(child)) {
233                         pt_error_return(regs, EPERM);
234                         goto out_tsk;
235                 }
236                 pt_succ_return(regs, 0);
237                 goto out_tsk;
238         }
239
240         ret = ptrace_check_attach(child, request == PTRACE_KILL);
241         if (ret < 0) {
242                 pt_error_return(regs, -ret);
243                 goto out_tsk;
244         }
245
246         if (!(test_thread_flag(TIF_32BIT))      &&
247             ((request == PTRACE_READDATA64)             ||
248              (request == PTRACE_WRITEDATA64)            ||
249              (request == PTRACE_READTEXT64)             ||
250              (request == PTRACE_WRITETEXT64)            ||
251              (request == PTRACE_PEEKTEXT64)             ||
252              (request == PTRACE_POKETEXT64)             ||
253              (request == PTRACE_PEEKDATA64)             ||
254              (request == PTRACE_POKEDATA64))) {
255                 addr = regs->u_regs[UREG_G2];
256                 addr2 = regs->u_regs[UREG_G3];
257                 request -= 30; /* wheee... */
258         }
259
260         switch(request) {
261         case PTRACE_PEEKTEXT: /* read word at location addr. */ 
262         case PTRACE_PEEKDATA: {
263                 unsigned long tmp64;
264                 unsigned int tmp32;
265                 int res, copied;
266
267                 res = -EIO;
268                 if (test_thread_flag(TIF_32BIT)) {
269                         copied = access_process_vm(child, addr,
270                                                    &tmp32, sizeof(tmp32), 0);
271                         tmp64 = (unsigned long) tmp32;
272                         if (copied == sizeof(tmp32))
273                                 res = 0;
274                 } else {
275                         copied = access_process_vm(child, addr,
276                                                    &tmp64, sizeof(tmp64), 0);
277                         if (copied == sizeof(tmp64))
278                                 res = 0;
279                 }
280                 if (res < 0)
281                         pt_error_return(regs, -res);
282                 else
283                         pt_os_succ_return(regs, tmp64, (void __user *) data);
284                 goto out_tsk;
285         }
286
287         case PTRACE_POKETEXT: /* write the word at location addr. */
288         case PTRACE_POKEDATA: {
289                 unsigned long tmp64;
290                 unsigned int tmp32;
291                 int copied, res = -EIO;
292
293                 if (test_thread_flag(TIF_32BIT)) {
294                         tmp32 = data;
295                         copied = access_process_vm(child, addr,
296                                                    &tmp32, sizeof(tmp32), 1);
297                         if (copied == sizeof(tmp32))
298                                 res = 0;
299                 } else {
300                         tmp64 = data;
301                         copied = access_process_vm(child, addr,
302                                                    &tmp64, sizeof(tmp64), 1);
303                         if (copied == sizeof(tmp64))
304                                 res = 0;
305                 }
306                 if (res < 0)
307                         pt_error_return(regs, -res);
308                 else
309                         pt_succ_return(regs, res);
310                 goto out_tsk;
311         }
312
313         case PTRACE_GETREGS: {
314                 struct pt_regs32 __user *pregs =
315                         (struct pt_regs32 __user *) addr;
316                 struct pt_regs *cregs = child->thread_info->kregs;
317                 int rval;
318
319                 if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
320                     __put_user(cregs->tpc, (&pregs->pc)) ||
321                     __put_user(cregs->tnpc, (&pregs->npc)) ||
322                     __put_user(cregs->y, (&pregs->y))) {
323                         pt_error_return(regs, EFAULT);
324                         goto out_tsk;
325                 }
326                 for (rval = 1; rval < 16; rval++)
327                         if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
328                                 pt_error_return(regs, EFAULT);
329                                 goto out_tsk;
330                         }
331                 pt_succ_return(regs, 0);
332 #ifdef DEBUG_PTRACE
333                 printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
334 #endif
335                 goto out_tsk;
336         }
337
338         case PTRACE_GETREGS64: {
339                 struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
340                 struct pt_regs *cregs = child->thread_info->kregs;
341                 unsigned long tpc = cregs->tpc;
342                 int rval;
343
344                 if ((child->thread_info->flags & _TIF_32BIT) != 0)
345                         tpc &= 0xffffffff;
346                 if (__put_user(cregs->tstate, (&pregs->tstate)) ||
347                     __put_user(tpc, (&pregs->tpc)) ||
348                     __put_user(cregs->tnpc, (&pregs->tnpc)) ||
349                     __put_user(cregs->y, (&pregs->y))) {
350                         pt_error_return(regs, EFAULT);
351                         goto out_tsk;
352                 }
353                 for (rval = 1; rval < 16; rval++)
354                         if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
355                                 pt_error_return(regs, EFAULT);
356                                 goto out_tsk;
357                         }
358                 pt_succ_return(regs, 0);
359 #ifdef DEBUG_PTRACE
360                 printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
361 #endif
362                 goto out_tsk;
363         }
364
365         case PTRACE_SETREGS: {
366                 struct pt_regs32 __user *pregs =
367                         (struct pt_regs32 __user *) addr;
368                 struct pt_regs *cregs = child->thread_info->kregs;
369                 unsigned int psr, pc, npc, y;
370                 int i;
371
372                 /* Must be careful, tracing process can only set certain
373                  * bits in the psr.
374                  */
375                 if (__get_user(psr, (&pregs->psr)) ||
376                     __get_user(pc, (&pregs->pc)) ||
377                     __get_user(npc, (&pregs->npc)) ||
378                     __get_user(y, (&pregs->y))) {
379                         pt_error_return(regs, EFAULT);
380                         goto out_tsk;
381                 }
382                 cregs->tstate &= ~(TSTATE_ICC);
383                 cregs->tstate |= psr_to_tstate_icc(psr);
384                 if (!((pc | npc) & 3)) {
385                         cregs->tpc = pc;
386                         cregs->tnpc = npc;
387                 }
388                 cregs->y = y;
389                 for (i = 1; i < 16; i++) {
390                         if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
391                                 pt_error_return(regs, EFAULT);
392                                 goto out_tsk;
393                         }
394                 }
395                 pt_succ_return(regs, 0);
396                 goto out_tsk;
397         }
398
399         case PTRACE_SETREGS64: {
400                 struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
401                 struct pt_regs *cregs = child->thread_info->kregs;
402                 unsigned long tstate, tpc, tnpc, y;
403                 int i;
404
405                 /* Must be careful, tracing process can only set certain
406                  * bits in the psr.
407                  */
408                 if (__get_user(tstate, (&pregs->tstate)) ||
409                     __get_user(tpc, (&pregs->tpc)) ||
410                     __get_user(tnpc, (&pregs->tnpc)) ||
411                     __get_user(y, (&pregs->y))) {
412                         pt_error_return(regs, EFAULT);
413                         goto out_tsk;
414                 }
415                 if ((child->thread_info->flags & _TIF_32BIT) != 0) {
416                         tpc &= 0xffffffff;
417                         tnpc &= 0xffffffff;
418                 }
419                 tstate &= (TSTATE_ICC | TSTATE_XCC);
420                 cregs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
421                 cregs->tstate |= tstate;
422                 if (!((tpc | tnpc) & 3)) {
423                         cregs->tpc = tpc;
424                         cregs->tnpc = tnpc;
425                 }
426                 cregs->y = y;
427                 for (i = 1; i < 16; i++) {
428                         if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
429                                 pt_error_return(regs, EFAULT);
430                                 goto out_tsk;
431                         }
432                 }
433                 pt_succ_return(regs, 0);
434                 goto out_tsk;
435         }
436
437         case PTRACE_GETFPREGS: {
438                 struct fps {
439                         unsigned int regs[32];
440                         unsigned int fsr;
441                         unsigned int flags;
442                         unsigned int extra;
443                         unsigned int fpqd;
444                         struct fq {
445                                 unsigned int insnaddr;
446                                 unsigned int insn;
447                         } fpq[16];
448                 };
449                 struct fps __user *fps = (struct fps __user *) addr;
450                 unsigned long *fpregs = child->thread_info->fpregs;
451
452                 if (copy_to_user(&fps->regs[0], fpregs,
453                                  (32 * sizeof(unsigned int))) ||
454                     __put_user(child->thread_info->xfsr[0], (&fps->fsr)) ||
455                     __put_user(0, (&fps->fpqd)) ||
456                     __put_user(0, (&fps->flags)) ||
457                     __put_user(0, (&fps->extra)) ||
458                     clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) {
459                         pt_error_return(regs, EFAULT);
460                         goto out_tsk;
461                 }
462                 pt_succ_return(regs, 0);
463                 goto out_tsk;
464         }
465
466         case PTRACE_GETFPREGS64: {
467                 struct fps {
468                         unsigned int regs[64];
469                         unsigned long fsr;
470                 };
471                 struct fps __user *fps = (struct fps __user *) addr;
472                 unsigned long *fpregs = child->thread_info->fpregs;
473
474                 if (copy_to_user(&fps->regs[0], fpregs,
475                                  (64 * sizeof(unsigned int))) ||
476                     __put_user(child->thread_info->xfsr[0], (&fps->fsr))) {
477                         pt_error_return(regs, EFAULT);
478                         goto out_tsk;
479                 }
480                 pt_succ_return(regs, 0);
481                 goto out_tsk;
482         }
483
484         case PTRACE_SETFPREGS: {
485                 struct fps {
486                         unsigned int regs[32];
487                         unsigned int fsr;
488                         unsigned int flags;
489                         unsigned int extra;
490                         unsigned int fpqd;
491                         struct fq {
492                                 unsigned int insnaddr;
493                                 unsigned int insn;
494                         } fpq[16];
495                 };
496                 struct fps __user *fps = (struct fps __user *) addr;
497                 unsigned long *fpregs = child->thread_info->fpregs;
498                 unsigned fsr;
499
500                 if (copy_from_user(fpregs, &fps->regs[0],
501                                    (32 * sizeof(unsigned int))) ||
502                     __get_user(fsr, (&fps->fsr))) {
503                         pt_error_return(regs, EFAULT);
504                         goto out_tsk;
505                 }
506                 child->thread_info->xfsr[0] &= 0xffffffff00000000UL;
507                 child->thread_info->xfsr[0] |= fsr;
508                 if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
509                         child->thread_info->gsr[0] = 0;
510                 child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
511                 pt_succ_return(regs, 0);
512                 goto out_tsk;
513         }
514
515         case PTRACE_SETFPREGS64: {
516                 struct fps {
517                         unsigned int regs[64];
518                         unsigned long fsr;
519                 };
520                 struct fps __user *fps = (struct fps __user *) addr;
521                 unsigned long *fpregs = child->thread_info->fpregs;
522
523                 if (copy_from_user(fpregs, &fps->regs[0],
524                                    (64 * sizeof(unsigned int))) ||
525                     __get_user(child->thread_info->xfsr[0], (&fps->fsr))) {
526                         pt_error_return(regs, EFAULT);
527                         goto out_tsk;
528                 }
529                 if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
530                         child->thread_info->gsr[0] = 0;
531                 child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
532                 pt_succ_return(regs, 0);
533                 goto out_tsk;
534         }
535
536         case PTRACE_READTEXT:
537         case PTRACE_READDATA: {
538                 int res = ptrace_readdata(child, addr,
539                                           (char __user *)addr2, data);
540                 if (res == data) {
541                         pt_succ_return(regs, 0);
542                         goto out_tsk;
543                 }
544                 if (res >= 0)
545                         res = -EIO;
546                 pt_error_return(regs, -res);
547                 goto out_tsk;
548         }
549
550         case PTRACE_WRITETEXT:
551         case PTRACE_WRITEDATA: {
552                 int res = ptrace_writedata(child, (char __user *) addr2,
553                                            addr, data);
554                 if (res == data) {
555                         pt_succ_return(regs, 0);
556                         goto out_tsk;
557                 }
558                 if (res >= 0)
559                         res = -EIO;
560                 pt_error_return(regs, -res);
561                 goto out_tsk;
562         }
563         case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
564                 addr = 1;
565
566         case PTRACE_CONT: { /* restart after signal. */
567                 if (!valid_signal(data)) {
568                         pt_error_return(regs, EIO);
569                         goto out_tsk;
570                 }
571
572                 if (request == PTRACE_SYSCALL) {
573                         set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
574                 } else {
575                         clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
576                 }
577
578                 child->exit_code = data;
579 #ifdef DEBUG_PTRACE
580                 printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n", child->comm,
581                         child->pid, child->exit_code,
582                         child->thread_info->kregs->tpc,
583                         child->thread_info->kregs->tnpc);
584                        
585 #endif
586                 wake_up_process(child);
587                 pt_succ_return(regs, 0);
588                 goto out_tsk;
589         }
590
591 /*
592  * make the child exit.  Best I can do is send it a sigkill. 
593  * perhaps it should be put in the status that it wants to 
594  * exit.
595  */
596         case PTRACE_KILL: {
597                 if (child->exit_state == EXIT_ZOMBIE) { /* already dead */
598                         pt_succ_return(regs, 0);
599                         goto out_tsk;
600                 }
601                 child->exit_code = SIGKILL;
602                 wake_up_process(child);
603                 pt_succ_return(regs, 0);
604                 goto out_tsk;
605         }
606
607         case PTRACE_SUNDETACH: { /* detach a process that was attached. */
608                 int error = ptrace_detach(child, data);
609                 if (error) {
610                         pt_error_return(regs, EIO);
611                         goto out_tsk;
612                 }
613                 pt_succ_return(regs, 0);
614                 goto out_tsk;
615         }
616
617         /* PTRACE_DUMPCORE unsupported... */
618
619         default: {
620                 int err = ptrace_request(child, request, addr, data);
621                 if (err)
622                         pt_error_return(regs, -err);
623                 else
624                         pt_succ_return(regs, 0);
625                 goto out_tsk;
626         }
627         }
628 out_tsk:
629         if (child)
630                 put_task_struct(child);
631 out:
632         unlock_kernel();
633 }
634
635 asmlinkage void syscall_trace(void)
636 {
637 #ifdef DEBUG_PTRACE
638         printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
639 #endif
640         if (!test_thread_flag(TIF_SYSCALL_TRACE))
641                 return;
642         if (!(current->ptrace & PT_PTRACED))
643                 return;
644         ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
645                                  ? 0x80 : 0));
646
647         /*
648          * this isn't the same as continuing with a signal, but it will do
649          * for normal use.  strace only continues with a signal if the
650          * stopping signal is not SIGTRAP.  -brl
651          */
652 #ifdef DEBUG_PTRACE
653         printk("%s [%d]: syscall_trace exit= %x\n", current->comm,
654                 current->pid, current->exit_code);
655 #endif
656         if (current->exit_code) {
657                 send_sig (current->exit_code, current, 1);
658                 current->exit_code = 0;
659         }
660 }