diff mbox

xive: Workaround a problem with indirect TM access

Message ID 20170502092112.13060-1-benh@kernel.crashing.org
State Accepted
Headers show

Commit Message

Benjamin Herrenschmidt May 2, 2017, 9:21 a.m. UTC
A HW issue can cause accesses to the content of the indirect data
area to pass the actual selection of the target thread. The
workaround is to read the PC_TCTXT_INDIR0 register back before
accessing the data area.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 hw/xive.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

Comments

Stewart Smith May 3, 2017, 6:43 a.m. UTC | #1
Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> A HW issue can cause accesses to the content of the indirect data
> area to pass the actual selection of the target thread. The
> workaround is to read the PC_TCTXT_INDIR0 register back before
> accessing the data area.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>  hw/xive.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)

Merged to master as of fa70adcb9d139bd9709681ea138bb2b10a08ff2a
diff mbox

Patch

diff --git a/hw/xive.c b/hw/xive.c
index 1952ce6..5a54730 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -3775,6 +3775,11 @@  static void xive_cleanup_cpu_tma(struct cpu_thread *c)
 		  PC_TCTXT_INDIR_VALID |
 		  SETFIELD(PC_TCTXT_INDIR_THRDID, 0ull, c->pir & 0xff));
 
+	/* Workaround for HW issue: Need to read the above register
+	 * back before doing the subsequent accesses
+	 */
+	xive_regr(x, PC_TCTXT_INDIR0);
+
 	/* Pull user context, OS context and Pool context if any */
 	in_be32(ind_tm_base + TM_SPC_PULL_USR_CTX);
 	in_be32(ind_tm_base + TM_SPC_PULL_OS_CTX);
@@ -4233,6 +4238,11 @@  static int64_t opal_xive_dump_tm(uint32_t offset, const char *n, uint32_t pir)
 		  PC_TCTXT_INDIR_VALID |
 		  SETFIELD(PC_TCTXT_INDIR_THRDID, 0ull, pir & 0xff));
 
+	/* Workaround for HW issue: Need to read the above register
+	 * back before doing the subsequent accesses
+	 */
+	xive_regr(x, PC_TCTXT_INDIR0);
+
 	v0 = in_be64(ind_tm_base + offset);
 	v1 = in_be64(ind_tm_base + offset + 8);
 	prlog(PR_INFO, "CPU[%04x]: TM state for QW %s\n", pir, n);