summaryrefslogtreecommitdiff
path: root/arch/arm/kernel/signal.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-06-22 23:26:05 +0400
committerRussell King <rmk@dyn-67.arm.linux.org.uk>2005-06-22 23:26:05 +0400
commite00d349e7781a92cf35b242259c9e5341a9661bb (patch)
treecd7e9d10adb8bc3b18c20c3d925c64b4c6f3f3b0 /arch/arm/kernel/signal.c
parent052162198b89e64d37c20238412674152d614997 (diff)
downloadlinux-e00d349e7781a92cf35b242259c9e5341a9661bb.tar.xz
[PATCH] ARM: Move signal return code into vector page
Move the signal return code into the vector page instead of placing it on the user mode stack, which will allow us to avoid flushing the instruction cache on signals, as well as eventually allowing non-exec stack. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/signal.c')
-rw-r--r--arch/arm/kernel/signal.c29
1 files changed, 19 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 @@
#include <asm/unistd.h>
#include "ptrace.h"
+#include "signal.h"
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -35,7 +36,7 @@
#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
-static const unsigned long retcodes[4] = {
+const unsigned long sigreturn_codes[4] = {
SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
};
@@ -500,17 +501,25 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
if (ka->sa.sa_flags & SA_SIGINFO)
idx += 2;
- if (__put_user(retcodes[idx], rc))
+ if (__put_user(sigreturn_codes[idx], rc))
return 1;
- /*
- * Ensure that the instruction cache sees
- * the return code written onto the stack.
- */
- flush_icache_range((unsigned long)rc,
- (unsigned long)(rc + 1));
-
- retcode = ((unsigned long)rc) + thumb;
+ if (cpsr & MODE32_BIT) {
+ /*
+ * 32-bit code can use the new high-page
+ * signal return code support.
+ */
+ retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
+ } else {
+ /*
+ * Ensure that the instruction cache sees
+ * the return code written onto the stack.
+ */
+ flush_icache_range((unsigned long)rc,
+ (unsigned long)(rc + 1));
+
+ retcode = ((unsigned long)rc) + thumb;
+ }
}
regs->ARM_r0 = usig;