aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/signal.c
diff options
context:
space:
mode:
authorAnton Vorontsov <anton.vorontsov@linaro.org>2012-07-31 07:59:42 -0400
committerAnton Vorontsov <anton.vorontsov@linaro.org>2012-07-31 08:16:47 -0400
commite6db06a53b1dcf4e9da4aba143e2eb4d63418abb (patch)
tree10adcecb71c95ce4393c39fa7911d091bcadfe09 /arch/arm/kernel/signal.c
parentecc2edd56c49fa31a0a9ed15a7bf810ae79d3b85 (diff)
parentc56f5c0342dfee11a1a13d2f5bb7618de5b17590 (diff)
Merge with upstream to accommodate with thermal changes
This merge is performed to take commit c56f5c0342dfee11a1 ("Thermal: Make Thermal trip points writeable") out of Linus' tree and then fixup power supply class. This is needed since thermal stuff added a new argument: CC drivers/power/power_supply_core.o drivers/power/power_supply_core.c: In function ‘psy_register_thermal’: drivers/power/power_supply_core.c:204:6: warning: passing argument 3 of ‘thermal_zone_device_register’ makes integer from pointer without a cast [enabled by default] include/linux/thermal.h:154:29: note: expected ‘int’ but argument is of type ‘struct power_supply *’ drivers/power/power_supply_core.c:204:6: error: too few arguments to function ‘thermal_zone_device_register’ include/linux/thermal.h:154:29: note: declared here make[1]: *** [drivers/power/power_supply_core.o] Error 1 make: *** [drivers/power/] Error 2 Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Diffstat (limited to 'arch/arm/kernel/signal.c')
-rw-r--r--arch/arm/kernel/signal.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index fd2392a17ac1..536c5d6b340b 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -27,6 +27,7 @@
27 */ 27 */
28#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) 28#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
29#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) 29#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
30#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
30 31
31/* 32/*
32 * With EABI, the syscall number has to be loaded into r7. 33 * With EABI, the syscall number has to be loaded into r7.
@@ -47,6 +48,18 @@ const unsigned long sigreturn_codes[7] = {
47}; 48};
48 49
49/* 50/*
51 * Either we support OABI only, or we have EABI with the OABI
52 * compat layer enabled. In the later case we don't know if
53 * user space is EABI or not, and if not we must not clobber r7.
54 * Always using the OABI syscall solves that issue and works for
55 * all those cases.
56 */
57const unsigned long syscall_restart_code[2] = {
58 SWI_SYS_RESTART, /* swi __NR_restart_syscall */
59 0xe49df004, /* ldr pc, [sp], #4 */
60};
61
62/*
50 * atomically swap in the new signal mask, and wait for a signal. 63 * atomically swap in the new signal mask, and wait for a signal.
51 */ 64 */
52asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) 65asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
@@ -592,10 +605,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
592 case -ERESTARTNOHAND: 605 case -ERESTARTNOHAND:
593 case -ERESTARTSYS: 606 case -ERESTARTSYS:
594 case -ERESTARTNOINTR: 607 case -ERESTARTNOINTR:
595 case -ERESTART_RESTARTBLOCK:
596 regs->ARM_r0 = regs->ARM_ORIG_r0; 608 regs->ARM_r0 = regs->ARM_ORIG_r0;
597 regs->ARM_pc = restart_addr; 609 regs->ARM_pc = restart_addr;
598 break; 610 break;
611 case -ERESTART_RESTARTBLOCK:
612 regs->ARM_r0 = -EINTR;
613 break;
599 } 614 }
600 } 615 }
601 616
@@ -611,14 +626,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
611 * debugger has chosen to restart at a different PC. 626 * debugger has chosen to restart at a different PC.
612 */ 627 */
613 if (regs->ARM_pc == restart_addr) { 628 if (regs->ARM_pc == restart_addr) {
614 if (retval == -ERESTARTNOHAND || 629 if (retval == -ERESTARTNOHAND
615 retval == -ERESTART_RESTARTBLOCK
616 || (retval == -ERESTARTSYS 630 || (retval == -ERESTARTSYS
617 && !(ka.sa.sa_flags & SA_RESTART))) { 631 && !(ka.sa.sa_flags & SA_RESTART))) {
618 regs->ARM_r0 = -EINTR; 632 regs->ARM_r0 = -EINTR;
619 regs->ARM_pc = continue_addr; 633 regs->ARM_pc = continue_addr;
620 } 634 }
621 clear_thread_flag(TIF_SYSCALL_RESTARTSYS);
622 } 635 }
623 636
624 handle_signal(signr, &ka, &info, regs); 637 handle_signal(signr, &ka, &info, regs);
@@ -632,8 +645,29 @@ static void do_signal(struct pt_regs *regs, int syscall)
632 * ignore the restart. 645 * ignore the restart.
633 */ 646 */
634 if (retval == -ERESTART_RESTARTBLOCK 647 if (retval == -ERESTART_RESTARTBLOCK
635 && regs->ARM_pc == restart_addr) 648 && regs->ARM_pc == continue_addr) {
636 set_thread_flag(TIF_SYSCALL_RESTARTSYS); 649 if (thumb_mode(regs)) {
650 regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
651 regs->ARM_pc -= 2;
652 } else {
653#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
654 regs->ARM_r7 = __NR_restart_syscall;
655 regs->ARM_pc -= 4;
656#else
657 u32 __user *usp;
658
659 regs->ARM_sp -= 4;
660 usp = (u32 __user *)regs->ARM_sp;
661
662 if (put_user(regs->ARM_pc, usp) == 0) {
663 regs->ARM_pc = KERN_RESTART_CODE;
664 } else {
665 regs->ARM_sp += 4;
666 force_sigsegv(0, current);
667 }
668#endif
669 }
670 }
637 } 671 }
638 672
639 restore_saved_sigmask(); 673 restore_saved_sigmask();