From c7d442f46c1bb18e48204f41c3d838c475eb5130 Mon Sep 17 00:00:00 2001 From: Sebastian Capella Date: Tue, 25 Mar 2014 01:18:35 +0100 Subject: [PATCH 01/10] ARM: 8010/1: avoid tracers in soft_restart Use of tracers in local_irq_disable is causes abort loops when called with irqs disabled using a temporary stack. Replace local_irq_disable with raw_local_irq_disable instead to avoid tracers. Signed-off-by: Sebastian Capella Signed-off-by: Russell King --- arch/arm/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 92f7b15dd221..f58b723bec00 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -100,7 +100,7 @@ void soft_restart(unsigned long addr) u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack); /* Disable interrupts first */ - local_irq_disable(); + raw_local_irq_disable(); local_fiq_disable(); /* Disable the L2 if we're the last man standing. */ From 8fad87bca7ac9737e413ba5f1656f1114a8c314d Mon Sep 17 00:00:00 2001 From: Liu Hua Date: Thu, 27 Mar 2014 06:56:18 +0100 Subject: [PATCH 02/10] ARM: 8012/1: kdump: Avoid overflow when converting pfn to physaddr When we configure CONFIG_ARM_LPAE=y, pfn << PAGE_SHIFT will overflow if pfn >= 0x100000 in copy_oldmem_page. So use __pfn_to_phys for converting. Signed-off-by: Liu Hua Signed-off-by: Russell King --- arch/arm/kernel/crash_dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/crash_dump.c b/arch/arm/kernel/crash_dump.c index 90c50d4b43f7..5d1286d51154 100644 --- a/arch/arm/kernel/crash_dump.c +++ b/arch/arm/kernel/crash_dump.c @@ -39,7 +39,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!csize) return 0; - vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); + vaddr = ioremap(__pfn_to_phys(pfn), PAGE_SIZE); if (!vaddr) return -ENOMEM; From fff00db852f2ff0faf5f539b5e28ac498fc007f8 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 31 Mar 2014 22:20:34 +0100 Subject: [PATCH 03/10] ARM: 8014/1: mm: fix reporting of read-only PMD bits On non-LPAE ARMv6+, read-only PMD bits are defined with the combination "PMD_SECT_APX | PMD_SECT_AP_WRITE". Adjusted the bit masks to correctly report this. Signed-off-by: Kees Cook Tested-by: Laura Abbott Signed-off-by: Russell King --- arch/arm/mm/dump.c | 55 ++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c index ef69152f9b52..c508f41a43bc 100644 --- a/arch/arm/mm/dump.c +++ b/arch/arm/mm/dump.c @@ -120,25 +120,7 @@ static const struct prot_bits pte_bits[] = { }; static const struct prot_bits section_bits[] = { -#ifndef CONFIG_ARM_LPAE - /* These are approximate */ - { - .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, - .val = 0, - .set = " ro", - }, { - .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, - .val = PMD_SECT_AP_WRITE, - .set = " RW", - }, { - .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, - .val = PMD_SECT_AP_READ, - .set = "USR ro", - }, { - .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, - .val = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, - .set = "USR RW", -#else +#ifdef CONFIG_ARM_LPAE { .mask = PMD_SECT_USER, .val = PMD_SECT_USER, @@ -148,6 +130,41 @@ static const struct prot_bits section_bits[] = { .val = PMD_SECT_RDONLY, .set = "ro", .clear = "RW", +#elif __LINUX_ARM_ARCH__ >= 6 + { + .mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .val = PMD_SECT_APX | PMD_SECT_AP_WRITE, + .set = " ro", + }, { + .mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .val = PMD_SECT_AP_WRITE, + .set = " RW", + }, { + .mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .val = PMD_SECT_AP_READ, + .set = "USR ro", + }, { + .mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .val = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .set = "USR RW", +#else /* ARMv4/ARMv5 */ + /* These are approximate */ + { + .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .val = 0, + .set = " ro", + }, { + .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .val = PMD_SECT_AP_WRITE, + .set = " RW", + }, { + .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .val = PMD_SECT_AP_READ, + .set = "USR ro", + }, { + .mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .val = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE, + .set = "USR RW", #endif }, { .mask = PMD_SECT_XN, From c9d347e0277696c80496161cbef47393b850a0aa Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 24 Mar 2014 16:51:58 +0100 Subject: [PATCH 04/10] ARM: 8009/1: dcscb.c: remove call to outer_flush_all() Strictly speaking this call is a no-op on the platform where dcscb.c is used since it only has architected caches. The call was there as a hint to people inspired by this code when writing their own backend, but the hint might not always be correct. For example, if a PL310 were to be used it wouldn't be safe to call the regular outer_flush_all() as atomic instructions for locking are involved in that case and those instructions cannot be assumed to still be operational after v7_exit_coherency_flush() has returned. Given no other CPUs (in the cluster) should be running at that point then standard concurrency concerns wouldn't apply. So let's simply kill this call for now and enhance the existing comment. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-vexpress/dcscb.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c index 14d499688736..788495d35cf9 100644 --- a/arch/arm/mach-vexpress/dcscb.c +++ b/arch/arm/mach-vexpress/dcscb.c @@ -137,11 +137,16 @@ static void dcscb_power_down(void) v7_exit_coherency_flush(all); /* - * This is a harmless no-op. On platforms with a real - * outer cache this might either be needed or not, - * depending on where the outer cache sits. + * A full outer cache flush could be needed at this point + * on platforms with such a cache, depending on where the + * outer cache sits. In some cases the notion of a "last + * cluster standing" would need to be implemented if the + * outer cache is shared across clusters. In any case, when + * the outer cache needs flushing, there is no concurrent + * access to the cache controller to worry about and no + * special locking besides what is already provided by the + * MCPM state machinery is needed. */ - outer_flush_all(); /* * Disable cluster-level coherency by masking From 779dd9590b00bd91b7811c24f0df34a9d91bfa0f Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 6 Apr 2014 16:17:39 +0100 Subject: [PATCH 05/10] ARM: add missing system_misc.h include to process.c arm_pm_restart(), arm_pm_idle() and soft_restart() are all declared in system_misc.h, but this file is not included in process.c. Add this missing include. Found via sparse: arch/arm/kernel/process.c:98:6: warning: symbol 'soft_restart' was not declared. Should it be static? arch/arm/kernel/process.c:127:6: warning: symbol 'arm_pm_restart' was not declared. Should it be static? arch/arm/kernel/process.c:134:6: warning: symbol 'arm_pm_idle' was not declared. Should it be static? Signed-off-by: Russell King --- arch/arm/kernel/process.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 92f7b15dd221..da450e06c9ae 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include From fdb487f5c961b94486a78fa61fa28b8eff1954ab Mon Sep 17 00:00:00 2001 From: Chao Xie Linux Date: Wed, 2 Apr 2014 02:47:09 +0100 Subject: [PATCH 06/10] ARM: 8015/1: Add cpu_is_pj4 to distinguish PJ4 because it has some differences with V7 The patch add cpu_is_pj4 at arch/arm/include/asm/cputype.h PJ4 has some differences with V7, for example the coprocessor. To disinguish this kind of situation. cpu_is_pj4 is needed. Signed-off-by: Chao Xie Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Tested-by: Stephen Warren Reviewed-by: Stephen Warren Tested-by: Matt Porter Signed-off-by: Russell King --- arch/arm/include/asm/cputype.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 42f0889f0584..c651e3b26ec7 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -221,4 +221,23 @@ static inline int cpu_is_xsc3(void) #define cpu_is_xscale() 1 #endif +/* + * Marvell's PJ4 core is based on V7 version. It has some modification + * for coprocessor setting. For this reason, we need a way to distinguish + * it. + */ +#ifndef CONFIG_CPU_PJ4 +#define cpu_is_pj4() 0 +#else +static inline int cpu_is_pj4(void) +{ + unsigned int id; + + id = read_cpuid_id(); + if ((id & 0xfffffff0) == 0x562f5840) + return 1; + + return 0; +} +#endif #endif From a5d4506d070adb785459bf142ef707d7c5fe3b84 Mon Sep 17 00:00:00 2001 From: Chao Xie Linux Date: Wed, 2 Apr 2014 02:50:03 +0100 Subject: [PATCH 07/10] ARM: 8016/1: Check cpu id in pj4_cp0_init. Check cpu id in pj4_cp0_init. So for no-PJ4 V7 cpus, pj4_cpu0_init just return. This fix will help to make the all the V7 cpus(PJ4 and no-PJ4) can use code. Signed-off-by: Chao Xie Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Tested-by: Stephen Warren Reviewed-by: Stephen Warren Tested-by: Matt Porter Signed-off-by: Russell King --- arch/arm/kernel/pj4-cp0.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c index 679cf4d18c08..fc7208636284 100644 --- a/arch/arm/kernel/pj4-cp0.c +++ b/arch/arm/kernel/pj4-cp0.c @@ -17,6 +17,7 @@ #include #include #include +#include static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) { @@ -80,6 +81,9 @@ static int __init pj4_cp0_init(void) { u32 cp_access; + if (!cpu_is_pj4()) + return 0; + cp_access = pj4_cp_access_read() & ~0xf; pj4_cp_access_write(cp_access); From 39ad04ccd6e1b235601e9ac5a7f508d05728a97a Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 2 Apr 2014 10:57:48 +0100 Subject: [PATCH 08/10] ARM: 8017/1: Move asm macro get_thread_info to asm/assembler.h asm/assembler.h is a better place for this macro since it is used by asm files outside arch/arm/kernel/ Signed-off-by: Catalin Marinas Tested-by: Arun KS Signed-off-by: Russell King --- arch/arm/include/asm/assembler.h | 10 ++++++++++ arch/arm/kernel/entry-header.S | 11 ----------- arch/arm/vfp/entry.S | 5 ++++- arch/arm/vfp/vfphw.S | 5 ++++- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 380ac4f20000..9a4965ad6867 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -174,6 +174,16 @@ restore_irqs_notrace \oldcpsr .endm +/* + * Get current thread_info. + */ + .macro get_thread_info, rd + ARM( mov \rd, sp, lsr #13 ) + THUMB( mov \rd, sp ) + THUMB( lsr \rd, \rd, #13 ) + mov \rd, \rd, lsl #13 + .endm + #define USER(x...) \ 9999: x; \ .pushsection __ex_table,"a"; \ diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 39f89fbd5111..1420725142ca 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -236,11 +236,6 @@ movs pc, lr @ return & move spsr_svc into cpsr .endm - .macro get_thread_info, rd - mov \rd, sp, lsr #13 - mov \rd, \rd, lsl #13 - .endm - @ @ 32-bit wide "mov pc, reg" @ @@ -306,12 +301,6 @@ .endm #endif /* ifdef CONFIG_CPU_V7M / else */ - .macro get_thread_info, rd - mov \rd, sp - lsr \rd, \rd, #13 - mov \rd, \rd, lsl #13 - .endm - @ @ 32-bit wide "mov pc, reg" @ diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index 46e17492fd1f..9cc290ae4e3b 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -8,9 +8,12 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include +#include #include #include -#include "../kernel/entry-header.S" +#include +#include @ VFP entry point. @ diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 3e5d3115a2a6..98f6246c9002 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -14,10 +14,13 @@ * r10 points at the start of the private FP workspace in the thread structure * sp points to a struct pt_regs (as defined in include/asm/proc/ptrace.h) */ +#include +#include #include #include #include -#include "../kernel/entry-header.S" +#include +#include .macro DBGSTR, str #ifdef DEBUG From 0b1f68e836bcf1ca2861f95066985c57ecfb2f1a Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 2 Apr 2014 10:57:49 +0100 Subject: [PATCH 09/10] ARM: 8018/1: Add {inc,dec}_preempt_count asm macros The patch adds asm macros for inc_preempt_count and dec_preempt_count_ti (which also gets the current thread_info) instead of open-coding them in arch/arm/vfp/*.S files. Signed-off-by: Catalin Marinas Tested-by: Arun KS Signed-off-by: Russell King --- arch/arm/include/asm/assembler.h | 32 ++++++++++++++++++++++++++++++++ arch/arm/vfp/entry.S | 20 +++----------------- arch/arm/vfp/vfphw.S | 14 ++------------ 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 9a4965ad6867..b974184f9941 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -23,6 +23,7 @@ #include #include #include +#include #define IOMEM(x) (x) @@ -184,6 +185,37 @@ mov \rd, \rd, lsl #13 .endm +/* + * Increment/decrement the preempt count. + */ +#ifdef CONFIG_PREEMPT_COUNT + .macro inc_preempt_count, ti, tmp + ldr \tmp, [\ti, #TI_PREEMPT] @ get preempt count + add \tmp, \tmp, #1 @ increment it + str \tmp, [\ti, #TI_PREEMPT] + .endm + + .macro dec_preempt_count, ti, tmp + ldr \tmp, [\ti, #TI_PREEMPT] @ get preempt count + sub \tmp, \tmp, #1 @ decrement it + str \tmp, [\ti, #TI_PREEMPT] + .endm + + .macro dec_preempt_count_ti, ti, tmp + get_thread_info \ti + dec_preempt_count \ti, \tmp + .endm +#else + .macro inc_preempt_count, ti, tmp + .endm + + .macro dec_preempt_count, ti, tmp + .endm + + .macro dec_preempt_count_ti, ti, tmp + .endm +#endif + #define USER(x...) \ 9999: x; \ .pushsection __ex_table,"a"; \ diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index 9cc290ae4e3b..f0759e70fb86 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -25,11 +25,7 @@ @ IRQs disabled. @ ENTRY(do_vfp) -#ifdef CONFIG_PREEMPT_COUNT - ldr r4, [r10, #TI_PREEMPT] @ get preempt count - add r11, r4, #1 @ increment it - str r11, [r10, #TI_PREEMPT] -#endif + inc_preempt_count r10, r4 enable_irq ldr r4, .LCvfp ldr r11, [r10, #TI_CPU] @ CPU number @@ -38,12 +34,7 @@ ENTRY(do_vfp) ENDPROC(do_vfp) ENTRY(vfp_null_entry) -#ifdef CONFIG_PREEMPT_COUNT - get_thread_info r10 - ldr r4, [r10, #TI_PREEMPT] @ get preempt count - sub r11, r4, #1 @ decrement it - str r11, [r10, #TI_PREEMPT] -#endif + dec_preempt_count_ti r10, r4 mov pc, lr ENDPROC(vfp_null_entry) @@ -56,12 +47,7 @@ ENDPROC(vfp_null_entry) __INIT ENTRY(vfp_testing_entry) -#ifdef CONFIG_PREEMPT_COUNT - get_thread_info r10 - ldr r4, [r10, #TI_PREEMPT] @ get preempt count - sub r11, r4, #1 @ decrement it - str r11, [r10, #TI_PREEMPT] -#endif + dec_preempt_count_ti r10, r4 ldr r0, VFP_arch_address str r0, [r0] @ set to non-zero value mov pc, r9 @ we have handled the fault diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 98f6246c9002..be807625ed8c 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -182,12 +182,7 @@ vfp_hw_state_valid: @ else it's one 32-bit instruction, so @ always subtract 4 from the following @ instruction address. -#ifdef CONFIG_PREEMPT_COUNT - get_thread_info r10 - ldr r4, [r10, #TI_PREEMPT] @ get preempt count - sub r11, r4, #1 @ decrement it - str r11, [r10, #TI_PREEMPT] -#endif + dec_preempt_count_ti r10, r4 mov pc, r9 @ we think we have handled things @@ -206,12 +201,7 @@ look_for_VFP_exceptions: @ not recognised by VFP DBGSTR "not VFP" -#ifdef CONFIG_PREEMPT_COUNT - get_thread_info r10 - ldr r4, [r10, #TI_PREEMPT] @ get preempt count - sub r11, r4, #1 @ decrement it - str r11, [r10, #TI_PREEMPT] -#endif + dec_preempt_count_ti r10, r4 mov pc, lr process_exception: From b5b6b5f5442860474ebd263cfd3e4a2a972632d8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 10 Apr 2014 00:49:50 +0100 Subject: [PATCH 10/10] Dump the registers on undefined instruction userspace faults Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 172ee18ff124..abd2fc067736 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -445,6 +445,7 @@ die_sig: if (user_debug & UDBG_UNDEFINED) { printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); + __show_regs(regs); dump_instr(KERN_INFO, regs); } #endif