aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabio Estevam <festevam@gmail.com>2013-07-23 10:13:06 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-07-26 07:02:09 -0400
commit1f49856bb029779d8f1b63517a3a3b34ffe672c7 (patch)
tree2fa00a1dc1f50c04c7c3fd339f534275e213590b
parent8fbac214e5c594a0c2fe78c14adf2cdbb1febc92 (diff)
ARM: 7789/1: Do not run dummy_flush_tlb_a15_erratum() on non-Cortex-A15
Commit 93dc688 (ARM: 7684/1: errata: Workaround for Cortex-A15 erratum 798181 (TLBI/DSB operations)) causes the following undefined instruction error on a mx53 (Cortex-A8): Internal error: Oops - undefined instruction: 0 [#1] SMP ARM CPU: 0 PID: 275 Comm: modprobe Not tainted 3.11.0-rc2-next-20130722-00009-g9b0f371 #881 task: df46cc00 ti: df48e000 task.ti: df48e000 PC is at check_and_switch_context+0x17c/0x4d0 LR is at check_and_switch_context+0xdc/0x4d0 This problem happens because check_and_switch_context() calls dummy_flush_tlb_a15_erratum() without checking if we are really running on a Cortex-A15 or not. To avoid this issue, only call dummy_flush_tlb_a15_erratum() inside check_and_switch_context() if erratum_a15_798181() returns true, which means that we are really running on a Cortex-A15. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/include/asm/tlbflush.h16
-rw-r--r--arch/arm/kernel/smp_tlb.c17
-rw-r--r--arch/arm/mm/context.c3
3 files changed, 18 insertions, 18 deletions
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index fdbb9e369745..f467e9b3f8d5 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -443,7 +443,18 @@ static inline void local_flush_bp_all(void)
443 isb(); 443 isb();
444} 444}
445 445
446#include <asm/cputype.h>
446#ifdef CONFIG_ARM_ERRATA_798181 447#ifdef CONFIG_ARM_ERRATA_798181
448static inline int erratum_a15_798181(void)
449{
450 unsigned int midr = read_cpuid_id();
451
452 /* Cortex-A15 r0p0..r3p2 affected */
453 if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2)
454 return 0;
455 return 1;
456}
457
447static inline void dummy_flush_tlb_a15_erratum(void) 458static inline void dummy_flush_tlb_a15_erratum(void)
448{ 459{
449 /* 460 /*
@@ -453,6 +464,11 @@ static inline void dummy_flush_tlb_a15_erratum(void)
453 dsb(); 464 dsb();
454} 465}
455#else 466#else
467static inline int erratum_a15_798181(void)
468{
469 return 0;
470}
471
456static inline void dummy_flush_tlb_a15_erratum(void) 472static inline void dummy_flush_tlb_a15_erratum(void)
457{ 473{
458} 474}
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c
index a98b62dca2fa..c2edfff573c2 100644
--- a/arch/arm/kernel/smp_tlb.c
+++ b/arch/arm/kernel/smp_tlb.c
@@ -70,23 +70,6 @@ static inline void ipi_flush_bp_all(void *ignored)
70 local_flush_bp_all(); 70 local_flush_bp_all();
71} 71}
72 72
73#ifdef CONFIG_ARM_ERRATA_798181
74static int erratum_a15_798181(void)
75{
76 unsigned int midr = read_cpuid_id();
77
78 /* Cortex-A15 r0p0..r3p2 affected */
79 if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2)
80 return 0;
81 return 1;
82}
83#else
84static int erratum_a15_798181(void)
85{
86 return 0;
87}
88#endif
89
90static void ipi_flush_tlb_a15_erratum(void *arg) 73static void ipi_flush_tlb_a15_erratum(void *arg)
91{ 74{
92 dmb(); 75 dmb();
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index b55b1015724b..4a0544492f10 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -245,7 +245,8 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
245 if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) { 245 if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) {
246 local_flush_bp_all(); 246 local_flush_bp_all();
247 local_flush_tlb_all(); 247 local_flush_tlb_all();
248 dummy_flush_tlb_a15_erratum(); 248 if (erratum_a15_798181())
249 dummy_flush_tlb_a15_erratum();
249 } 250 }
250 251
251 atomic64_set(&per_cpu(active_asids, cpu), asid); 252 atomic64_set(&per_cpu(active_asids, cpu), asid);