From e00d349e7781a92cf35b242259c9e5341a9661bb Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 22 Jun 2005 20:26:05 +0100 Subject: [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 --- arch/arm/kernel/signal.c | 29 +++++++++++++++++++---------- arch/arm/kernel/signal.h | 12 ++++++++++++ arch/arm/kernel/traps.c | 9 +++++++++ 3 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 arch/arm/kernel/signal.h (limited to 'arch/arm/kernel') 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 #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; 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 @@ +/* + * 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]; 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 @@ #include #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); } -- cgit v1.2.2 From 3a66941106855215127f8bf1afd06099b72dc75b Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 22 Jun 2005 21:43:10 +0100 Subject: [PATCH] ARM: Ensure memory information is page aligned Ensure that meminfo.bank[] array contains page-aligned start/size information. Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 9fed5fa194d9..8cf733daa800 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -395,6 +395,20 @@ static void __init early_initrd(char **p) } __early_param("initrd=", early_initrd); +static void __init add_memory(unsigned long start, unsigned long size) +{ + /* + * Ensure that start/size are aligned to a page boundary. + * Size is appropriately rounded down, start is rounded up. + */ + size -= start & ~PAGE_MASK; + + meminfo.bank[meminfo.nr_banks].start = PAGE_ALIGN(start); + meminfo.bank[meminfo.nr_banks].size = size & PAGE_MASK; + meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start); + meminfo.nr_banks += 1; +} + /* * Pick out the memory size. We look for mem=size@start, * where start and size are "size[KkMm]" @@ -419,10 +433,7 @@ static void __init early_mem(char **p) if (**p == '@') start = memparse(*p + 1, p); - meminfo.bank[meminfo.nr_banks].start = start; - meminfo.bank[meminfo.nr_banks].size = size; - meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start); - meminfo.nr_banks += 1; + add_memory(start, size); } __early_param("mem=", early_mem); @@ -564,11 +575,7 @@ static int __init parse_tag_mem32(const struct tag *tag) tag->u.mem.start, tag->u.mem.size / 1024); return -EINVAL; } - meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start; - meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size; - meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start); - meminfo.nr_banks += 1; - + add_memory(tag->u.mem.start, tag->u.mem.size); return 0; } -- cgit v1.2.2