[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>
This commit is contained in:
parent
052162198b
commit
e00d349e77
|
@ -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));
|
||||
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;
|
||||
retcode = ((unsigned long)rc) + thumb;
|
||||
}
|
||||
}
|
||||
|
||||
regs->ARM_r0 = usig;
|
||||
|
|
|
@ -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];
|
|
@ -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" ,
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue