Commit cd6407fe authored by Linus Torvalds's avatar Linus Torvalds

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

Pull ARM fixes from Russell King:
 "Last merge window, we had some updates from Al cleaning up the signal
  restart handling.  These have caused some problems on ARM, and while
  Al has some fixes, we have some concerns with Al's patches but we've
  been unsuccesful with discussing this.

  We have got to the point where we need to do something, and we've
  decided that the best solution is to revert the appropriate commits
  until Al is able to reply to us.

  Also included here are four patches to fix warnings that I've noticed
  in my build system, and one fix for kprobes test code."

* 'fixes' of git://git.linaro.org/people/rmk/linux-arm:
  ARM: fix warning caused by wrongly typed arm_dma_limit
  ARM: fix warnings about atomic64_read
  ARM: 7440/1: kprobes: only test 'sub pc, pc, #1b-2b+8-2' on ARMv6
  ARM: 7441/1: perf: return -EOPNOTSUPP if requested mode exclusion is unavailable
  ARM: 7443/1: Revert "new way of handling ERESTART_RESTARTBLOCK"
  ARM: 7442/1: Revert "remove unused restart trampoline"
  ARM: fix set_domain() macro
  ARM: fix mach-versatile/pci.c warning
parents 26c439d4 09b2ad13
...@@ -243,7 +243,7 @@ typedef struct { ...@@ -243,7 +243,7 @@ typedef struct {
#define ATOMIC64_INIT(i) { (i) } #define ATOMIC64_INIT(i) { (i) }
static inline u64 atomic64_read(atomic64_t *v) static inline u64 atomic64_read(const atomic64_t *v)
{ {
u64 result; u64 result;
......
...@@ -60,13 +60,13 @@ ...@@ -60,13 +60,13 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#ifdef CONFIG_CPU_USE_DOMAINS #ifdef CONFIG_CPU_USE_DOMAINS
#define set_domain(x) \ static inline void set_domain(unsigned val)
do { \ {
__asm__ __volatile__( \ asm volatile(
"mcr p15, 0, %0, c3, c0 @ set domain" \ "mcr p15, 0, %0, c3, c0 @ set domain"
: : "r" (x)); \ : : "r" (val));
isb(); \ isb();
} while (0) }
#define modify_domain(dom,type) \ #define modify_domain(dom,type) \
do { \ do { \
...@@ -78,8 +78,8 @@ ...@@ -78,8 +78,8 @@
} while (0) } while (0)
#else #else
#define set_domain(x) do { } while (0) static inline void set_domain(unsigned val) { }
#define modify_domain(dom,type) do { } while (0) static inline void modify_domain(unsigned dom, unsigned type) { }
#endif #endif
/* /*
......
...@@ -148,7 +148,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, ...@@ -148,7 +148,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
#define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_TRACE 8
#define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_AUDIT 9
#define TIF_SYSCALL_RESTARTSYS 10
#define TIF_POLLING_NRFLAG 16 #define TIF_POLLING_NRFLAG 16
#define TIF_USING_IWMMXT 17 #define TIF_USING_IWMMXT 17
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
...@@ -164,11 +163,9 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, ...@@ -164,11 +163,9 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_SYSCALL_RESTARTSYS (1 << TIF_SYSCALL_RESTARTSYS)
/* Checks for any syscall work in entry-common.S */ /* Checks for any syscall work in entry-common.S */
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
_TIF_SYSCALL_RESTARTSYS)
/* /*
* Change these and you break ASM code in entry-common.S * Change these and you break ASM code in entry-common.S
......
...@@ -187,8 +187,8 @@ void kprobe_arm_test_cases(void) ...@@ -187,8 +187,8 @@ void kprobe_arm_test_cases(void)
TEST_BF_R ("mov pc, r",0,2f,"") TEST_BF_R ("mov pc, r",0,2f,"")
TEST_BF_RR("mov pc, r",0,2f,", asl r",1,0,"") TEST_BF_RR("mov pc, r",0,2f,", asl r",1,0,"")
TEST_BB( "sub pc, pc, #1b-2b+8") TEST_BB( "sub pc, pc, #1b-2b+8")
#if __LINUX_ARM_ARCH__ >= 6 #if __LINUX_ARM_ARCH__ == 6 && !defined(CONFIG_CPU_V7)
TEST_BB( "sub pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before ARMv6 */ TEST_BB( "sub pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before and after ARMv6 */
#endif #endif
TEST_BB_R( "sub pc, pc, r",14, 1f-2f+8,"") TEST_BB_R( "sub pc, pc, r",14, 1f-2f+8,"")
TEST_BB_R( "rsb pc, r",14,1f-2f+8,", pc") TEST_BB_R( "rsb pc, r",14,1f-2f+8,", pc")
......
...@@ -503,7 +503,7 @@ __hw_perf_event_init(struct perf_event *event) ...@@ -503,7 +503,7 @@ __hw_perf_event_init(struct perf_event *event)
event_requires_mode_exclusion(&event->attr)) { event_requires_mode_exclusion(&event->attr)) {
pr_debug("ARM performance counters do not support " pr_debug("ARM performance counters do not support "
"mode exclusion\n"); "mode exclusion\n");
return -EPERM; return -EOPNOTSUPP;
} }
/* /*
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <linux/unistd.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/traps.h> #include <asm/traps.h>
...@@ -918,8 +917,6 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) ...@@ -918,8 +917,6 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0,
regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS))
scno = __NR_restart_syscall - __NR_SYSCALL_BASE;
if (!test_thread_flag(TIF_SYSCALL_TRACE)) if (!test_thread_flag(TIF_SYSCALL_TRACE))
return scno; return scno;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
*/ */
#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
/* /*
* With EABI, the syscall number has to be loaded into r7. * With EABI, the syscall number has to be loaded into r7.
...@@ -46,6 +47,18 @@ const unsigned long sigreturn_codes[7] = { ...@@ -46,6 +47,18 @@ const unsigned long sigreturn_codes[7] = {
MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
}; };
/*
* Either we support OABI only, or we have EABI with the OABI
* compat layer enabled. In the later case we don't know if
* user space is EABI or not, and if not we must not clobber r7.
* Always using the OABI syscall solves that issue and works for
* all those cases.
*/
const unsigned long syscall_restart_code[2] = {
SWI_SYS_RESTART, /* swi __NR_restart_syscall */
0xe49df004, /* ldr pc, [sp], #4 */
};
/* /*
* atomically swap in the new signal mask, and wait for a signal. * atomically swap in the new signal mask, and wait for a signal.
*/ */
...@@ -592,10 +605,12 @@ static void do_signal(struct pt_regs *regs, int syscall) ...@@ -592,10 +605,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
case -ERESTARTNOHAND: case -ERESTARTNOHAND:
case -ERESTARTSYS: case -ERESTARTSYS:
case -ERESTARTNOINTR: case -ERESTARTNOINTR:
case -ERESTART_RESTARTBLOCK:
regs->ARM_r0 = regs->ARM_ORIG_r0; regs->ARM_r0 = regs->ARM_ORIG_r0;
regs->ARM_pc = restart_addr; regs->ARM_pc = restart_addr;
break; break;
case -ERESTART_RESTARTBLOCK:
regs->ARM_r0 = -EINTR;
break;
} }
} }
...@@ -611,14 +626,12 @@ static void do_signal(struct pt_regs *regs, int syscall) ...@@ -611,14 +626,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
* debugger has chosen to restart at a different PC. * debugger has chosen to restart at a different PC.
*/ */
if (regs->ARM_pc == restart_addr) { if (regs->ARM_pc == restart_addr) {
if (retval == -ERESTARTNOHAND || if (retval == -ERESTARTNOHAND
retval == -ERESTART_RESTARTBLOCK
|| (retval == -ERESTARTSYS || (retval == -ERESTARTSYS
&& !(ka.sa.sa_flags & SA_RESTART))) { && !(ka.sa.sa_flags & SA_RESTART))) {
regs->ARM_r0 = -EINTR; regs->ARM_r0 = -EINTR;
regs->ARM_pc = continue_addr; regs->ARM_pc = continue_addr;
} }
clear_thread_flag(TIF_SYSCALL_RESTARTSYS);
} }
handle_signal(signr, &ka, &info, regs); handle_signal(signr, &ka, &info, regs);
...@@ -632,8 +645,29 @@ static void do_signal(struct pt_regs *regs, int syscall) ...@@ -632,8 +645,29 @@ static void do_signal(struct pt_regs *regs, int syscall)
* ignore the restart. * ignore the restart.
*/ */
if (retval == -ERESTART_RESTARTBLOCK if (retval == -ERESTART_RESTARTBLOCK
&& regs->ARM_pc == restart_addr) && regs->ARM_pc == continue_addr) {
set_thread_flag(TIF_SYSCALL_RESTARTSYS); if (thumb_mode(regs)) {
regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
regs->ARM_pc -= 2;
} else {
#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
regs->ARM_r7 = __NR_restart_syscall;
regs->ARM_pc -= 4;
#else
u32 __user *usp;
regs->ARM_sp -= 4;
usp = (u32 __user *)regs->ARM_sp;
if (put_user(regs->ARM_pc, usp) == 0) {
regs->ARM_pc = KERN_RESTART_CODE;
} else {
regs->ARM_sp += 4;
force_sigsegv(0, current);
}
#endif
}
}
} }
restore_saved_sigmask(); restore_saved_sigmask();
......
...@@ -8,5 +8,7 @@ ...@@ -8,5 +8,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
extern const unsigned long sigreturn_codes[7]; extern const unsigned long sigreturn_codes[7];
extern const unsigned long syscall_restart_code[2];
...@@ -820,6 +820,8 @@ void __init early_trap_init(void *vectors_base) ...@@ -820,6 +820,8 @@ void __init early_trap_init(void *vectors_base)
*/ */
memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
sigreturn_codes, sizeof(sigreturn_codes)); sigreturn_codes, sizeof(sigreturn_codes));
memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
syscall_restart_code, sizeof(syscall_restart_code));
flush_icache_range(vectors, vectors + PAGE_SIZE); flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT); modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
......
...@@ -339,7 +339,6 @@ void __init pci_versatile_preinit(void) ...@@ -339,7 +339,6 @@ void __init pci_versatile_preinit(void)
static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{ {
int irq; int irq;
int devslot = PCI_SLOT(dev->devfn);
/* slot, pin, irq /* slot, pin, irq
* 24 1 27 * 24 1 27
......
...@@ -64,7 +64,7 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page ...@@ -64,7 +64,7 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
#ifdef CONFIG_ZONE_DMA #ifdef CONFIG_ZONE_DMA
extern phys_addr_t arm_dma_limit; extern phys_addr_t arm_dma_limit;
#else #else
#define arm_dma_limit ((u32)~0) #define arm_dma_limit ((phys_addr_t)~0)
#endif #endif
extern phys_addr_t arm_lowmem_limit; extern phys_addr_t arm_lowmem_limit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment