From 94e5a85b3be0ce109d26aa6812b2a02c518a0e4b Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 18 Jan 2012 15:32:49 +0000 Subject: ARM: earlier initialization of vectors page Initialize the contents of the vectors page immediately after we allocate the page, but before we map it. This avoids any possible aliases with other mappings which may need to be flushed after the page has been mapped irrespective of the cache type. We follow this later with a flush_cache_all() after all static memory mappings have been initialized, which ensures that this is safe from any cache effects. Tested-by: Catalin Marinas Reviewed-by: Catalin Marinas Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 99a57270250..be15dafaa88 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -781,18 +781,16 @@ static void __init kuser_get_tls_init(unsigned long vectors) memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); } -void __init early_trap_init(void) +void __init early_trap_init(void *vectors_base) { -#if defined(CONFIG_CPU_USE_DOMAINS) - unsigned long vectors = CONFIG_VECTORS_BASE; -#else - unsigned long vectors = (unsigned long)vectors_page; -#endif + unsigned long vectors = (unsigned long)vectors_base; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; extern char __kuser_helper_start[], __kuser_helper_end[]; int kuser_sz = __kuser_helper_end - __kuser_helper_start; + vectors_page = vectors_base; + /* * Copy the vectors, stubs and kuser helpers (in entry-armv.S) * into the vector page, mapped at 0xffff0000, and ensure these -- cgit v1.2.3 From bdf800c4fceb6d8dbe65471d214eb44a61f5bfc9 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 7 Feb 2012 19:42:33 +0100 Subject: ARM: 7322/1: Print BUG instead of undefined instruction on BUG_ON() The ARM kernel uses undefined instructions to implement BUG/BUG_ON(). This leads to problems where people don't read one line above the Oops message and see the "kernel BUG at ..." message and so they wrongly assume the kernel has hit an undefined instruction. Instead of printing: Internal error: Oops - undefined instruction: 0 [#1] PREEMPT SMP print Internal error: Oops - BUG: 0 [#1] PREEMPT SMP This should prevent people from thinking the BUG_ON was an undefined instruction when it was actually intentional. Signed-off-by: Stephen Boyd Acked-by: Simon Glass Tested-by: Simon Glass Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 99a57270250..f84dfe67724 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -266,6 +266,7 @@ void die(const char *str, struct pt_regs *regs, int err) { struct thread_info *thread = current_thread_info(); int ret; + enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; oops_enter(); @@ -273,7 +274,9 @@ void die(const char *str, struct pt_regs *regs, int err) console_verbose(); bust_spinlocks(1); if (!user_mode(regs)) - report_bug(regs->ARM_pc, regs); + bug_type = report_bug(regs->ARM_pc, regs); + if (bug_type != BUG_TRAP_TYPE_NONE) + str = "Oops - BUG"; ret = __die(str, err, thread, regs); if (regs && kexec_should_crash(thread->task)) -- cgit v1.2.3 From 8211ca658728d03ba331de0276950289e52a1b0f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 4 Feb 2012 12:12:11 +0000 Subject: ARM: Add compiled ISA to oops dumps Add the compiled ISA to oops dumps, along side the preempt/smp configuration. This allows us to see immediately whether the kernel was compiled for Thumb-2 or not. Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index be15dafaa88..23377a3bf50 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -227,6 +227,11 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) #else #define S_SMP "" #endif +#ifdef CONFIG_THUMB2_KERNEL +#define S_ISA " THUMB2" +#else +#define S_ISA " ARM" +#endif static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs) { @@ -234,8 +239,8 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt static int die_counter; int ret; - printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", - str, err, ++die_counter); + printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP + S_ISA "\n", str, err, ++die_counter); /* trap and error numbers are mostly meaningless on ARM */ ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); -- cgit v1.2.3 From 9f97da78bf018206fb623cd351d454af2f105fe0 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 28 Mar 2012 18:30:01 +0100 Subject: Disintegrate asm/system.h for ARM Disintegrate asm/system.h for ARM. Signed-off-by: David Howells cc: Russell King cc: linux-arm-kernel@lists.infradead.org --- arch/arm/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index f84dfe67724..cd77743472a 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -29,11 +29,11 @@ #include #include #include -#include #include #include #include #include +#include #include "signal.h" -- cgit v1.2.3 From 4542b6a0fa6b48d9ae6b41c1efeb618b7a221b2a Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Thu, 29 Mar 2012 20:44:06 +0100 Subject: ARM: 7365/1: drop unused parameter from flush_cache_user_range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vma isn't used and flush_cache_user_range isn't a standard macro that is used on several archs with the same prototype. In fact only unicore32 has a macro with the same name (with an identical implementation and no in-tree users). This is a part of a patch proposed by Dima Zavin (with Message-id: 1272439931-12795-1-git-send-email-dima@android.com) that didn't get accepted. Cc: Dima Zavin Acked-by: Catalin Marinas Signed-off-by: Uwe Kleine-König Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 778454750a6..55b2f3dc6bb 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -496,7 +496,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags) if (end > vma->vm_end) end = vma->vm_end; - flush_cache_user_range(vma, start, end); + flush_cache_user_range(start, end); } up_read(&mm->mmap_sem); } -- cgit v1.2.3 From 435a7ef52db7d86e67a009b36cac1457f8972391 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Mon, 30 Apr 2012 10:26:14 +0100 Subject: ARM: 7409/1: Do not call flush_cache_user_range with mmap_sem held We can't be holding the mmap_sem while calling flush_cache_user_range because the flush can fault. If we fault on a user address, the page fault handler will try to take mmap_sem again. Since both places acquire the read lock, most of the time it succeeds. However, if another thread tries to acquire the write lock on the mmap_sem (e.g. mmap) in between the call to flush_cache_user_range and the fault, the down_read in do_page_fault will deadlock. [will: removed drop of vma parameter as already queued by rmk (7365/1)] Acked-by: Catalin Marinas Signed-off-by: Dima Zavin Signed-off-by: John Stultz Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 55b2f3dc6bb..63d402f75e2 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -496,7 +496,9 @@ do_cache_op(unsigned long start, unsigned long end, int flags) if (end > vma->vm_end) end = vma->vm_end; + up_read(&mm->mmap_sem); flush_cache_user_range(start, end); + return; } up_read(&mm->mmap_sem); } -- cgit v1.2.3 From c5102f5935503ebebad46e137d0eef68f272cc16 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 27 Apr 2012 13:08:53 +0100 Subject: ARM: 7408/1: cacheflush: return error to userspace when flushing syscall fails The cacheflush syscall can fail for two reasons: (1) The arguments are invalid (nonsensical address range or no VMA) (2) The region generates a translation fault on a VIPT or PIPT cache This patch allows do_cache_op to return an error code to userspace in the case of the above. The various coherent_user_range implementations are modified to return 0 in the case of VIVT caches or -EFAULT in the case of an abort on v6/v7 cores. Reviewed-by: Catalin Marinas Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 63d402f75e2..3647170e9a1 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -479,14 +479,14 @@ static int bad_syscall(int n, struct pt_regs *regs) return regs->ARM_r0; } -static inline void +static inline int do_cache_op(unsigned long start, unsigned long end, int flags) { struct mm_struct *mm = current->active_mm; struct vm_area_struct *vma; if (end < start || flags) - return; + return -EINVAL; down_read(&mm->mmap_sem); vma = find_vma(mm, start); @@ -497,10 +497,10 @@ do_cache_op(unsigned long start, unsigned long end, int flags) end = vma->vm_end; up_read(&mm->mmap_sem); - flush_cache_user_range(start, end); - return; + return flush_cache_user_range(start, end); } up_read(&mm->mmap_sem); + return -EINVAL; } /* @@ -546,8 +546,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) * the specified region). */ case NR(cacheflush): - do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2); - return 0; + return do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2); case NR(usr26): if (!(elf_hwcap & HWCAP_26BIT)) -- cgit v1.2.3 From fa18484d0947b976a769d15c83c50617493c81c1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 2 May 2012 21:13:45 -0400 Subject: arm: remove unused restart trampoline Signed-off-by: Al Viro --- arch/arm/kernel/traps.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 778454750a6..5aef330e9c5 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -819,8 +819,6 @@ void __init early_trap_init(void *vectors_base) */ memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), 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); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); -- cgit v1.2.3 From 3b0c06226783ffc836217eb34f7eca311b1e63f7 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 4 Jul 2012 18:16:30 +0100 Subject: ARM: 7442/1: Revert "remove unused restart trampoline" This reverts commit fa18484d0947b976a769d15c83c50617493c81c1. We need the restart trampoline back so that we can revert a related problematic patch 6b5c8045ecc7e726cdaa2a9d9c8e5008050e1252 ("arm: new way of handling ERESTART_RESTARTBLOCK"). Acked-by: Catalin Marinas Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/kernel/traps.c') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 4928d89758f..3647170e9a1 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -820,6 +820,8 @@ void __init early_trap_init(void *vectors_base) */ memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), 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); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); -- cgit v1.2.3