diff options
Diffstat (limited to 'arch/x86_64/kernel/signal.c')
-rw-r--r-- | arch/x86_64/kernel/signal.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 429c0269dc4e..3c5f30893715 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
@@ -34,9 +34,9 @@ | |||
34 | 34 | ||
35 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 35 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
36 | 36 | ||
37 | void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 37 | int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
38 | sigset_t *set, struct pt_regs * regs); | 38 | sigset_t *set, struct pt_regs * regs); |
39 | void ia32_setup_frame(int sig, struct k_sigaction *ka, | 39 | int ia32_setup_frame(int sig, struct k_sigaction *ka, |
40 | sigset_t *set, struct pt_regs * regs); | 40 | sigset_t *set, struct pt_regs * regs); |
41 | 41 | ||
42 | asmlinkage long | 42 | asmlinkage long |
@@ -238,7 +238,7 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) | |||
238 | return (void __user *)round_down(rsp - size, 16); | 238 | return (void __user *)round_down(rsp - size, 16); |
239 | } | 239 | } |
240 | 240 | ||
241 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 241 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
242 | sigset_t *set, struct pt_regs * regs) | 242 | sigset_t *set, struct pt_regs * regs) |
243 | { | 243 | { |
244 | struct rt_sigframe __user *frame; | 244 | struct rt_sigframe __user *frame; |
@@ -327,20 +327,23 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
327 | current->comm, current->pid, frame, regs->rip, frame->pretcode); | 327 | current->comm, current->pid, frame, regs->rip, frame->pretcode); |
328 | #endif | 328 | #endif |
329 | 329 | ||
330 | return; | 330 | return 1; |
331 | 331 | ||
332 | give_sigsegv: | 332 | give_sigsegv: |
333 | force_sigsegv(sig, current); | 333 | force_sigsegv(sig, current); |
334 | return 0; | ||
334 | } | 335 | } |
335 | 336 | ||
336 | /* | 337 | /* |
337 | * OK, we're invoking a handler | 338 | * OK, we're invoking a handler |
338 | */ | 339 | */ |
339 | 340 | ||
340 | static void | 341 | static int |
341 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 342 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
342 | sigset_t *oldset, struct pt_regs *regs) | 343 | sigset_t *oldset, struct pt_regs *regs) |
343 | { | 344 | { |
345 | int ret; | ||
346 | |||
344 | #ifdef DEBUG_SIG | 347 | #ifdef DEBUG_SIG |
345 | printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", | 348 | printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", |
346 | current->pid, sig, | 349 | current->pid, sig, |
@@ -384,20 +387,22 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
384 | #ifdef CONFIG_IA32_EMULATION | 387 | #ifdef CONFIG_IA32_EMULATION |
385 | if (test_thread_flag(TIF_IA32)) { | 388 | if (test_thread_flag(TIF_IA32)) { |
386 | if (ka->sa.sa_flags & SA_SIGINFO) | 389 | if (ka->sa.sa_flags & SA_SIGINFO) |
387 | ia32_setup_rt_frame(sig, ka, info, oldset, regs); | 390 | ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs); |
388 | else | 391 | else |
389 | ia32_setup_frame(sig, ka, oldset, regs); | 392 | ret = ia32_setup_frame(sig, ka, oldset, regs); |
390 | } else | 393 | } else |
391 | #endif | 394 | #endif |
392 | setup_rt_frame(sig, ka, info, oldset, regs); | 395 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
393 | 396 | ||
394 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 397 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { |
395 | spin_lock_irq(¤t->sighand->siglock); | 398 | spin_lock_irq(¤t->sighand->siglock); |
396 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 399 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
397 | sigaddset(¤t->blocked,sig); | 400 | sigaddset(¤t->blocked,sig); |
398 | recalc_sigpending(); | 401 | recalc_sigpending(); |
399 | spin_unlock_irq(¤t->sighand->siglock); | 402 | spin_unlock_irq(¤t->sighand->siglock); |
400 | } | 403 | } |
404 | |||
405 | return ret; | ||
401 | } | 406 | } |
402 | 407 | ||
403 | /* | 408 | /* |
@@ -437,8 +442,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
437 | asm volatile("movq %0,%%db7" : : "r" (current->thread.debugreg7)); | 442 | asm volatile("movq %0,%%db7" : : "r" (current->thread.debugreg7)); |
438 | 443 | ||
439 | /* Whee! Actually deliver the signal. */ | 444 | /* Whee! Actually deliver the signal. */ |
440 | handle_signal(signr, &info, &ka, oldset, regs); | 445 | return handle_signal(signr, &info, &ka, oldset, regs); |
441 | return 1; | ||
442 | } | 446 | } |
443 | 447 | ||
444 | no_signal: | 448 | no_signal: |