aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel/signal.c')
-rw-r--r--arch/microblaze/kernel/signal.c85
1 files changed, 45 insertions, 40 deletions
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 599671168980..7f4c7bef1642 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -31,6 +31,7 @@
31#include <linux/personality.h> 31#include <linux/personality.h>
32#include <linux/percpu.h> 32#include <linux/percpu.h>
33#include <linux/linkage.h> 33#include <linux/linkage.h>
34#include <linux/tracehook.h>
34#include <asm/entry.h> 35#include <asm/entry.h>
35#include <asm/ucontext.h> 36#include <asm/ucontext.h>
36#include <linux/uaccess.h> 37#include <linux/uaccess.h>
@@ -42,8 +43,6 @@
42 43
43#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
44 45
45asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
46
47asmlinkage long 46asmlinkage long
48sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 47sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
49 struct pt_regs *regs) 48 struct pt_regs *regs)
@@ -98,6 +97,9 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
98 sigset_t set; 97 sigset_t set;
99 int rval; 98 int rval;
100 99
100 /* Always make any pending restarted system calls return -EINTR */
101 current_thread_info()->restart_block.fn = do_no_restart_syscall;
102
101 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 103 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
102 goto badframe; 104 goto badframe;
103 105
@@ -105,10 +107,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
105 goto badframe; 107 goto badframe;
106 108
107 sigdelsetmask(&set, ~_BLOCKABLE); 109 sigdelsetmask(&set, ~_BLOCKABLE);
108 spin_lock_irq(&current->sighand->siglock); 110 set_current_blocked(&set);
109 current->blocked = set;
110 recalc_sigpending();
111 spin_unlock_irq(&current->sighand->siglock);
112 111
113 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval)) 112 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
114 goto badframe; 113 goto badframe;
@@ -169,7 +168,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
169 return (void __user *)((sp - frame_size) & -8UL); 168 return (void __user *)((sp - frame_size) & -8UL);
170} 169}
171 170
172static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 171static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
173 sigset_t *set, struct pt_regs *regs) 172 sigset_t *set, struct pt_regs *regs)
174{ 173{
175 struct rt_sigframe __user *frame; 174 struct rt_sigframe __user *frame;
@@ -267,12 +266,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
267 current->comm, current->pid, frame, regs->pc); 266 current->comm, current->pid, frame, regs->pc);
268#endif 267#endif
269 268
270 return; 269 return 0;
271 270
272give_sigsegv: 271give_sigsegv:
273 if (sig == SIGSEGV) 272 force_sigsegv(sig, current);
274 ka->sa.sa_handler = SIG_DFL; 273 return -EFAULT;
275 force_sig(SIGSEGV, current);
276} 274}
277 275
278/* Handle restarting system calls */ 276/* Handle restarting system calls */
@@ -316,24 +314,20 @@ static int
316handle_signal(unsigned long sig, struct k_sigaction *ka, 314handle_signal(unsigned long sig, struct k_sigaction *ka,
317 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) 315 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
318{ 316{
317 int ret;
318
319 /* Set up the stack frame */ 319 /* Set up the stack frame */
320 if (ka->sa.sa_flags & SA_SIGINFO) 320 if (ka->sa.sa_flags & SA_SIGINFO)
321 setup_rt_frame(sig, ka, info, oldset, regs); 321 ret = setup_rt_frame(sig, ka, info, oldset, regs);
322 else 322 else
323 setup_rt_frame(sig, ka, NULL, oldset, regs); 323 ret = setup_rt_frame(sig, ka, NULL, oldset, regs);
324 324
325 if (ka->sa.sa_flags & SA_ONESHOT) 325 if (ret)
326 ka->sa.sa_handler = SIG_DFL; 326 return ret;
327 327
328 if (!(ka->sa.sa_flags & SA_NODEFER)) { 328 block_sigmask(ka, sig);
329 spin_lock_irq(&current->sighand->siglock); 329
330 sigorsets(&current->blocked, 330 return 0;
331 &current->blocked, &ka->sa.sa_mask);
332 sigaddset(&current->blocked, sig);
333 recalc_sigpending();
334 spin_unlock_irq(&current->sighand->siglock);
335 }
336 return 1;
337} 331}
338 332
339/* 333/*
@@ -345,24 +339,17 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
345 * the kernel can handle, and then we build all the user-level signal handling 339 * the kernel can handle, and then we build all the user-level signal handling
346 * stack-frames in one go after that. 340 * stack-frames in one go after that.
347 */ 341 */
348int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) 342static void do_signal(struct pt_regs *regs, int in_syscall)
349{ 343{
350 siginfo_t info; 344 siginfo_t info;
351 int signr; 345 int signr;
352 struct k_sigaction ka; 346 struct k_sigaction ka;
347 sigset_t *oldset;
353#ifdef DEBUG_SIG 348#ifdef DEBUG_SIG
354 printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall); 349 printk(KERN_INFO "do signal: %p %d\n", regs, in_syscall);
355 printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1, 350 printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
356 regs->r12, current_thread_info()->flags); 351 regs->r12, current_thread_info()->flags);
357#endif 352#endif
358 /*
359 * We want the common case to go fast, which
360 * is why we may in certain cases get here from
361 * kernel mode. Just return without doing anything
362 * if so.
363 */
364 if (kernel_mode(regs))
365 return 1;
366 353
367 if (current_thread_info()->status & TS_RESTORE_SIGMASK) 354 if (current_thread_info()->status & TS_RESTORE_SIGMASK)
368 oldset = &current->saved_sigmask; 355 oldset = &current->saved_sigmask;
@@ -374,7 +361,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
374 /* Whee! Actually deliver the signal. */ 361 /* Whee! Actually deliver the signal. */
375 if (in_syscall) 362 if (in_syscall)
376 handle_restart(regs, &ka, 1); 363 handle_restart(regs, &ka, 1);
377 if (handle_signal(signr, &ka, &info, oldset, regs)) { 364 if (!handle_signal(signr, &ka, &info, oldset, regs)) {
378 /* 365 /*
379 * A signal was successfully delivered; the saved 366 * A signal was successfully delivered; the saved
380 * sigmask will have been stored in the signal frame, 367 * sigmask will have been stored in the signal frame,
@@ -384,7 +371,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
384 current_thread_info()->status &= 371 current_thread_info()->status &=
385 ~TS_RESTORE_SIGMASK; 372 ~TS_RESTORE_SIGMASK;
386 } 373 }
387 return 1; 374 return;
388 } 375 }
389 376
390 if (in_syscall) 377 if (in_syscall)
@@ -398,7 +385,25 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
398 current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 385 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
399 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 386 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
400 } 387 }
388}
401 389
402 /* Did we come from a system call? */ 390void do_notify_resume(struct pt_regs *regs, int in_syscall)
403 return 0; 391{
392 /*
393 * We want the common case to go fast, which
394 * is why we may in certain cases get here from
395 * kernel mode. Just return without doing anything
396 * if so.
397 */
398 if (kernel_mode(regs))
399 return;
400
401 if (test_thread_flag(TIF_SIGPENDING))
402 do_signal(regs, in_syscall);
403
404 if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) {
405 tracehook_notify_resume(regs);
406 if (current->replacement_session_keyring)
407 key_replace_session_keyring();
408 }
404} 409}