aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-10-15 17:37:54 -0400
committerPaul Mackerras <paulus@ozlabs.org>2017-10-15 17:46:46 -0400
commitad98dd1a75ac6a8b68cd2f7bf4676b65734f2a43 (patch)
treef1acd782e055017a8f12afccd7de5a9de76b532d
parent8f6a9f0d0604817f7c8d4376fd51718f1bf192ee (diff)
KVM: PPC: Book3S HV: Add more barriers in XIVE load/unload code
On POWER9 systems, we push the VCPU context onto the XIVE (eXternal Interrupt Virtualization Engine) hardware when entering a guest, and pull the context off the XIVE when exiting the guest. The push is done with cache-inhibited stores, and the pull with cache-inhibited loads. Testing has revealed that it is possible (though very rare) for the stores to get reordered with the loads so that we end up with the guest VCPU context still loaded on the XIVE after we have exited the guest. When that happens, it is possible for the same VCPU context to then get loaded on another CPU, which causes the machine to checkstop. To fix this, we add I/O barrier instructions (eieio) before and after the push and pull operations. As partial compensation for the potential slowdown caused by the extra barriers, we remove the eieio instructions between the two stores in the push operation, and between the two loads in the pull operation. (The architecture requires loads to cache-inhibited, guarded storage to be kept in order, and requires stores to cache-inhibited, guarded storage likewise to be kept in order, but allows such loads and stores to be reordered with respect to each other.) Reported-by: Carol L Soto <clsoto@us.ibm.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S8
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index c700bedccaab..42639fba89e8 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -989,13 +989,14 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
989 beq no_xive 989 beq no_xive
990 ld r11, VCPU_XIVE_SAVED_STATE(r4) 990 ld r11, VCPU_XIVE_SAVED_STATE(r4)
991 li r9, TM_QW1_OS 991 li r9, TM_QW1_OS
992 stdcix r11,r9,r10
993 eieio 992 eieio
993 stdcix r11,r9,r10
994 lwz r11, VCPU_XIVE_CAM_WORD(r4) 994 lwz r11, VCPU_XIVE_CAM_WORD(r4)
995 li r9, TM_QW1_OS + TM_WORD2 995 li r9, TM_QW1_OS + TM_WORD2
996 stwcix r11,r9,r10 996 stwcix r11,r9,r10
997 li r9, 1 997 li r9, 1
998 stw r9, VCPU_XIVE_PUSHED(r4) 998 stw r9, VCPU_XIVE_PUSHED(r4)
999 eieio
999no_xive: 1000no_xive:
1000#endif /* CONFIG_KVM_XICS */ 1001#endif /* CONFIG_KVM_XICS */
1001 1002
@@ -1401,8 +1402,8 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
1401 cmpldi cr0, r10, 0 1402 cmpldi cr0, r10, 0
1402 beq 1f 1403 beq 1f
1403 /* First load to pull the context, we ignore the value */ 1404 /* First load to pull the context, we ignore the value */
1404 lwzx r11, r7, r10
1405 eieio 1405 eieio
1406 lwzx r11, r7, r10
1406 /* Second load to recover the context state (Words 0 and 1) */ 1407 /* Second load to recover the context state (Words 0 and 1) */
1407 ldx r11, r6, r10 1408 ldx r11, r6, r10
1408 b 3f 1409 b 3f
@@ -1410,8 +1411,8 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
1410 cmpldi cr0, r10, 0 1411 cmpldi cr0, r10, 0
1411 beq 1f 1412 beq 1f
1412 /* First load to pull the context, we ignore the value */ 1413 /* First load to pull the context, we ignore the value */
1413 lwzcix r11, r7, r10
1414 eieio 1414 eieio
1415 lwzcix r11, r7, r10
1415 /* Second load to recover the context state (Words 0 and 1) */ 1416 /* Second load to recover the context state (Words 0 and 1) */
1416 ldcix r11, r6, r10 1417 ldcix r11, r6, r10
14173: std r11, VCPU_XIVE_SAVED_STATE(r9) 14183: std r11, VCPU_XIVE_SAVED_STATE(r9)
@@ -1421,6 +1422,7 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
1421 stw r10, VCPU_XIVE_PUSHED(r9) 1422 stw r10, VCPU_XIVE_PUSHED(r9)
1422 stb r10, (VCPU_XIVE_SAVED_STATE+3)(r9) 1423 stb r10, (VCPU_XIVE_SAVED_STATE+3)(r9)
1423 stb r0, (VCPU_XIVE_SAVED_STATE+4)(r9) 1424 stb r0, (VCPU_XIVE_SAVED_STATE+4)(r9)
1425 eieio
14241: 14261:
1425#endif /* CONFIG_KVM_XICS */ 1427#endif /* CONFIG_KVM_XICS */
1426 /* Save more register state */ 1428 /* Save more register state */