ia64/linux-2.6.18-xen.hg

view arch/sparc64/kernel/signal.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 /* $Id: signal.c,v 1.60 2002/02/09 19:49:31 davem Exp $
2 * arch/sparc64/kernel/signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
7 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
8 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9 */
11 #ifdef CONFIG_SPARC32_COMPAT
12 #include <linux/compat.h> /* for compat_old_sigset_t */
13 #endif
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17 #include <linux/errno.h>
18 #include <linux/wait.h>
19 #include <linux/ptrace.h>
20 #include <linux/unistd.h>
21 #include <linux/mm.h>
22 #include <linux/tty.h>
23 #include <linux/smp_lock.h>
24 #include <linux/binfmts.h>
25 #include <linux/bitops.h>
27 #include <asm/uaccess.h>
28 #include <asm/ptrace.h>
29 #include <asm/svr4.h>
30 #include <asm/pgtable.h>
31 #include <asm/fpumacro.h>
32 #include <asm/uctx.h>
33 #include <asm/siginfo.h>
34 #include <asm/visasm.h>
36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
38 /* {set, get}context() needed for 64-bit SparcLinux userland. */
39 asmlinkage void sparc64_set_context(struct pt_regs *regs)
40 {
41 struct ucontext __user *ucp = (struct ucontext __user *)
42 regs->u_regs[UREG_I0];
43 mc_gregset_t __user *grp;
44 unsigned long pc, npc, tstate;
45 unsigned long fp, i7;
46 unsigned char fenab;
47 int err;
49 flush_user_windows();
50 if (get_thread_wsaved() ||
51 (((unsigned long)ucp) & (sizeof(unsigned long)-1)) ||
52 (!__access_ok(ucp, sizeof(*ucp))))
53 goto do_sigsegv;
54 grp = &ucp->uc_mcontext.mc_gregs;
55 err = __get_user(pc, &((*grp)[MC_PC]));
56 err |= __get_user(npc, &((*grp)[MC_NPC]));
57 if (err || ((pc | npc) & 3))
58 goto do_sigsegv;
59 if (regs->u_regs[UREG_I1]) {
60 sigset_t set;
62 if (_NSIG_WORDS == 1) {
63 if (__get_user(set.sig[0], &ucp->uc_sigmask.sig[0]))
64 goto do_sigsegv;
65 } else {
66 if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(sigset_t)))
67 goto do_sigsegv;
68 }
69 sigdelsetmask(&set, ~_BLOCKABLE);
70 spin_lock_irq(&current->sighand->siglock);
71 current->blocked = set;
72 recalc_sigpending();
73 spin_unlock_irq(&current->sighand->siglock);
74 }
75 if (test_thread_flag(TIF_32BIT)) {
76 pc &= 0xffffffff;
77 npc &= 0xffffffff;
78 }
79 regs->tpc = pc;
80 regs->tnpc = npc;
81 err |= __get_user(regs->y, &((*grp)[MC_Y]));
82 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
83 regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
84 regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
85 err |= __get_user(regs->u_regs[UREG_G1], (&(*grp)[MC_G1]));
86 err |= __get_user(regs->u_regs[UREG_G2], (&(*grp)[MC_G2]));
87 err |= __get_user(regs->u_regs[UREG_G3], (&(*grp)[MC_G3]));
88 err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4]));
89 err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5]));
90 err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6]));
91 err |= __get_user(regs->u_regs[UREG_G7], (&(*grp)[MC_G7]));
92 err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0]));
93 err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1]));
94 err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2]));
95 err |= __get_user(regs->u_regs[UREG_I3], (&(*grp)[MC_O3]));
96 err |= __get_user(regs->u_regs[UREG_I4], (&(*grp)[MC_O4]));
97 err |= __get_user(regs->u_regs[UREG_I5], (&(*grp)[MC_O5]));
98 err |= __get_user(regs->u_regs[UREG_I6], (&(*grp)[MC_O6]));
99 err |= __get_user(regs->u_regs[UREG_I7], (&(*grp)[MC_O7]));
101 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
102 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
103 err |= __put_user(fp,
104 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
105 err |= __put_user(i7,
106 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
108 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
109 if (fenab) {
110 unsigned long *fpregs = current_thread_info()->fpregs;
111 unsigned long fprs;
113 fprs_write(0);
114 err |= __get_user(fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
115 if (fprs & FPRS_DL)
116 err |= copy_from_user(fpregs,
117 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs),
118 (sizeof(unsigned int) * 32));
119 if (fprs & FPRS_DU)
120 err |= copy_from_user(fpregs+16,
121 ((unsigned long __user *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16,
122 (sizeof(unsigned int) * 32));
123 err |= __get_user(current_thread_info()->xfsr[0],
124 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
125 err |= __get_user(current_thread_info()->gsr[0],
126 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
127 regs->tstate &= ~TSTATE_PEF;
128 }
129 if (err)
130 goto do_sigsegv;
132 return;
133 do_sigsegv:
134 force_sig(SIGSEGV, current);
135 }
137 asmlinkage void sparc64_get_context(struct pt_regs *regs)
138 {
139 struct ucontext __user *ucp = (struct ucontext __user *)
140 regs->u_regs[UREG_I0];
141 mc_gregset_t __user *grp;
142 mcontext_t __user *mcp;
143 unsigned long fp, i7;
144 unsigned char fenab;
145 int err;
147 synchronize_user_stack();
148 if (get_thread_wsaved() || clear_user(ucp, sizeof(*ucp)))
149 goto do_sigsegv;
151 #if 1
152 fenab = 0; /* IMO get_context is like any other system call, thus modifies FPU state -jj */
153 #else
154 fenab = (current_thread_info()->fpsaved[0] & FPRS_FEF);
155 #endif
157 mcp = &ucp->uc_mcontext;
158 grp = &mcp->mc_gregs;
160 /* Skip over the trap instruction, first. */
161 if (test_thread_flag(TIF_32BIT)) {
162 regs->tpc = (regs->tnpc & 0xffffffff);
163 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
164 } else {
165 regs->tpc = regs->tnpc;
166 regs->tnpc += 4;
167 }
168 err = 0;
169 if (_NSIG_WORDS == 1)
170 err |= __put_user(current->blocked.sig[0],
171 (unsigned long __user *)&ucp->uc_sigmask);
172 else
173 err |= __copy_to_user(&ucp->uc_sigmask, &current->blocked,
174 sizeof(sigset_t));
176 err |= __put_user(regs->tstate, &((*grp)[MC_TSTATE]));
177 err |= __put_user(regs->tpc, &((*grp)[MC_PC]));
178 err |= __put_user(regs->tnpc, &((*grp)[MC_NPC]));
179 err |= __put_user(regs->y, &((*grp)[MC_Y]));
180 err |= __put_user(regs->u_regs[UREG_G1], &((*grp)[MC_G1]));
181 err |= __put_user(regs->u_regs[UREG_G2], &((*grp)[MC_G2]));
182 err |= __put_user(regs->u_regs[UREG_G3], &((*grp)[MC_G3]));
183 err |= __put_user(regs->u_regs[UREG_G4], &((*grp)[MC_G4]));
184 err |= __put_user(regs->u_regs[UREG_G5], &((*grp)[MC_G5]));
185 err |= __put_user(regs->u_regs[UREG_G6], &((*grp)[MC_G6]));
186 err |= __put_user(regs->u_regs[UREG_G7], &((*grp)[MC_G7]));
187 err |= __put_user(regs->u_regs[UREG_I0], &((*grp)[MC_O0]));
188 err |= __put_user(regs->u_regs[UREG_I1], &((*grp)[MC_O1]));
189 err |= __put_user(regs->u_regs[UREG_I2], &((*grp)[MC_O2]));
190 err |= __put_user(regs->u_regs[UREG_I3], &((*grp)[MC_O3]));
191 err |= __put_user(regs->u_regs[UREG_I4], &((*grp)[MC_O4]));
192 err |= __put_user(regs->u_regs[UREG_I5], &((*grp)[MC_O5]));
193 err |= __put_user(regs->u_regs[UREG_I6], &((*grp)[MC_O6]));
194 err |= __put_user(regs->u_regs[UREG_I7], &((*grp)[MC_O7]));
196 err |= __get_user(fp,
197 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
198 err |= __get_user(i7,
199 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
200 err |= __put_user(fp, &(mcp->mc_fp));
201 err |= __put_user(i7, &(mcp->mc_i7));
203 err |= __put_user(fenab, &(mcp->mc_fpregs.mcfpu_enab));
204 if (fenab) {
205 unsigned long *fpregs = current_thread_info()->fpregs;
206 unsigned long fprs;
208 fprs = current_thread_info()->fpsaved[0];
209 if (fprs & FPRS_DL)
210 err |= copy_to_user(&(mcp->mc_fpregs.mcfpu_fregs), fpregs,
211 (sizeof(unsigned int) * 32));
212 if (fprs & FPRS_DU)
213 err |= copy_to_user(
214 ((unsigned long __user *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
215 (sizeof(unsigned int) * 32));
216 err |= __put_user(current_thread_info()->xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
217 err |= __put_user(current_thread_info()->gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
218 err |= __put_user(fprs, &(mcp->mc_fpregs.mcfpu_fprs));
219 }
220 if (err)
221 goto do_sigsegv;
223 return;
224 do_sigsegv:
225 force_sig(SIGSEGV, current);
226 }
228 struct rt_signal_frame {
229 struct sparc_stackf ss;
230 siginfo_t info;
231 struct pt_regs regs;
232 __siginfo_fpu_t __user *fpu_save;
233 stack_t stack;
234 sigset_t mask;
235 __siginfo_fpu_t fpu_state;
236 };
238 /* Align macros */
239 #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
241 static long _sigpause_common(old_sigset_t set)
242 {
243 set &= _BLOCKABLE;
244 spin_lock_irq(&current->sighand->siglock);
245 current->saved_sigmask = current->blocked;
246 siginitset(&current->blocked, set);
247 recalc_sigpending();
248 spin_unlock_irq(&current->sighand->siglock);
250 current->state = TASK_INTERRUPTIBLE;
251 schedule();
252 set_thread_flag(TIF_RESTORE_SIGMASK);
253 return -ERESTARTNOHAND;
254 }
256 asmlinkage long sys_sigpause(unsigned int set)
257 {
258 return _sigpause_common(set);
259 }
261 asmlinkage long sys_sigsuspend(old_sigset_t set)
262 {
263 return _sigpause_common(set);
264 }
266 static inline int
267 restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
268 {
269 unsigned long *fpregs = current_thread_info()->fpregs;
270 unsigned long fprs;
271 int err;
273 err = __get_user(fprs, &fpu->si_fprs);
274 fprs_write(0);
275 regs->tstate &= ~TSTATE_PEF;
276 if (fprs & FPRS_DL)
277 err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
278 (sizeof(unsigned int) * 32));
279 if (fprs & FPRS_DU)
280 err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
281 (sizeof(unsigned int) * 32));
282 err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
283 err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr);
284 current_thread_info()->fpsaved[0] |= fprs;
285 return err;
286 }
288 void do_rt_sigreturn(struct pt_regs *regs)
289 {
290 struct rt_signal_frame __user *sf;
291 unsigned long tpc, tnpc, tstate;
292 __siginfo_fpu_t __user *fpu_save;
293 mm_segment_t old_fs;
294 sigset_t set;
295 stack_t st;
296 int err;
298 /* Always make any pending restarted system calls return -EINTR */
299 current_thread_info()->restart_block.fn = do_no_restart_syscall;
301 synchronize_user_stack ();
302 sf = (struct rt_signal_frame __user *)
303 (regs->u_regs [UREG_FP] + STACK_BIAS);
305 /* 1. Make sure we are not getting garbage from the user */
306 if (((unsigned long) sf) & 3)
307 goto segv;
309 err = get_user(tpc, &sf->regs.tpc);
310 err |= __get_user(tnpc, &sf->regs.tnpc);
311 if (test_thread_flag(TIF_32BIT)) {
312 tpc &= 0xffffffff;
313 tnpc &= 0xffffffff;
314 }
315 err |= ((tpc | tnpc) & 3);
317 /* 2. Restore the state */
318 err |= __get_user(regs->y, &sf->regs.y);
319 err |= __get_user(tstate, &sf->regs.tstate);
320 err |= copy_from_user(regs->u_regs, sf->regs.u_regs, sizeof(regs->u_regs));
322 /* User can only change condition codes and %asi in %tstate. */
323 regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
324 regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
326 err |= __get_user(fpu_save, &sf->fpu_save);
327 if (fpu_save)
328 err |= restore_fpu_state(regs, &sf->fpu_state);
330 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
331 err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t));
333 if (err)
334 goto segv;
336 regs->tpc = tpc;
337 regs->tnpc = tnpc;
339 /* It is more difficult to avoid calling this function than to
340 call it and ignore errors. */
341 old_fs = get_fs();
342 set_fs(KERNEL_DS);
343 do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
344 set_fs(old_fs);
346 sigdelsetmask(&set, ~_BLOCKABLE);
347 spin_lock_irq(&current->sighand->siglock);
348 current->blocked = set;
349 recalc_sigpending();
350 spin_unlock_irq(&current->sighand->siglock);
351 return;
352 segv:
353 force_sig(SIGSEGV, current);
354 }
356 /* Checks if the fp is valid */
357 static int invalid_frame_pointer(void __user *fp, int fplen)
358 {
359 if (((unsigned long) fp) & 7)
360 return 1;
361 return 0;
362 }
364 static inline int
365 save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
366 {
367 unsigned long *fpregs = (unsigned long *)(regs+1);
368 unsigned long fprs;
369 int err = 0;
371 fprs = current_thread_info()->fpsaved[0];
372 if (fprs & FPRS_DL)
373 err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
374 (sizeof(unsigned int) * 32));
375 if (fprs & FPRS_DU)
376 err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
377 (sizeof(unsigned int) * 32));
378 err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr);
379 err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr);
380 err |= __put_user(fprs, &fpu->si_fprs);
382 return err;
383 }
385 static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
386 {
387 unsigned long sp;
389 sp = regs->u_regs[UREG_FP] + STACK_BIAS;
391 /* This is the X/Open sanctioned signal stack switching. */
392 if (ka->sa.sa_flags & SA_ONSTACK) {
393 if (!on_sig_stack(sp) &&
394 !((current->sas_ss_sp + current->sas_ss_size) & 7))
395 sp = current->sas_ss_sp + current->sas_ss_size;
396 }
397 return (void __user *)(sp - framesize);
398 }
400 static inline void
401 setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
402 int signo, sigset_t *oldset, siginfo_t *info)
403 {
404 struct rt_signal_frame __user *sf;
405 int sigframe_size, err;
407 /* 1. Make sure everything is clean */
408 synchronize_user_stack();
409 save_and_clear_fpu();
411 sigframe_size = RT_ALIGNEDSZ;
412 if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
413 sigframe_size -= sizeof(__siginfo_fpu_t);
415 sf = (struct rt_signal_frame __user *)
416 get_sigframe(ka, regs, sigframe_size);
418 if (invalid_frame_pointer (sf, sigframe_size))
419 goto sigill;
421 if (get_thread_wsaved() != 0)
422 goto sigill;
424 /* 2. Save the current process state */
425 err = copy_to_user(&sf->regs, regs, sizeof (*regs));
427 if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
428 err |= save_fpu_state(regs, &sf->fpu_state);
429 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
430 } else {
431 err |= __put_user(0, &sf->fpu_save);
432 }
434 /* Setup sigaltstack */
435 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
436 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
437 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
439 err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
441 err |= copy_in_user((u64 __user *)sf,
442 (u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS),
443 sizeof(struct reg_window));
445 if (info)
446 err |= copy_siginfo_to_user(&sf->info, info);
447 else {
448 err |= __put_user(signo, &sf->info.si_signo);
449 err |= __put_user(SI_NOINFO, &sf->info.si_code);
450 }
451 if (err)
452 goto sigsegv;
454 /* 3. signal handler back-trampoline and parameters */
455 regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS;
456 regs->u_regs[UREG_I0] = signo;
457 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
459 /* The sigcontext is passed in this way because of how it
460 * is defined in GLIBC's /usr/include/bits/sigcontext.h
461 * for sparc64. It includes the 128 bytes of siginfo_t.
462 */
463 regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
465 /* 5. signal handler */
466 regs->tpc = (unsigned long) ka->sa.sa_handler;
467 regs->tnpc = (regs->tpc + 4);
468 if (test_thread_flag(TIF_32BIT)) {
469 regs->tpc &= 0xffffffff;
470 regs->tnpc &= 0xffffffff;
471 }
472 /* 4. return to kernel instructions */
473 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
474 return;
476 sigill:
477 do_exit(SIGILL);
478 sigsegv:
479 force_sigsegv(signo, current);
480 }
482 static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
483 siginfo_t *info,
484 sigset_t *oldset, struct pt_regs *regs)
485 {
486 setup_rt_frame(ka, regs, signr, oldset,
487 (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
488 spin_lock_irq(&current->sighand->siglock);
489 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
490 if (!(ka->sa.sa_flags & SA_NOMASK))
491 sigaddset(&current->blocked,signr);
492 recalc_sigpending();
493 spin_unlock_irq(&current->sighand->siglock);
494 }
496 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
497 struct sigaction *sa)
498 {
499 switch (regs->u_regs[UREG_I0]) {
500 case ERESTART_RESTARTBLOCK:
501 case ERESTARTNOHAND:
502 no_system_call_restart:
503 regs->u_regs[UREG_I0] = EINTR;
504 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
505 break;
506 case ERESTARTSYS:
507 if (!(sa->sa_flags & SA_RESTART))
508 goto no_system_call_restart;
509 /* fallthrough */
510 case ERESTARTNOINTR:
511 regs->u_regs[UREG_I0] = orig_i0;
512 regs->tpc -= 4;
513 regs->tnpc -= 4;
514 }
515 }
517 /* Note that 'init' is a special process: it doesn't get signals it doesn't
518 * want to handle. Thus you cannot kill init even with a SIGKILL even by
519 * mistake.
520 */
521 static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
522 {
523 siginfo_t info;
524 struct signal_deliver_cookie cookie;
525 struct k_sigaction ka;
526 int signr;
527 sigset_t *oldset;
529 cookie.restart_syscall = restart_syscall;
530 cookie.orig_i0 = orig_i0;
532 if (test_thread_flag(TIF_RESTORE_SIGMASK))
533 oldset = &current->saved_sigmask;
534 else
535 oldset = &current->blocked;
537 #ifdef CONFIG_SPARC32_COMPAT
538 if (test_thread_flag(TIF_32BIT)) {
539 extern void do_signal32(sigset_t *, struct pt_regs *,
540 unsigned long, int);
541 do_signal32(oldset, regs, orig_i0,
542 cookie.restart_syscall);
543 return;
544 }
545 #endif
547 signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
548 if (signr > 0) {
549 if (cookie.restart_syscall)
550 syscall_restart(orig_i0, regs, &ka.sa);
551 handle_signal(signr, &ka, &info, oldset, regs);
553 /* a signal was successfully delivered; the saved
554 * sigmask will have been stored in the signal frame,
555 * and will be restored by sigreturn, so we can simply
556 * clear the TIF_RESTORE_SIGMASK flag.
557 */
558 if (test_thread_flag(TIF_RESTORE_SIGMASK))
559 clear_thread_flag(TIF_RESTORE_SIGMASK);
560 return;
561 }
562 if (cookie.restart_syscall &&
563 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
564 regs->u_regs[UREG_I0] == ERESTARTSYS ||
565 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
566 /* replay the system call when we are done */
567 regs->u_regs[UREG_I0] = cookie.orig_i0;
568 regs->tpc -= 4;
569 regs->tnpc -= 4;
570 }
571 if (cookie.restart_syscall &&
572 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
573 regs->u_regs[UREG_G1] = __NR_restart_syscall;
574 regs->tpc -= 4;
575 regs->tnpc -= 4;
576 }
578 /* if there's no signal to deliver, we just put the saved sigmask
579 * back
580 */
581 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
582 clear_thread_flag(TIF_RESTORE_SIGMASK);
583 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
584 }
585 }
587 void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall,
588 unsigned long thread_info_flags)
589 {
590 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
591 do_signal(regs, orig_i0, restart_syscall);
592 }
594 void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
595 {
596 struct signal_deliver_cookie *cp = cookie;
598 if (cp->restart_syscall &&
599 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
600 regs->u_regs[UREG_I0] == ERESTARTSYS ||
601 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
602 /* replay the system call when we are done */
603 regs->u_regs[UREG_I0] = cp->orig_i0;
604 regs->tpc -= 4;
605 regs->tnpc -= 4;
606 cp->restart_syscall = 0;
607 }
608 if (cp->restart_syscall &&
609 regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
610 regs->u_regs[UREG_G1] = __NR_restart_syscall;
611 regs->tpc -= 4;
612 regs->tnpc -= 4;
613 cp->restart_syscall = 0;
614 }
615 }