Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm

Pull arm updates from Russell King:
"This contains both some fixes found when trying to get the
Assabet+neponset setup as a replacement firewall with a 3c589 PCMCIA
card, and a bunch of changes from Al to fix up the ARM signal
handling, particularly some of the restart behaviour."

* 'for-linus' of git://git.linaro.org/people/rmk/linux-arm:
ARM: neponset: make sure neponset_ncr_frob() is exported
ARM: fix out[bwl]()
arm: don't open-code ptrace_report_syscall()
arm: bury unused _TIF_RESTORE_SIGMASK
arm: remove unused restart trampoline
arm: new way of handling ERESTART_RESTARTBLOCK
arm: if we get into work_pending while returning to kernel mode, just go away
arm: don't call try_to_freeze() from do_signal()
arm: if there's no handler we need to restore sigmask, syscall or no syscall
arm: trim _TIF_WORK_MASK, get rid of useless test and branch...
arm: missing checks of __get_user()/__put_user() return values

+44 -89
+11 -13
arch/arm/include/asm/io.h
··· 47 47 extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); 48 48 extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); 49 49 50 - #define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)) 51 - #define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)) 52 - #define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)) 50 + #define __raw_writeb(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))) 51 + #define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))) 52 + #define __raw_writel(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))) 53 53 54 54 #define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a)) 55 55 #define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) ··· 229 229 #define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \ 230 230 __raw_readl(c)); __r; }) 231 231 232 - #define writeb_relaxed(v,c) ((void)__raw_writeb(v,c)) 233 - #define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \ 234 - cpu_to_le16(v),c)) 235 - #define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ 236 - cpu_to_le32(v),c)) 232 + #define writeb_relaxed(v,c) __raw_writeb(v,c) 233 + #define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c) 234 + #define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c) 237 235 238 236 #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) 239 237 #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) ··· 279 281 #define ioread16be(p) ({ unsigned int __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; }) 280 282 #define ioread32be(p) ({ unsigned int __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; }) 281 283 282 - #define iowrite8(v,p) ({ __iowmb(); (void)__raw_writeb(v, p); }) 283 - #define iowrite16(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_le16(v), p); }) 284 - #define iowrite32(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_le32(v), p); }) 284 + #define iowrite8(v,p) ({ __iowmb(); __raw_writeb(v, p); }) 285 + #define iowrite16(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_le16(v), p); }) 286 + #define iowrite32(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_le32(v), p); }) 285 287 286 - #define iowrite16be(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_be16(v), p); }) 287 - #define iowrite32be(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_be32(v), p); }) 288 + #define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); }) 289 + #define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); }) 288 290 289 291 #define ioread8_rep(p,d,c) __raw_readsb(p,d,c) 290 292 #define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
+5 -3
arch/arm/include/asm/thread_info.h
··· 148 148 #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ 149 149 #define TIF_SYSCALL_TRACE 8 150 150 #define TIF_SYSCALL_AUDIT 9 151 + #define TIF_SYSCALL_RESTARTSYS 10 151 152 #define TIF_POLLING_NRFLAG 16 152 153 #define TIF_USING_IWMMXT 17 153 154 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ ··· 163 162 #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) 164 163 #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 165 164 #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) 166 - #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 167 165 #define _TIF_SECCOMP (1 << TIF_SECCOMP) 166 + #define _TIF_SYSCALL_RESTARTSYS (1 << TIF_SYSCALL_RESTARTSYS) 168 167 169 168 /* Checks for any syscall work in entry-common.S */ 170 - #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) 169 + #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ 170 + _TIF_SYSCALL_RESTARTSYS) 171 171 172 172 /* 173 173 * Change these and you break ASM code in entry-common.S 174 174 */ 175 - #define _TIF_WORK_MASK 0x000000ff 175 + #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME) 176 176 177 177 #endif /* __KERNEL__ */ 178 178 #endif /* __ASM_ARM_THREAD_INFO_H */
+6 -2
arch/arm/kernel/entry-common.S
··· 53 53 work_pending: 54 54 tst r1, #_TIF_NEED_RESCHED 55 55 bne work_resched 56 - tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME 57 - beq no_work_pending 56 + /* 57 + * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here 58 + */ 59 + ldr r2, [sp, #S_PSR] 58 60 mov r0, sp @ 'regs' 61 + tst r2, #15 @ are we returning to user mode? 62 + bne no_work_pending @ no? just leave, then... 59 63 mov r2, why @ 'syscall' 60 64 tst r1, #_TIF_SIGPENDING @ delivering a signal? 61 65 movne why, #0 @ prevent further restarts
+3
arch/arm/kernel/ptrace.c
··· 25 25 #include <linux/regset.h> 26 26 #include <linux/audit.h> 27 27 #include <linux/tracehook.h> 28 + #include <linux/unistd.h> 28 29 29 30 #include <asm/pgtable.h> 30 31 #include <asm/traps.h> ··· 918 917 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, 919 918 regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); 920 919 920 + if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS)) 921 + scno = __NR_restart_syscall - __NR_SYSCALL_BASE; 921 922 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 922 923 return scno; 923 924
+18 -67
arch/arm/kernel/signal.c
··· 29 29 */ 30 30 #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) 31 31 #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) 32 - #define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE) 33 32 34 33 /* 35 34 * With EABI, the syscall number has to be loaded into r7. ··· 46 47 const unsigned long sigreturn_codes[7] = { 47 48 MOV_R7_NR_SIGRETURN, SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, 48 49 MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, 49 - }; 50 - 51 - /* 52 - * Either we support OABI only, or we have EABI with the OABI 53 - * compat layer enabled. In the later case we don't know if 54 - * user space is EABI or not, and if not we must not clobber r7. 55 - * Always using the OABI syscall solves that issue and works for 56 - * all those cases. 57 - */ 58 - const unsigned long syscall_restart_code[2] = { 59 - SWI_SYS_RESTART, /* swi __NR_restart_syscall */ 60 - 0xe49df004, /* ldr pc, [sp], #4 */ 61 50 }; 62 51 63 52 /* ··· 69 82 old_sigset_t mask; 70 83 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 71 84 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 72 - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 85 + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || 86 + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || 87 + __get_user(mask, &act->sa_mask)) 73 88 return -EFAULT; 74 - __get_user(new_ka.sa.sa_flags, &act->sa_flags); 75 - __get_user(mask, &act->sa_mask); 76 89 siginitset(&new_ka.sa.sa_mask, mask); 77 90 } 78 91 ··· 81 94 if (!ret && oact) { 82 95 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 83 96 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 84 - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 97 + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || 98 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || 99 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) 85 100 return -EFAULT; 86 - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 87 - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 88 101 } 89 102 90 103 return ret; ··· 589 602 int signr; 590 603 591 604 /* 592 - * We want the common case to go fast, which 593 - * is why we may in certain cases get here from 594 - * kernel mode. Just return without doing anything 595 - * if so. 596 - */ 597 - if (!user_mode(regs)) 598 - return; 599 - 600 - /* 601 605 * If we were from a system call, check for system call restarting... 602 606 */ 603 607 if (syscall) { ··· 604 626 case -ERESTARTNOHAND: 605 627 case -ERESTARTSYS: 606 628 case -ERESTARTNOINTR: 629 + case -ERESTART_RESTARTBLOCK: 607 630 regs->ARM_r0 = regs->ARM_ORIG_r0; 608 631 regs->ARM_pc = restart_addr; 609 632 break; 610 - case -ERESTART_RESTARTBLOCK: 611 - regs->ARM_r0 = -EINTR; 612 - break; 613 633 } 614 634 } 615 - 616 - if (try_to_freeze()) 617 - goto no_signal; 618 635 619 636 /* 620 637 * Get the signal to deliver. When running under ptrace, at this ··· 625 652 * debugger has chosen to restart at a different PC. 626 653 */ 627 654 if (regs->ARM_pc == restart_addr) { 628 - if (retval == -ERESTARTNOHAND 655 + if (retval == -ERESTARTNOHAND || 656 + retval == -ERESTART_RESTARTBLOCK 629 657 || (retval == -ERESTARTSYS 630 658 && !(ka.sa.sa_flags & SA_RESTART))) { 631 659 regs->ARM_r0 = -EINTR; 632 660 regs->ARM_pc = continue_addr; 633 661 } 662 + clear_thread_flag(TIF_SYSCALL_RESTARTSYS); 634 663 } 635 664 636 665 if (test_thread_flag(TIF_RESTORE_SIGMASK)) ··· 652 677 return; 653 678 } 654 679 655 - no_signal: 656 680 if (syscall) { 657 681 /* 658 682 * Handle restarting a different system call. As above, ··· 659 685 * ignore the restart. 660 686 */ 661 687 if (retval == -ERESTART_RESTARTBLOCK 662 - && regs->ARM_pc == continue_addr) { 663 - if (thumb_mode(regs)) { 664 - regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; 665 - regs->ARM_pc -= 2; 666 - } else { 667 - #if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT) 668 - regs->ARM_r7 = __NR_restart_syscall; 669 - regs->ARM_pc -= 4; 670 - #else 671 - u32 __user *usp; 672 - 673 - regs->ARM_sp -= 4; 674 - usp = (u32 __user *)regs->ARM_sp; 675 - 676 - if (put_user(regs->ARM_pc, usp) == 0) { 677 - regs->ARM_pc = KERN_RESTART_CODE; 678 - } else { 679 - regs->ARM_sp += 4; 680 - force_sigsegv(0, current); 681 - } 682 - #endif 683 - } 684 - } 685 - 686 - /* If there's no signal to deliver, we just put the saved sigmask 687 - * back. 688 - */ 689 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 690 - clear_thread_flag(TIF_RESTORE_SIGMASK); 691 - sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 692 - } 688 + && regs->ARM_pc == restart_addr) 689 + set_thread_flag(TIF_SYSCALL_RESTARTSYS); 693 690 } 691 + 692 + /* If there's no signal to deliver, we just put the saved sigmask 693 + * back. 694 + */ 695 + if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK)) 696 + set_current_blocked(&current->saved_sigmask); 694 697 } 695 698 696 699 asmlinkage void
-2
arch/arm/kernel/signal.h
··· 8 8 * published by the Free Software Foundation. 9 9 */ 10 10 #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) 11 - #define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes)) 12 11 13 12 extern const unsigned long sigreturn_codes[7]; 14 - extern const unsigned long syscall_restart_code[2];
-2
arch/arm/kernel/traps.c
··· 820 820 */ 821 821 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), 822 822 sigreturn_codes, sizeof(sigreturn_codes)); 823 - memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE), 824 - syscall_restart_code, sizeof(syscall_restart_code)); 825 823 826 824 flush_icache_range(vectors, vectors + PAGE_SIZE); 827 825 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+1
arch/arm/mach-sa1100/neponset.c
··· 89 89 WARN(1, "nep_base unset\n"); 90 90 } 91 91 } 92 + EXPORT_SYMBOL(neponset_ncr_frob); 92 93 93 94 static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) 94 95 {