ia64/linux-2.6.18-xen.hg

view arch/sparc64/kernel/ptrace.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

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