mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/5] CM error report fixes
@ 2015-09-22 17:26 Paul Burton
  2015-09-22 17:26 ` [PATCH 1/5] MIPS: clarify mips_cm_is64 documentation Paul Burton
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Paul Burton @ 2015-09-22 17:26 UTC (permalink / raw)
  To: linux-mips
  Cc: Paul Burton, linux-kernel, James Hogan, Markos Chandras, Ralf Baechle

This series fixes a few problems with support for the CM, in particular
relating to CM3 which has a 64 bit interface to the core. These issues
prevented reporting of CM errors (useful debug output when tracking the
source of a bus error) in some situations, and could cause further
exceptions.

Paul Burton (5):
  MIPS: clarify mips_cm_is64 documentation
  MIPS: don't read GCRs when a CM is not present
  MIPS: avoid buffer overrun in mips_cm_error_report
  MIPS: allow read64 GCR accessors to work on MIPS32 kernels
  MIPS: always read full 64 bit CM error GCRs for CM3

 arch/mips/include/asm/mips-cm.h | 27 ++++++++++++----
 arch/mips/kernel/mips-cm.c      | 71 ++++++++++++++++++++++-------------------
 2 files changed, 59 insertions(+), 39 deletions(-)

-- 
2.5.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] MIPS: clarify mips_cm_is64 documentation
  2015-09-22 17:26 [PATCH 0/5] CM error report fixes Paul Burton
@ 2015-09-22 17:26 ` Paul Burton
  2015-09-22 17:26 ` [PATCH 2/5] MIPS: don't read GCRs when a CM is not present Paul Burton
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Paul Burton @ 2015-09-22 17:26 UTC (permalink / raw)
  To: linux-mips
  Cc: Paul Burton, linux-kernel, James Hogan, Markos Chandras, Ralf Baechle

The documentation for mips_cm_is64 implied that the width of the CM GCRs
would change depending upon the CPU, which is not true. Reword the
explanation to be clearer that the GCR width is purely dependent upon
the version of the CM.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---

 arch/mips/include/asm/mips-cm.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index d75b75e..2a70b76 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -36,12 +36,12 @@ extern phys_addr_t __mips_cm_phys_base(void);
 /*
  * mips_cm_is64 - determine CM register width
  *
- * The CM register width is processor and CM specific. A 64-bit processor
- * usually has a 64-bit CM and a 32-bit one has a 32-bit CM but a 64-bit
- * processor could come with a 32-bit CM. Moreover, accesses on 64-bit CMs
- * can be done either using regular 64-bit load/store instructions, or 32-bit
- * load/store instruction on 32-bit register pairs. We opt for using 64-bit
- * accesses on 64-bit CMs and kernels and 32-bit in any other case.
+ * The CM register width is determined by the version of the CM, with CM3
+ * introducing 64 bit GCRs and all prior CM versions having 32 bit GCRs.
+ * However we may run a kernel built for MIPS32 on a system with 64 bit GCRs,
+ * or vice-versa. This variable indicates the width of the memory accesses
+ * that the kernel will perform to GCRs, which may differ from the actual
+ * width of the GCRs.
  *
  * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses.
  */
-- 
2.5.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/5] MIPS: don't read GCRs when a CM is not present
  2015-09-22 17:26 [PATCH 0/5] CM error report fixes Paul Burton
  2015-09-22 17:26 ` [PATCH 1/5] MIPS: clarify mips_cm_is64 documentation Paul Burton
@ 2015-09-22 17:26 ` Paul Burton
  2015-09-22 17:26 ` [PATCH 3/5] MIPS: avoid buffer overrun in mips_cm_error_report Paul Burton
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Paul Burton @ 2015-09-22 17:26 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton, Markos Chandras, Ralf Baechle, linux-kernel

Commit 3885c2b463f6 ("MIPS: CM: Add support for reporting CM cache
errors") leads to Malta boards unconditionally reading CM GCRs upon bus
errors, regardless of whether a CM is present. This is incorrect & will
lead to further exceptions. Fix by moving the GCR reads to after the
check for whether a CM is present.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---

 arch/mips/kernel/mips-cm.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index b8ceee5..10524ce 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -252,7 +252,6 @@ int mips_cm_probe(void)
 
 void mips_cm_error_report(void)
 {
-	unsigned long revision = mips_cm_revision();
 	/*
 	 * CM3 has a 64-bit Error cause register with 0:57 containing the error
 	 * info and 63:58 the error type. For old CMs, everything is contained
@@ -260,17 +259,21 @@ void mips_cm_error_report(void)
 	 * though the cm_error is u64, we will simply ignore the upper word
 	 * for CM2.
 	 */
-	u64 cm_error = read_gcr_error_cause();
-	int cm_error_cause_sft = CM_GCR_ERROR_CAUSE_ERRTYPE_SHF +
-				 ((revision >= CM_REV_CM3) ? 31 : 0);
-	unsigned long cm_addr = read_gcr_error_addr();
-	unsigned long cm_other = read_gcr_error_mult();
-	int ocause, cause;
+	u64 cm_error;
+	unsigned long revision, cm_addr, cm_other;
+	int ocause, cause, cm_error_cause_sft;
 	char buf[256];
 
 	if (!mips_cm_present())
 		return;
 
+	revision = mips_cm_revision();
+	cm_error = read_gcr_error_cause();
+	cm_addr = read_gcr_error_addr();
+	cm_other = read_gcr_error_mult();
+
+	cm_error_cause_sft = CM_GCR_ERROR_CAUSE_ERRTYPE_SHF +
+				 ((revision >= CM_REV_CM3) ? 31 : 0);
 	cause = cm_error >> cm_error_cause_sft;
 
 	if (!cause)
-- 
2.5.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/5] MIPS: avoid buffer overrun in mips_cm_error_report
  2015-09-22 17:26 [PATCH 0/5] CM error report fixes Paul Burton
  2015-09-22 17:26 ` [PATCH 1/5] MIPS: clarify mips_cm_is64 documentation Paul Burton
  2015-09-22 17:26 ` [PATCH 2/5] MIPS: don't read GCRs when a CM is not present Paul Burton
@ 2015-09-22 17:26 ` Paul Burton
  2015-09-22 17:26 ` [PATCH 4/5] MIPS: allow read64 GCR accessors to work on MIPS32 kernels Paul Burton
  2015-09-22 17:26 ` [PATCH 5/5] MIPS: always read full 64 bit CM error GCRs for CM3 Paul Burton
  4 siblings, 0 replies; 6+ messages in thread
From: Paul Burton @ 2015-09-22 17:26 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton, Markos Chandras, Ralf Baechle, linux-kernel

Commit 3885c2b463f6 ("MIPS: CM: Add support for reporting CM cache
errors") added cases for decoding errors reported by CM3, but leaves the
buf variable which is printed as a string uninitialised for cause values
other than 1, 2 or 3. Fix by ensuring the buf variable is initialised to
an empty string in such cases.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---

 arch/mips/kernel/mips-cm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 10524ce..88a8e21 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -366,6 +366,8 @@ void mips_cm_error_report(void)
 				 cm3_cmd_group[cmd_group_bits],
 				 cm3_cca_bits, 1 << mcp_bits,
 				 cm3_tr[cm3_tr_bits], sched_bit);
+		} else {
+			buf[0] = 0;
 		}
 
 		pr_err("CM_ERROR=%llx %s <%s>\n", cm_error,
-- 
2.5.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/5] MIPS: allow read64 GCR accessors to work on MIPS32 kernels
  2015-09-22 17:26 [PATCH 0/5] CM error report fixes Paul Burton
                   ` (2 preceding siblings ...)
  2015-09-22 17:26 ` [PATCH 3/5] MIPS: avoid buffer overrun in mips_cm_error_report Paul Burton
@ 2015-09-22 17:26 ` Paul Burton
  2015-09-22 17:26 ` [PATCH 5/5] MIPS: always read full 64 bit CM error GCRs for CM3 Paul Burton
  4 siblings, 0 replies; 6+ messages in thread
From: Paul Burton @ 2015-09-22 17:26 UTC (permalink / raw)
  To: linux-mips
  Cc: Paul Burton, linux-kernel, James Hogan, Markos Chandras, Ralf Baechle

If we run a MIPS32 kernel on a system using CM3 we may still need to
access 64 bit GCRs, as will be done in later patches. Allow this by
having the read64_gcr_* accessor functions perform 2 x 32 bit reads on
those systems.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---

 arch/mips/include/asm/mips-cm.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 2a70b76..b9df4b2 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -125,7 +125,17 @@ static inline u32 read32_gcr_##name(void)			\
 								\
 static inline u64 read64_gcr_##name(void)			\
 {								\
-	return __raw_readq(addr_gcr_##name());			\
+	void __iomem *addr = addr_gcr_##name();			\
+	u64 ret;						\
+								\
+	if (mips_cm_is64) {					\
+		ret = __raw_readq(addr);			\
+	} else {						\
+		ret = __raw_readl(addr);			\
+		ret |= (u64)__raw_readl(addr + 0x4) << 32;	\
+	}							\
+								\
+	return ret;						\
 }								\
 								\
 static inline unsigned long read_gcr_##name(void)		\
-- 
2.5.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 5/5] MIPS: always read full 64 bit CM error GCRs for CM3
  2015-09-22 17:26 [PATCH 0/5] CM error report fixes Paul Burton
                   ` (3 preceding siblings ...)
  2015-09-22 17:26 ` [PATCH 4/5] MIPS: allow read64 GCR accessors to work on MIPS32 kernels Paul Burton
@ 2015-09-22 17:26 ` Paul Burton
  4 siblings, 0 replies; 6+ messages in thread
From: Paul Burton @ 2015-09-22 17:26 UTC (permalink / raw)
  To: linux-mips
  Cc: Paul Burton, linux-kernel, James Hogan, Markos Chandras, Ralf Baechle

CM3 has 64 bit GCR_ERROR_* registers, but the code in
mips_cm_error_report was previously only reading 32 bits of it in MIPS32
kernels. Fix by splitting the reads for CM2 & CM3, and making use of the
read64_ variants of the accessor function for CM3.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---

 arch/mips/include/asm/mips-cm.h |  3 ++
 arch/mips/kernel/mips-cm.c      | 70 +++++++++++++++++++++--------------------
 2 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index b9df4b2..82e7e92 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -11,6 +11,7 @@
 #ifndef __MIPS_ASM_MIPS_CM_H__
 #define __MIPS_ASM_MIPS_CM_H__
 
+#include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/types.h>
@@ -259,6 +260,8 @@ BUILD_CM_Cx_R_(tcid_8_priority,	0x80)
 /* GCR_ERROR_CAUSE register fields */
 #define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF		27
 #define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK		(_ULCAST_(0x1f) << 27)
+#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF		58
+#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK		GENMASK_ULL(63, 58)
 #define CM_GCR_ERROR_CAUSE_ERRINFO_SHF		0
 #define CM_GCR_ERROR_CAUSE_ERRINGO_MSK		(_ULCAST_(0x7ffffff) << 0)
 
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 88a8e21..02f7d7a 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -252,36 +252,26 @@ int mips_cm_probe(void)
 
 void mips_cm_error_report(void)
 {
-	/*
-	 * CM3 has a 64-bit Error cause register with 0:57 containing the error
-	 * info and 63:58 the error type. For old CMs, everything is contained
-	 * in a single 32-bit register (0:26 and 31:27 respectively). Even
-	 * though the cm_error is u64, we will simply ignore the upper word
-	 * for CM2.
-	 */
-	u64 cm_error;
-	unsigned long revision, cm_addr, cm_other;
-	int ocause, cause, cm_error_cause_sft;
+	u64 cm_error, cm_addr, cm_other;
+	unsigned long revision;
+	int ocause, cause;
 	char buf[256];
 
 	if (!mips_cm_present())
 		return;
 
 	revision = mips_cm_revision();
-	cm_error = read_gcr_error_cause();
-	cm_addr = read_gcr_error_addr();
-	cm_other = read_gcr_error_mult();
 
-	cm_error_cause_sft = CM_GCR_ERROR_CAUSE_ERRTYPE_SHF +
-				 ((revision >= CM_REV_CM3) ? 31 : 0);
-	cause = cm_error >> cm_error_cause_sft;
+	if (revision < CM_REV_CM3) { /* CM2 */
+		cm_error = read_gcr_error_cause();
+		cm_addr = read_gcr_error_addr();
+		cm_other = read_gcr_error_mult();
+		cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
+		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
 
-	if (!cause)
-		/* All good */
-		return;
+		if (!cause)
+			return;
 
-	ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
-	if (revision < CM_REV_CM3) { /* CM2 */
 		if (cause < 16) {
 			unsigned long cca_bits = (cm_error >> 15) & 7;
 			unsigned long tr_bits = (cm_error >> 12) & 7;
@@ -313,18 +303,30 @@ void mips_cm_error_report(void)
 		}
 			pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error,
 			       cm2_causes[cause], buf);
-		pr_err("CM_ADDR =%08lx\n", cm_addr);
-		pr_err("CM_OTHER=%08lx %s\n", cm_other, cm2_causes[ocause]);
+		pr_err("CM_ADDR =%08llx\n", cm_addr);
+		pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]);
 	} else { /* CM3 */
-	/* Used by cause == {1,2,3} */
-		unsigned long core_id_bits = (cm_error >> 22) & 0xf;
-		unsigned long vp_id_bits = (cm_error >> 18) & 0xf;
-		unsigned long cmd_bits = (cm_error >> 14) & 0xf;
-		unsigned long cmd_group_bits = (cm_error >> 11) & 0xf;
-		unsigned long cm3_cca_bits = (cm_error >> 8) & 7;
-		unsigned long mcp_bits = (cm_error >> 5) & 0xf;
-		unsigned long cm3_tr_bits = (cm_error >> 1) & 0xf;
-		unsigned long sched_bit = cm_error & 0x1;
+		ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
+		ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
+
+		cm_error = read64_gcr_error_cause();
+		cm_addr = read64_gcr_error_addr();
+		cm_other = read64_gcr_error_mult();
+		cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF;
+		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+
+		if (!cause)
+			return;
+
+		/* Used by cause == {1,2,3} */
+		core_id_bits = (cm_error >> 22) & 0xf;
+		vp_id_bits = (cm_error >> 18) & 0xf;
+		cmd_bits = (cm_error >> 14) & 0xf;
+		cmd_group_bits = (cm_error >> 11) & 0xf;
+		cm3_cca_bits = (cm_error >> 8) & 7;
+		mcp_bits = (cm_error >> 5) & 0xf;
+		cm3_tr_bits = (cm_error >> 1) & 0xf;
+		sched_bit = cm_error & 0x1;
 
 		if (cause == 1 || cause == 3) { /* Tag ECC */
 			unsigned long tag_ecc = (cm_error >> 57) & 0x1;
@@ -372,8 +374,8 @@ void mips_cm_error_report(void)
 
 		pr_err("CM_ERROR=%llx %s <%s>\n", cm_error,
 		       cm3_causes[cause], buf);
-		pr_err("CM_ADDR =%lx\n", cm_addr);
-		pr_err("CM_OTHER=%lx %s\n", cm_other, cm3_causes[ocause]);
+		pr_err("CM_ADDR =%llx\n", cm_addr);
+		pr_err("CM_OTHER=%llx %s\n", cm_other, cm3_causes[ocause]);
 	}
 
 	/* reprime cause register */
-- 
2.5.3


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-09-22 17:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-22 17:26 [PATCH 0/5] CM error report fixes Paul Burton
2015-09-22 17:26 ` [PATCH 1/5] MIPS: clarify mips_cm_is64 documentation Paul Burton
2015-09-22 17:26 ` [PATCH 2/5] MIPS: don't read GCRs when a CM is not present Paul Burton
2015-09-22 17:26 ` [PATCH 3/5] MIPS: avoid buffer overrun in mips_cm_error_report Paul Burton
2015-09-22 17:26 ` [PATCH 4/5] MIPS: allow read64 GCR accessors to work on MIPS32 kernels Paul Burton
2015-09-22 17:26 ` [PATCH 5/5] MIPS: always read full 64 bit CM error GCRs for CM3 Paul Burton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®