diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/kernel/signal.c | 29 | ||||
-rw-r--r-- | arch/arm/kernel/signal.h | 12 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 9 |
3 files changed, 40 insertions, 10 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 931919fd5121..07ddeed61766 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/unistd.h> | 19 | #include <asm/unistd.h> |
20 | 20 | ||
21 | #include "ptrace.h" | 21 | #include "ptrace.h" |
22 | #include "signal.h" | ||
22 | 23 | ||
23 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 24 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
24 | 25 | ||
@@ -35,7 +36,7 @@ | |||
35 | #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) | 36 | #define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) |
36 | #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) | 37 | #define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) |
37 | 38 | ||
38 | static const unsigned long retcodes[4] = { | 39 | const unsigned long sigreturn_codes[4] = { |
39 | SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, | 40 | SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, |
40 | SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN | 41 | SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN |
41 | }; | 42 | }; |
@@ -500,17 +501,25 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka, | |||
500 | if (ka->sa.sa_flags & SA_SIGINFO) | 501 | if (ka->sa.sa_flags & SA_SIGINFO) |
501 | idx += 2; | 502 | idx += 2; |
502 | 503 | ||
503 | if (__put_user(retcodes[idx], rc)) | 504 | if (__put_user(sigreturn_codes[idx], rc)) |
504 | return 1; | 505 | return 1; |
505 | 506 | ||
506 | /* | 507 | if (cpsr & MODE32_BIT) { |
507 | * Ensure that the instruction cache sees | 508 | /* |
508 | * the return code written onto the stack. | 509 | * 32-bit code can use the new high-page |
509 | */ | 510 | * signal return code support. |
510 | flush_icache_range((unsigned long)rc, | 511 | */ |
511 | (unsigned long)(rc + 1)); | 512 | retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb; |
512 | 513 | } else { | |
513 | retcode = ((unsigned long)rc) + thumb; | 514 | /* |
515 | * Ensure that the instruction cache sees | ||
516 | * the return code written onto the stack. | ||
517 | */ | ||
518 | flush_icache_range((unsigned long)rc, | ||
519 | (unsigned long)(rc + 1)); | ||
520 | |||
521 | retcode = ((unsigned long)rc) + thumb; | ||
522 | } | ||
514 | } | 523 | } |
515 | 524 | ||
516 | regs->ARM_r0 = usig; | 525 | regs->ARM_r0 = usig; |
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h new file mode 100644 index 000000000000..91d26faca62b --- /dev/null +++ b/arch/arm/kernel/signal.h | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/kernel/signal.h | ||
3 | * | ||
4 | * Copyright (C) 2005 Russell King. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #define KERN_SIGRETURN_CODE 0xffff0500 | ||
11 | |||
12 | extern const unsigned long sigreturn_codes[4]; | ||
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 45d2a032d890..2fb0a4cfb37a 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/traps.h> | 30 | #include <asm/traps.h> |
31 | 31 | ||
32 | #include "ptrace.h" | 32 | #include "ptrace.h" |
33 | #include "signal.h" | ||
33 | 34 | ||
34 | const char *processor_modes[]= | 35 | const char *processor_modes[]= |
35 | { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , | 36 | { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , |
@@ -683,6 +684,14 @@ void __init trap_init(void) | |||
683 | memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); | 684 | memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); |
684 | memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); | 685 | memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); |
685 | memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); | 686 | memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); |
687 | |||
688 | /* | ||
689 | * Copy signal return handlers into the vector page, and | ||
690 | * set sigreturn to be a pointer to these. | ||
691 | */ | ||
692 | memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, | ||
693 | sizeof(sigreturn_codes)); | ||
694 | |||
686 | flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); | 695 | flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); |
687 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); | 696 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); |
688 | } | 697 | } |