diff mbox

[v2,8/9] opal: Recover from TFMR SPURR/PURR parity error.

Message ID 20150311103249.10209.5309.stgit@mars.in.ibm.com
State Accepted
Headers show

Commit Message

Mahesh J Salgaonkar March 11, 2015, 10:33 a.m. UTC
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

Recovery process for SPURR/PURR parity error:
- Set SPURR/PURR Register with valid value or zero
- Reset TFMR SPURR/PURR parity error bit.

To inject TFMR PURR parity error issue:
        $ putscom pu.ex 10013281 0004080000000000 -all

To inject TFMR SPURR parity error issue:
        $ putscom pu.ex 10013281 0005080000000000 -all

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
 hw/chiptod.c        |   24 ++++++++++++++++++++++++
 include/processor.h |    2 ++
 2 files changed, 26 insertions(+)
diff mbox

Patch

diff --git a/hw/chiptod.c b/hw/chiptod.c
index 1c77cb7..d51ce2b 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -705,6 +705,28 @@  static bool tfmr_recover_non_tb_errors(uint64_t tfmr)
 		tfmr_reset_errors |= SPR_TFMR_DEC_PARITY_ERR;
 	}
 
+	/*
+	 * Reset PURR/SPURR to recover. We also need help from KVM
+	 * layer to handle this change in PURR/SPURR. That needs
+	 * to be handled in kernel KVM layer. For now, to recover just
+	 * reset it.
+	 */
+	if (tfmr & SPR_TFMR_PURR_PARITY_ERR) {
+		/* set PURR register with sane value or reset it. */
+		mtspr(SPR_PURR, 0);
+
+		/* set bit 57 to clear TFMR PURR parity error. */
+		tfmr_reset_errors |= SPR_TFMR_PURR_PARITY_ERR;
+	}
+
+	if (tfmr & SPR_TFMR_SPURR_PARITY_ERR) {
+		/* set PURR register with sane value or reset it. */
+		mtspr(SPR_SPURR, 0);
+
+		/* set bit 58 to clear TFMR PURR parity error. */
+		tfmr_reset_errors |= SPR_TFMR_SPURR_PARITY_ERR;
+	}
+
 	/* Write TFMR twice to clear the error */
 	mtspr(SPR_TFMR, base_tfmr | tfmr_reset_errors);
 	mtspr(SPR_TFMR, base_tfmr | tfmr_reset_errors);
@@ -857,6 +879,8 @@  int chiptod_recover_tb_errors(void)
 	 * Now that TB is running, check for TFMR non-TB errors.
 	 */
 	if ((tfmr & SPR_TFMR_HDEC_PARITY_ERROR) ||
+		(tfmr & SPR_TFMR_PURR_PARITY_ERR) ||
+		(tfmr & SPR_TFMR_SPURR_PARITY_ERR) ||
 		(tfmr & SPR_TFMR_DEC_PARITY_ERR)) {
 		if (!tfmr_recover_non_tb_errors(tfmr)) {
 			rc = 0;
diff --git a/include/processor.h b/include/processor.h
index 30527b1..aaf7732 100644
--- a/include/processor.h
+++ b/include/processor.h
@@ -64,6 +64,8 @@ 
 #define SPR_PVR		0x11f	/* RO: Processor version register */
 #define SPR_HSPRG0	0x130	/* RW: Hypervisor scratch 0 */
 #define SPR_HSPRG1	0x131	/* RW: Hypervisor scratch 1 */
+#define SPR_SPURR	0x134	/* RW: Scaled Processor Utilization Resource */
+#define SPR_PURR	0x135	/* RW: Processor Utilization Resource reg */
 #define SPR_HDEC	0x136	/* RW: Hypervisor Decrementer */
 #define SPR_HSRR0	0x13a	/* RW: HV Exception save/restore reg 0 */
 #define SPR_HSRR1	0x13b	/* RW: HV Exception save/restore reg 1 */