diff options
Diffstat (limited to 'arch/arm/kernel/traps.c')
-rw-r--r-- | arch/arm/kernel/traps.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 45d2a032d890..d571c37ac30c 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" , |
@@ -229,16 +230,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) | |||
229 | do_exit(SIGSEGV); | 230 | do_exit(SIGSEGV); |
230 | } | 231 | } |
231 | 232 | ||
232 | void die_if_kernel(const char *str, struct pt_regs *regs, int err) | 233 | void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, |
233 | { | 234 | unsigned long err, unsigned long trap) |
234 | if (user_mode(regs)) | ||
235 | return; | ||
236 | |||
237 | die(str, regs, err); | ||
238 | } | ||
239 | |||
240 | static void notify_die(const char *str, struct pt_regs *regs, siginfo_t *info, | ||
241 | unsigned long err, unsigned long trap) | ||
242 | { | 235 | { |
243 | if (user_mode(regs)) { | 236 | if (user_mode(regs)) { |
244 | current->thread.error_code = err; | 237 | current->thread.error_code = err; |
@@ -255,16 +248,20 @@ static DEFINE_SPINLOCK(undef_lock); | |||
255 | 248 | ||
256 | void register_undef_hook(struct undef_hook *hook) | 249 | void register_undef_hook(struct undef_hook *hook) |
257 | { | 250 | { |
258 | spin_lock_irq(&undef_lock); | 251 | unsigned long flags; |
252 | |||
253 | spin_lock_irqsave(&undef_lock, flags); | ||
259 | list_add(&hook->node, &undef_hook); | 254 | list_add(&hook->node, &undef_hook); |
260 | spin_unlock_irq(&undef_lock); | 255 | spin_unlock_irqrestore(&undef_lock, flags); |
261 | } | 256 | } |
262 | 257 | ||
263 | void unregister_undef_hook(struct undef_hook *hook) | 258 | void unregister_undef_hook(struct undef_hook *hook) |
264 | { | 259 | { |
265 | spin_lock_irq(&undef_lock); | 260 | unsigned long flags; |
261 | |||
262 | spin_lock_irqsave(&undef_lock, flags); | ||
266 | list_del(&hook->node); | 263 | list_del(&hook->node); |
267 | spin_unlock_irq(&undef_lock); | 264 | spin_unlock_irqrestore(&undef_lock, flags); |
268 | } | 265 | } |
269 | 266 | ||
270 | asmlinkage void do_undefinstr(struct pt_regs *regs) | 267 | asmlinkage void do_undefinstr(struct pt_regs *regs) |
@@ -683,6 +680,14 @@ void __init trap_init(void) | |||
683 | memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); | 680 | memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); |
684 | memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); | 681 | memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); |
685 | memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); | 682 | memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); |
683 | |||
684 | /* | ||
685 | * Copy signal return handlers into the vector page, and | ||
686 | * set sigreturn to be a pointer to these. | ||
687 | */ | ||
688 | memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, | ||
689 | sizeof(sigreturn_codes)); | ||
690 | |||
686 | flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); | 691 | flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); |
687 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); | 692 | modify_domain(DOMAIN_USER, DOMAIN_CLIENT); |
688 | } | 693 | } |