msm: cache_erp: Handle recoverable L1 errors
Some CPU designs may be able to recover from certain types
of L1 instruction cache errors. Rather than panicing
whenever any kind of L1 error is encountered, add an option
to selectively panic on recoverable L1 errors.
Change-Id: Id8beb0e58d41fa5319f4ca76c5f35e2162f8b704
Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 372d0ac..8dd8579 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -2539,6 +2539,21 @@
For production builds, you should probably say 'N' here.
+config MSM_L1_RECOV_ERR_PANIC
+ bool "Panic on recoverable L1 cache errors"
+ depends on MSM_CACHE_ERP && MSM_L1_ERR_PANIC
+ help
+ Certain CPU designs may be able to automatically recover from certain
+ kinds of L1 cache errors, even though the L1 cache itself may not
+ support error correction. These errors should not result in any kind
+ of corruption, but their presence is nevertheless an indication of
+ poor system health. To cause the kernel to panic whenever a
+ recoverable L1 cache error is detected, say 'Y' here. This may be
+ useful as a debugging technique if general system instability is
+ suspected.
+
+ For production builds, you should definitely say 'N' here.
+
config MSM_L1_ERR_LOG
bool "Log CPU ERP events to system memory"
depends on MSM_CACHE_ERP
diff --git a/arch/arm/mach-msm/cache_erp.c b/arch/arm/mach-msm/cache_erp.c
index 8a73c84..6b8f58b 100644
--- a/arch/arm/mach-msm/cache_erp.c
+++ b/arch/arm/mach-msm/cache_erp.c
@@ -20,6 +20,7 @@
#include <linux/io.h>
#include <mach/msm-krait-l2-accessors.h>
#include <mach/msm_iomap.h>
+#include <mach/socinfo.h>
#include <asm/cputype.h>
#include "acpuclock.h"
@@ -32,6 +33,8 @@
#define CESR_TLBMH BIT(16)
#define CESR_I_MASK 0x000000CC
+#define CESR_VALID_MASK 0x000100FF
+
/* Print a message for everything but TLB MH events */
#define CESR_PRINT_MASK 0x000000FF
@@ -64,6 +67,12 @@
#define ERP_L1_ERR(a) do { } while (0)
#endif
+#ifdef CONFIG_MSM_L1_RECOV_ERR_PANIC
+#define ERP_L1_RECOV_ERR(a) panic(a)
+#else
+#define ERP_L1_RECOV_ERR(a) do { } while (0)
+#endif
+
#ifdef CONFIG_MSM_L2_ERP_PORT_PANIC
#define ERP_PORT_ERR(a) panic(a)
#else
@@ -319,8 +328,13 @@
/* Clear the interrupt bits we processed */
write_cesr(cesr);
- if (print_regs)
- ERP_L1_ERR("L1 cache error detected");
+ if (print_regs) {
+ if ((cesr & (~CESR_I_MASK & CESR_VALID_MASK)) ||
+ cpu_is_krait_v1() || cpu_is_krait_v2())
+ ERP_L1_ERR("L1 nonrecoverable cache error detected");
+ else
+ ERP_L1_RECOV_ERR("L1 recoverable error detected\n");
+ }
return IRQ_HANDLED;
}