diff options
Diffstat (limited to 'arch/arm/kernel')
| -rw-r--r-- | arch/arm/kernel/Makefile | 4 | ||||
| -rw-r--r-- | arch/arm/kernel/calls.S | 10 | ||||
| -rw-r--r-- | arch/arm/kernel/crunch.c | 13 | ||||
| -rw-r--r-- | arch/arm/kernel/entry-common.S | 10 | ||||
| -rw-r--r-- | arch/arm/kernel/irq.c | 24 | ||||
| -rw-r--r-- | arch/arm/kernel/return_address.c | 71 | ||||
| -rw-r--r-- | arch/arm/kernel/signal.c | 86 | ||||
| -rw-r--r-- | arch/arm/kernel/stacktrace.c | 4 | ||||
| -rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 15 |
9 files changed, 141 insertions, 96 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index ff89d0b3abc5..3213c9382b17 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
| @@ -8,10 +8,12 @@ ifdef CONFIG_DYNAMIC_FTRACE | |||
| 8 | CFLAGS_REMOVE_ftrace.o = -pg | 8 | CFLAGS_REMOVE_ftrace.o = -pg |
| 9 | endif | 9 | endif |
| 10 | 10 | ||
| 11 | CFLAGS_REMOVE_return_address.o = -pg | ||
| 12 | |||
| 11 | # Object file lists. | 13 | # Object file lists. |
| 12 | 14 | ||
| 13 | obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \ | 15 | obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \ |
| 14 | process.o ptrace.o setup.o signal.o \ | 16 | process.o ptrace.o return_address.o setup.o signal.o \ |
| 15 | sys_arm.o stacktrace.o time.o traps.o | 17 | sys_arm.o stacktrace.o time.o traps.o |
| 16 | 18 | ||
| 17 | obj-$(CONFIG_ISA_DMA_API) += dma.o | 19 | obj-$(CONFIG_ISA_DMA_API) += dma.o |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index f776e72a4cb8..ecfa98954d1d 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
| @@ -81,7 +81,7 @@ | |||
| 81 | CALL(sys_ni_syscall) /* was sys_ssetmask */ | 81 | CALL(sys_ni_syscall) /* was sys_ssetmask */ |
| 82 | /* 70 */ CALL(sys_setreuid16) | 82 | /* 70 */ CALL(sys_setreuid16) |
| 83 | CALL(sys_setregid16) | 83 | CALL(sys_setregid16) |
| 84 | CALL(sys_sigsuspend_wrapper) | 84 | CALL(sys_sigsuspend) |
| 85 | CALL(sys_sigpending) | 85 | CALL(sys_sigpending) |
| 86 | CALL(sys_sethostname) | 86 | CALL(sys_sethostname) |
| 87 | /* 75 */ CALL(sys_setrlimit) | 87 | /* 75 */ CALL(sys_setrlimit) |
| @@ -188,7 +188,7 @@ | |||
| 188 | CALL(sys_rt_sigpending) | 188 | CALL(sys_rt_sigpending) |
| 189 | CALL(sys_rt_sigtimedwait) | 189 | CALL(sys_rt_sigtimedwait) |
| 190 | CALL(sys_rt_sigqueueinfo) | 190 | CALL(sys_rt_sigqueueinfo) |
| 191 | CALL(sys_rt_sigsuspend_wrapper) | 191 | CALL(sys_rt_sigsuspend) |
| 192 | /* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) | 192 | /* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) |
| 193 | CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) | 193 | CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) |
| 194 | CALL(sys_chown16) | 194 | CALL(sys_chown16) |
| @@ -344,8 +344,8 @@ | |||
| 344 | CALL(sys_readlinkat) | 344 | CALL(sys_readlinkat) |
| 345 | CALL(sys_fchmodat) | 345 | CALL(sys_fchmodat) |
| 346 | CALL(sys_faccessat) | 346 | CALL(sys_faccessat) |
| 347 | /* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ | 347 | /* 335 */ CALL(sys_pselect6) |
| 348 | CALL(sys_ni_syscall) /* eventually ppoll */ | 348 | CALL(sys_ppoll) |
| 349 | CALL(sys_unshare) | 349 | CALL(sys_unshare) |
| 350 | CALL(sys_set_robust_list) | 350 | CALL(sys_set_robust_list) |
| 351 | CALL(sys_get_robust_list) | 351 | CALL(sys_get_robust_list) |
| @@ -355,7 +355,7 @@ | |||
| 355 | CALL(sys_vmsplice) | 355 | CALL(sys_vmsplice) |
| 356 | CALL(sys_move_pages) | 356 | CALL(sys_move_pages) |
| 357 | /* 345 */ CALL(sys_getcpu) | 357 | /* 345 */ CALL(sys_getcpu) |
| 358 | CALL(sys_ni_syscall) /* eventually epoll_pwait */ | 358 | CALL(sys_epoll_pwait) |
| 359 | CALL(sys_kexec_load) | 359 | CALL(sys_kexec_load) |
| 360 | CALL(sys_utimensat) | 360 | CALL(sys_utimensat) |
| 361 | CALL(sys_signalfd) | 361 | CALL(sys_signalfd) |
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c index 99995c2b2312..769abe15cf91 100644 --- a/arch/arm/kernel/crunch.c +++ b/arch/arm/kernel/crunch.c | |||
| @@ -31,7 +31,7 @@ void crunch_task_release(struct thread_info *thread) | |||
| 31 | 31 | ||
| 32 | static int crunch_enabled(u32 devcfg) | 32 | static int crunch_enabled(u32 devcfg) |
| 33 | { | 33 | { |
| 34 | return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); | 34 | return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) | 37 | static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) |
| @@ -56,11 +56,16 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) | |||
| 56 | break; | 56 | break; |
| 57 | 57 | ||
| 58 | case THREAD_NOTIFY_SWITCH: | 58 | case THREAD_NOTIFY_SWITCH: |
| 59 | devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); | 59 | devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG); |
| 60 | if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { | 60 | if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { |
| 61 | devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; | 61 | /* |
| 62 | * We don't use ep93xx_syscon_swlocked_write() here | ||
| 63 | * because we are on the context switch path and | ||
| 64 | * preemption is already disabled. | ||
| 65 | */ | ||
| 66 | devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA; | ||
| 62 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 67 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); |
| 63 | __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); | 68 | __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG); |
| 64 | } | 69 | } |
| 65 | break; | 70 | break; |
| 66 | } | 71 | } |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 366e5097a41a..bfa7f0af7ede 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
| @@ -373,16 +373,6 @@ sys_clone_wrapper: | |||
| 373 | b sys_clone | 373 | b sys_clone |
| 374 | ENDPROC(sys_clone_wrapper) | 374 | ENDPROC(sys_clone_wrapper) |
| 375 | 375 | ||
| 376 | sys_sigsuspend_wrapper: | ||
| 377 | add r3, sp, #S_OFF | ||
| 378 | b sys_sigsuspend | ||
| 379 | ENDPROC(sys_sigsuspend_wrapper) | ||
| 380 | |||
| 381 | sys_rt_sigsuspend_wrapper: | ||
| 382 | add r2, sp, #S_OFF | ||
| 383 | b sys_rt_sigsuspend | ||
| 384 | ENDPROC(sys_rt_sigsuspend_wrapper) | ||
| 385 | |||
| 386 | sys_sigreturn_wrapper: | 376 | sys_sigreturn_wrapper: |
| 387 | add r0, sp, #S_OFF | 377 | add r0, sp, #S_OFF |
| 388 | b sys_sigreturn | 378 | b sys_sigreturn |
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 096f600dc8d8..b7c3490eaa24 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
| @@ -98,17 +98,6 @@ unlock: | |||
| 98 | return 0; | 98 | return 0; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | /* Handle bad interrupts */ | ||
| 102 | static struct irq_desc bad_irq_desc = { | ||
| 103 | .handle_irq = handle_bad_irq, | ||
| 104 | .lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock), | ||
| 105 | }; | ||
| 106 | |||
| 107 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
| 108 | /* We are not allocating bad_irq_desc.affinity or .pending_mask */ | ||
| 109 | #error "ARM architecture does not support CONFIG_CPUMASK_OFFSTACK." | ||
| 110 | #endif | ||
| 111 | |||
| 112 | /* | 101 | /* |
| 113 | * do_IRQ handles all hardware IRQ's. Decoded IRQs should not | 102 | * do_IRQ handles all hardware IRQ's. Decoded IRQs should not |
| 114 | * come via this function. Instead, they should provide their | 103 | * come via this function. Instead, they should provide their |
| @@ -124,10 +113,13 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
| 124 | * Some hardware gives randomly wrong interrupts. Rather | 113 | * Some hardware gives randomly wrong interrupts. Rather |
| 125 | * than crashing, do something sensible. | 114 | * than crashing, do something sensible. |
| 126 | */ | 115 | */ |
| 127 | if (irq >= NR_IRQS) | 116 | if (unlikely(irq >= NR_IRQS)) { |
| 128 | handle_bad_irq(irq, &bad_irq_desc); | 117 | if (printk_ratelimit()) |
| 129 | else | 118 | printk(KERN_WARNING "Bad IRQ%u\n", irq); |
| 119 | ack_bad_irq(irq); | ||
| 120 | } else { | ||
| 130 | generic_handle_irq(irq); | 121 | generic_handle_irq(irq); |
| 122 | } | ||
| 131 | 123 | ||
| 132 | /* AT91 specific workaround */ | 124 | /* AT91 specific workaround */ |
| 133 | irq_finish(irq); | 125 | irq_finish(irq); |
| @@ -165,10 +157,6 @@ void __init init_IRQ(void) | |||
| 165 | for (irq = 0; irq < NR_IRQS; irq++) | 157 | for (irq = 0; irq < NR_IRQS; irq++) |
| 166 | irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE; | 158 | irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE; |
| 167 | 159 | ||
| 168 | #ifdef CONFIG_SMP | ||
| 169 | cpumask_setall(bad_irq_desc.affinity); | ||
| 170 | bad_irq_desc.node = smp_processor_id(); | ||
| 171 | #endif | ||
| 172 | init_arch_irq(); | 160 | init_arch_irq(); |
| 173 | } | 161 | } |
| 174 | 162 | ||
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c new file mode 100644 index 000000000000..df246da4ceca --- /dev/null +++ b/arch/arm/kernel/return_address.c | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/kernel/return_address.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> | ||
| 5 | * for Pengutronix | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License version 2 as published by | ||
| 9 | * the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #include <linux/module.h> | ||
| 12 | |||
| 13 | #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) | ||
| 14 | #include <linux/sched.h> | ||
| 15 | |||
| 16 | #include <asm/stacktrace.h> | ||
| 17 | |||
| 18 | struct return_address_data { | ||
| 19 | unsigned int level; | ||
| 20 | void *addr; | ||
| 21 | }; | ||
| 22 | |||
| 23 | static int save_return_addr(struct stackframe *frame, void *d) | ||
| 24 | { | ||
| 25 | struct return_address_data *data = d; | ||
| 26 | |||
| 27 | if (!data->level) { | ||
| 28 | data->addr = (void *)frame->lr; | ||
| 29 | |||
| 30 | return 1; | ||
| 31 | } else { | ||
| 32 | --data->level; | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | void *return_address(unsigned int level) | ||
| 38 | { | ||
| 39 | struct return_address_data data; | ||
| 40 | struct stackframe frame; | ||
| 41 | register unsigned long current_sp asm ("sp"); | ||
| 42 | |||
| 43 | data.level = level + 1; | ||
| 44 | |||
| 45 | frame.fp = (unsigned long)__builtin_frame_address(0); | ||
| 46 | frame.sp = current_sp; | ||
| 47 | frame.lr = (unsigned long)__builtin_return_address(0); | ||
| 48 | frame.pc = (unsigned long)return_address; | ||
| 49 | |||
| 50 | walk_stackframe(&frame, save_return_addr, &data); | ||
| 51 | |||
| 52 | if (!data.level) | ||
| 53 | return data.addr; | ||
| 54 | else | ||
| 55 | return NULL; | ||
| 56 | } | ||
| 57 | |||
| 58 | #else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */ | ||
| 59 | |||
| 60 | #if defined(CONFIG_ARM_UNWIND) | ||
| 61 | #warning "TODO: return_address should use unwind tables" | ||
| 62 | #endif | ||
| 63 | |||
| 64 | void *return_address(unsigned int level) | ||
| 65 | { | ||
| 66 | return NULL; | ||
| 67 | } | ||
| 68 | |||
| 69 | #endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */ | ||
| 70 | |||
| 71 | EXPORT_SYMBOL_GPL(return_address); | ||
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 93bb4247b7ed..e27ee1f701d5 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
| @@ -47,57 +47,22 @@ const unsigned long sigreturn_codes[7] = { | |||
| 47 | MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, | 47 | MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); | ||
| 51 | |||
| 52 | /* | 50 | /* |
| 53 | * atomically swap in the new signal mask, and wait for a signal. | 51 | * atomically swap in the new signal mask, and wait for a signal. |
| 54 | */ | 52 | */ |
| 55 | asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) | 53 | asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) |
| 56 | { | 54 | { |
| 57 | sigset_t saveset; | ||
| 58 | |||
| 59 | mask &= _BLOCKABLE; | 55 | mask &= _BLOCKABLE; |
| 60 | spin_lock_irq(¤t->sighand->siglock); | 56 | spin_lock_irq(¤t->sighand->siglock); |
| 61 | saveset = current->blocked; | 57 | current->saved_sigmask = current->blocked; |
| 62 | siginitset(¤t->blocked, mask); | 58 | siginitset(¤t->blocked, mask); |
| 63 | recalc_sigpending(); | 59 | recalc_sigpending(); |
| 64 | spin_unlock_irq(¤t->sighand->siglock); | 60 | spin_unlock_irq(¤t->sighand->siglock); |
| 65 | regs->ARM_r0 = -EINTR; | ||
| 66 | |||
| 67 | while (1) { | ||
| 68 | current->state = TASK_INTERRUPTIBLE; | ||
| 69 | schedule(); | ||
| 70 | if (do_signal(&saveset, regs, 0)) | ||
| 71 | return regs->ARM_r0; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | asmlinkage int | ||
| 76 | sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) | ||
| 77 | { | ||
| 78 | sigset_t saveset, newset; | ||
| 79 | |||
| 80 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
| 81 | if (sigsetsize != sizeof(sigset_t)) | ||
| 82 | return -EINVAL; | ||
| 83 | |||
| 84 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
| 85 | return -EFAULT; | ||
| 86 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
| 87 | |||
| 88 | spin_lock_irq(¤t->sighand->siglock); | ||
| 89 | saveset = current->blocked; | ||
| 90 | current->blocked = newset; | ||
| 91 | recalc_sigpending(); | ||
| 92 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 93 | regs->ARM_r0 = -EINTR; | ||
| 94 | 61 | ||
| 95 | while (1) { | 62 | current->state = TASK_INTERRUPTIBLE; |
| 96 | current->state = TASK_INTERRUPTIBLE; | 63 | schedule(); |
| 97 | schedule(); | 64 | set_restore_sigmask(); |
| 98 | if (do_signal(&saveset, regs, 0)) | 65 | return -ERESTARTNOHAND; |
| 99 | return regs->ARM_r0; | ||
| 100 | } | ||
| 101 | } | 66 | } |
| 102 | 67 | ||
| 103 | asmlinkage int | 68 | asmlinkage int |
| @@ -545,7 +510,7 @@ static inline void setup_syscall_restart(struct pt_regs *regs) | |||
| 545 | /* | 510 | /* |
| 546 | * OK, we're invoking a handler | 511 | * OK, we're invoking a handler |
| 547 | */ | 512 | */ |
| 548 | static void | 513 | static int |
| 549 | handle_signal(unsigned long sig, struct k_sigaction *ka, | 514 | handle_signal(unsigned long sig, struct k_sigaction *ka, |
| 550 | siginfo_t *info, sigset_t *oldset, | 515 | siginfo_t *info, sigset_t *oldset, |
| 551 | struct pt_regs * regs, int syscall) | 516 | struct pt_regs * regs, int syscall) |
| @@ -596,7 +561,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
| 596 | 561 | ||
| 597 | if (ret != 0) { | 562 | if (ret != 0) { |
| 598 | force_sigsegv(sig, tsk); | 563 | force_sigsegv(sig, tsk); |
| 599 | return; | 564 | return ret; |
| 600 | } | 565 | } |
| 601 | 566 | ||
| 602 | /* | 567 | /* |
| @@ -610,6 +575,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
| 610 | recalc_sigpending(); | 575 | recalc_sigpending(); |
| 611 | spin_unlock_irq(&tsk->sighand->siglock); | 576 | spin_unlock_irq(&tsk->sighand->siglock); |
| 612 | 577 | ||
| 578 | return 0; | ||
| 613 | } | 579 | } |
| 614 | 580 | ||
| 615 | /* | 581 | /* |
| @@ -621,7 +587,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
| 621 | * the kernel can handle, and then we build all the user-level signal handling | 587 | * the kernel can handle, and then we build all the user-level signal handling |
| 622 | * stack-frames in one go after that. | 588 | * stack-frames in one go after that. |
| 623 | */ | 589 | */ |
| 624 | static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) | 590 | static void do_signal(struct pt_regs *regs, int syscall) |
| 625 | { | 591 | { |
| 626 | struct k_sigaction ka; | 592 | struct k_sigaction ka; |
| 627 | siginfo_t info; | 593 | siginfo_t info; |
| @@ -634,7 +600,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) | |||
| 634 | * if so. | 600 | * if so. |
| 635 | */ | 601 | */ |
| 636 | if (!user_mode(regs)) | 602 | if (!user_mode(regs)) |
| 637 | return 0; | 603 | return; |
| 638 | 604 | ||
| 639 | if (try_to_freeze()) | 605 | if (try_to_freeze()) |
| 640 | goto no_signal; | 606 | goto no_signal; |
| @@ -643,9 +609,24 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) | |||
| 643 | 609 | ||
| 644 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 610 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
| 645 | if (signr > 0) { | 611 | if (signr > 0) { |
| 646 | handle_signal(signr, &ka, &info, oldset, regs, syscall); | 612 | sigset_t *oldset; |
| 613 | |||
| 614 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 615 | oldset = ¤t->saved_sigmask; | ||
| 616 | else | ||
| 617 | oldset = ¤t->blocked; | ||
| 618 | if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) { | ||
| 619 | /* | ||
| 620 | * A signal was successfully delivered; the saved | ||
| 621 | * sigmask will have been stored in the signal frame, | ||
| 622 | * and will be restored by sigreturn, so we can simply | ||
| 623 | * clear the TIF_RESTORE_SIGMASK flag. | ||
| 624 | */ | ||
| 625 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 626 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 627 | } | ||
| 647 | single_step_set(current); | 628 | single_step_set(current); |
| 648 | return 1; | 629 | return; |
| 649 | } | 630 | } |
| 650 | 631 | ||
| 651 | no_signal: | 632 | no_signal: |
| @@ -697,14 +678,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) | |||
| 697 | regs->ARM_r0 == -ERESTARTNOINTR) { | 678 | regs->ARM_r0 == -ERESTARTNOINTR) { |
| 698 | setup_syscall_restart(regs); | 679 | setup_syscall_restart(regs); |
| 699 | } | 680 | } |
| 681 | |||
| 682 | /* If there's no signal to deliver, we just put the saved sigmask | ||
| 683 | * back. | ||
| 684 | */ | ||
| 685 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
| 686 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 687 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
| 688 | } | ||
| 700 | } | 689 | } |
| 701 | single_step_set(current); | 690 | single_step_set(current); |
| 702 | return 0; | ||
| 703 | } | 691 | } |
| 704 | 692 | ||
| 705 | asmlinkage void | 693 | asmlinkage void |
| 706 | do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) | 694 | do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) |
| 707 | { | 695 | { |
| 708 | if (thread_flags & _TIF_SIGPENDING) | 696 | if (thread_flags & _TIF_SIGPENDING) |
| 709 | do_signal(¤t->blocked, regs, syscall); | 697 | do_signal(regs, syscall); |
| 710 | } | 698 | } |
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 9f444e5cc165..20b7411e47fd 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | * Note that with framepointer enabled, even the leaf functions have the same | 21 | * Note that with framepointer enabled, even the leaf functions have the same |
| 22 | * prologue and epilogue, therefore we can ignore the LR value in this case. | 22 | * prologue and epilogue, therefore we can ignore the LR value in this case. |
| 23 | */ | 23 | */ |
| 24 | int unwind_frame(struct stackframe *frame) | 24 | int notrace unwind_frame(struct stackframe *frame) |
| 25 | { | 25 | { |
| 26 | unsigned long high, low; | 26 | unsigned long high, low; |
| 27 | unsigned long fp = frame->fp; | 27 | unsigned long fp = frame->fp; |
| @@ -43,7 +43,7 @@ int unwind_frame(struct stackframe *frame) | |||
| 43 | } | 43 | } |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | void walk_stackframe(struct stackframe *frame, | 46 | void notrace walk_stackframe(struct stackframe *frame, |
| 47 | int (*fn)(struct stackframe *, void *), void *data) | 47 | int (*fn)(struct stackframe *, void *), void *data) |
| 48 | { | 48 | { |
| 49 | while (1) { | 49 | while (1) { |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 4340bf3d2c84..69371028a202 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <asm-generic/vmlinux.lds.h> | 6 | #include <asm-generic/vmlinux.lds.h> |
| 7 | #include <asm/thread_info.h> | 7 | #include <asm/thread_info.h> |
| 8 | #include <asm/memory.h> | 8 | #include <asm/memory.h> |
| 9 | #include <asm/page.h> | ||
| 9 | 10 | ||
| 10 | OUTPUT_ARCH(arm) | 11 | OUTPUT_ARCH(arm) |
| 11 | ENTRY(stext) | 12 | ENTRY(stext) |
| @@ -63,7 +64,7 @@ SECTIONS | |||
| 63 | usr/built-in.o(.init.ramfs) | 64 | usr/built-in.o(.init.ramfs) |
| 64 | __initramfs_end = .; | 65 | __initramfs_end = .; |
| 65 | #endif | 66 | #endif |
| 66 | . = ALIGN(4096); | 67 | . = ALIGN(PAGE_SIZE); |
| 67 | __per_cpu_load = .; | 68 | __per_cpu_load = .; |
| 68 | __per_cpu_start = .; | 69 | __per_cpu_start = .; |
| 69 | *(.data.percpu.page_aligned) | 70 | *(.data.percpu.page_aligned) |
| @@ -73,7 +74,7 @@ SECTIONS | |||
| 73 | #ifndef CONFIG_XIP_KERNEL | 74 | #ifndef CONFIG_XIP_KERNEL |
| 74 | __init_begin = _stext; | 75 | __init_begin = _stext; |
| 75 | INIT_DATA | 76 | INIT_DATA |
| 76 | . = ALIGN(4096); | 77 | . = ALIGN(PAGE_SIZE); |
| 77 | __init_end = .; | 78 | __init_end = .; |
| 78 | #endif | 79 | #endif |
| 79 | } | 80 | } |
| @@ -118,7 +119,7 @@ SECTIONS | |||
| 118 | *(.got) /* Global offset table */ | 119 | *(.got) /* Global offset table */ |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | RODATA | 122 | RO_DATA(PAGE_SIZE) |
| 122 | 123 | ||
| 123 | _etext = .; /* End of text and rodata section */ | 124 | _etext = .; /* End of text and rodata section */ |
| 124 | 125 | ||
| @@ -158,17 +159,17 @@ SECTIONS | |||
| 158 | *(.data.init_task) | 159 | *(.data.init_task) |
| 159 | 160 | ||
| 160 | #ifdef CONFIG_XIP_KERNEL | 161 | #ifdef CONFIG_XIP_KERNEL |
| 161 | . = ALIGN(4096); | 162 | . = ALIGN(PAGE_SIZE); |
| 162 | __init_begin = .; | 163 | __init_begin = .; |
| 163 | INIT_DATA | 164 | INIT_DATA |
| 164 | . = ALIGN(4096); | 165 | . = ALIGN(PAGE_SIZE); |
| 165 | __init_end = .; | 166 | __init_end = .; |
| 166 | #endif | 167 | #endif |
| 167 | 168 | ||
| 168 | . = ALIGN(4096); | 169 | . = ALIGN(PAGE_SIZE); |
| 169 | __nosave_begin = .; | 170 | __nosave_begin = .; |
| 170 | *(.data.nosave) | 171 | *(.data.nosave) |
| 171 | . = ALIGN(4096); | 172 | . = ALIGN(PAGE_SIZE); |
| 172 | __nosave_end = .; | 173 | __nosave_end = .; |
| 173 | 174 | ||
| 174 | /* | 175 | /* |
