浏览代码

KVM: PPC: Book3S HV: Work around TEXASR bug in fake suspend state

This works around a hardware bug in "Nimbus" POWER9 DD2.2 processors,
where the contents of the TEXASR can get corrupted while a thread is
in fake suspend state.  The workaround is for the instruction emulation
code to use the value saved at the most recent guest exit in real
suspend mode.  We achieve this by simply not saving the TEXASR into
the vcpu struct on an exit in fake suspend state.  We also have to
take care to set the orig_texasr field only on guest exit in real
suspend state.

This also means that on guest entry in fake suspend state, TEXASR
will be restored to the value it had on the last exit in real suspend
state, effectively counteracting any hardware-caused corruption.  This
works because TEXASR may not be written in suspend state.

With this, the guest might see the wrong values in TEXASR if it reads
it while in suspend state, but will see the correct value in
non-transactional state (e.g. after a treclaim), and treclaim will
work correctly.

With this workaround, the code will actually run slightly faster, and
will operate correctly on systems without the TEXASR bug (since TEXASR
may not be written in suspend state, and is only changed by failure
recording, which will have already been done before we get into fake
suspend state).  Therefore these changes are not made subject to a CPU
feature bit.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Paul Mackerras 7 年之前
父节点
当前提交
681c617b7c
共有 1 个文件被更改,包括 10 次插入7 次删除
  1. 10 7
      arch/powerpc/kvm/book3s_hv_rmhandlers.S

+ 10 - 7
arch/powerpc/kvm/book3s_hv_rmhandlers.S

@@ -3117,10 +3117,6 @@ kvmppc_save_tm:
 	li	r3, TM_CAUSE_KVM_RESCHED
 	li	r3, TM_CAUSE_KVM_RESCHED
 
 
 BEGIN_FTR_SECTION
 BEGIN_FTR_SECTION
-	/* Emulation of the treclaim instruction needs TEXASR before treclaim */
-	mfspr	r6, SPRN_TEXASR
-	std	r6, VCPU_ORIG_TEXASR(r9)
-
 	lbz	r0, HSTATE_FAKE_SUSPEND(r13) /* Were we fake suspended? */
 	lbz	r0, HSTATE_FAKE_SUSPEND(r13) /* Were we fake suspended? */
 	cmpwi	r0, 0
 	cmpwi	r0, 0
 	beq	3f
 	beq	3f
@@ -3130,7 +3126,12 @@ BEGIN_FTR_SECTION_NESTED(96)
 	bl	pnv_power9_force_smt4_catch
 	bl	pnv_power9_force_smt4_catch
 END_FTR_SECTION_NESTED(CPU_FTR_P9_TM_XER_SO_BUG, CPU_FTR_P9_TM_XER_SO_BUG, 96)
 END_FTR_SECTION_NESTED(CPU_FTR_P9_TM_XER_SO_BUG, CPU_FTR_P9_TM_XER_SO_BUG, 96)
 	nop
 	nop
+	b	6f
 3:
 3:
+	/* Emulation of the treclaim instruction needs TEXASR before treclaim */
+	mfspr	r6, SPRN_TEXASR
+	std	r6, VCPU_ORIG_TEXASR(r9)
+6:
 END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_HV_ASSIST)
 END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_HV_ASSIST)
 
 
 	/* Clear the MSR RI since r1, r13 are all going to be foobar. */
 	/* Clear the MSR RI since r1, r13 are all going to be foobar. */
@@ -3176,7 +3177,8 @@ END_FTR_SECTION_NESTED(CPU_FTR_P9_TM_XER_SO_BUG, CPU_FTR_P9_TM_XER_SO_BUG, 96)
 	andc	r3, r3, r0
 	andc	r3, r3, r0
 	mtspr	SPRN_PSSCR, r3
 	mtspr	SPRN_PSSCR, r3
 	ld	r9, HSTATE_KVM_VCPU(r13)
 	ld	r9, HSTATE_KVM_VCPU(r13)
-	b	1f
+	/* Don't save TEXASR, use value from last exit in real suspend state */
+	b	11f
 2:
 2:
 END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_HV_ASSIST)
 END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_HV_ASSIST)
 
 
@@ -3250,12 +3252,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_HV_ASSIST)
 	 * change these outside of a transaction, so they must always be
 	 * change these outside of a transaction, so they must always be
 	 * context switched.
 	 * context switched.
 	 */
 	 */
+	mfspr	r7, SPRN_TEXASR
+	std	r7, VCPU_TEXASR(r9)
+11:
 	mfspr	r5, SPRN_TFHAR
 	mfspr	r5, SPRN_TFHAR
 	mfspr	r6, SPRN_TFIAR
 	mfspr	r6, SPRN_TFIAR
-	mfspr	r7, SPRN_TEXASR
 	std	r5, VCPU_TFHAR(r9)
 	std	r5, VCPU_TFHAR(r9)
 	std	r6, VCPU_TFIAR(r9)
 	std	r6, VCPU_TFIAR(r9)
-	std	r7, VCPU_TEXASR(r9)
 
 
 	addi	r1, r1, PPC_MIN_STKFRM
 	addi	r1, r1, PPC_MIN_STKFRM
 	ld	r0, PPC_LR_STKOFF(r1)
 	ld	r0, PPC_LR_STKOFF(r1)