Skip to content

Commit ad98dd1

Browse files
ozbenhpaulusmack
authored andcommitted
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 <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent 8f6a9f0 commit ad98dd1

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -989,13 +989,14 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
989989
beq no_xive
990990
ld r11, VCPU_XIVE_SAVED_STATE(r4)
991991
li r9, TM_QW1_OS
992-
stdcix r11,r9,r10
993992
eieio
993+
stdcix r11,r9,r10
994994
lwz r11, VCPU_XIVE_CAM_WORD(r4)
995995
li r9, TM_QW1_OS + TM_WORD2
996996
stwcix r11,r9,r10
997997
li r9, 1
998998
stw r9, VCPU_XIVE_PUSHED(r4)
999+
eieio
9991000
no_xive:
10001001
#endif /* CONFIG_KVM_XICS */
10011002

@@ -1401,17 +1402,17 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
14011402
cmpldi cr0, r10, 0
14021403
beq 1f
14031404
/* First load to pull the context, we ignore the value */
1404-
lwzx r11, r7, r10
14051405
eieio
1406+
lwzx r11, r7, r10
14061407
/* Second load to recover the context state (Words 0 and 1) */
14071408
ldx r11, r6, r10
14081409
b 3f
14091410
2: ld r10, HSTATE_XIVE_TIMA_PHYS(r13)
14101411
cmpldi cr0, r10, 0
14111412
beq 1f
14121413
/* First load to pull the context, we ignore the value */
1413-
lwzcix r11, r7, r10
14141414
eieio
1415+
lwzcix r11, r7, r10
14151416
/* Second load to recover the context state (Words 0 and 1) */
14161417
ldcix r11, r6, r10
14171418
3: std r11, VCPU_XIVE_SAVED_STATE(r9)
@@ -1421,6 +1422,7 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */
14211422
stw r10, VCPU_XIVE_PUSHED(r9)
14221423
stb r10, (VCPU_XIVE_SAVED_STATE+3)(r9)
14231424
stb r0, (VCPU_XIVE_SAVED_STATE+4)(r9)
1425+
eieio
14241426
1:
14251427
#endif /* CONFIG_KVM_XICS */
14261428
/* Save more register state */

0 commit comments

Comments
 (0)