Skip to content

Commit

Permalink
[PATCH] ARM: Move signal return code into vector page
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Russell King committed Jun 22, 2005
1 parent 0521621 commit e00d349
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 10 deletions.
29 changes: 19 additions & 10 deletions arch/arm/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <asm/unistd.h>

#include "ptrace.h"
#include "signal.h"

#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))

Expand All @@ -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
};
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 12 additions & 0 deletions arch/arm/kernel/signal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* linux/arch/arm/kernel/signal.h
*
* Copyright (C) 2005 Russell King.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#define KERN_SIGRETURN_CODE 0xffff0500

extern const unsigned long sigreturn_codes[4];
9 changes: 9 additions & 0 deletions arch/arm/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <asm/traps.h>

#include "ptrace.h"
#include "signal.h"

const char *processor_modes[]=
{ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
Expand Down Expand Up @@ -683,6 +684,14 @@ void __init trap_init(void)
memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);

/*
* Copy signal return handlers into the vector page, and
* set sigreturn to be a pointer to these.
*/
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
sizeof(sigreturn_codes));

flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
}

0 comments on commit e00d349

Please sign in to comment.