Skip to content

Commit 7ae9bda

Browse files
sjitindarsinghpaulusmack
authored andcommitted
KVM: PPC: Book3S HV: Handle virtual mode in XIVE VCPU push code
The code in book3s_hv_rmhandlers.S that pushes the XIVE virtual CPU context to the hardware currently assumes it is being called in real mode, which is usually true. There is however a path by which it can be executed in virtual mode, in the case where indep_threads_mode = N. A virtual CPU executing on an offline secondary thread can take a hypervisor interrupt in virtual mode and return from the kvmppc_hv_entry() call after the kvm_secondary_got_guest label. It is possible for it to be given another vcpu to execute before it gets to execute the stop instruction. In that case it will call kvmppc_hv_entry() for the second VCPU in virtual mode, and the XIVE vCPU push code will be executed in virtual mode. The result in that case will be a host crash due to an unexpected data storage interrupt caused by executing the stdcix instruction in virtual mode. This fixes it by adding a code path for virtual mode, which uses the virtual TIMA pointer and normal load/store instructions. [[email protected] - wrote patch description] Signed-off-by: Suraj Jitindar Singh <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent 1f80ba3 commit 7ae9bda

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -969,17 +969,27 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
969969

970970
#ifdef CONFIG_KVM_XICS
971971
/* We are entering the guest on that thread, push VCPU to XIVE */
972-
ld r10, HSTATE_XIVE_TIMA_PHYS(r13)
973-
cmpldi cr0, r10, 0
974-
beq no_xive
975972
ld r11, VCPU_XIVE_SAVED_STATE(r4)
976973
li r9, TM_QW1_OS
974+
lwz r8, VCPU_XIVE_CAM_WORD(r4)
975+
li r7, TM_QW1_OS + TM_WORD2
976+
mfmsr r0
977+
andi. r0, r0, MSR_DR /* in real mode? */
978+
beq 2f
979+
ld r10, HSTATE_XIVE_TIMA_VIRT(r13)
980+
cmpldi cr1, r10, 0
981+
beq cr1, no_xive
982+
eieio
983+
stdx r11,r9,r10
984+
stwx r8,r7,r10
985+
b 3f
986+
2: ld r10, HSTATE_XIVE_TIMA_PHYS(r13)
987+
cmpldi cr1, r10, 0
988+
beq cr1, no_xive
977989
eieio
978990
stdcix r11,r9,r10
979-
lwz r11, VCPU_XIVE_CAM_WORD(r4)
980-
li r9, TM_QW1_OS + TM_WORD2
981-
stwcix r11,r9,r10
982-
li r9, 1
991+
stwcix r8,r7,r10
992+
3: li r9, 1
983993
stb r9, VCPU_XIVE_PUSHED(r4)
984994
eieio
985995

@@ -998,12 +1008,16 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
9981008
* on, we mask it.
9991009
*/
10001010
lbz r0, VCPU_XIVE_ESC_ON(r4)
1001-
cmpwi r0,0
1002-
beq 1f
1003-
ld r10, VCPU_XIVE_ESC_RADDR(r4)
1011+
cmpwi cr1, r0,0
1012+
beq cr1, 1f
10041013
li r9, XIVE_ESB_SET_PQ_01
1014+
beq 4f /* in real mode? */
1015+
ld r10, VCPU_XIVE_ESC_VADDR(r4)
1016+
ldx r0, r10, r9
1017+
b 5f
1018+
4: ld r10, VCPU_XIVE_ESC_RADDR(r4)
10051019
ldcix r0, r10, r9
1006-
sync
1020+
5: sync
10071021

10081022
/* We have a possible subtle race here: The escalation interrupt might
10091023
* have fired and be on its way to the host queue while we mask it,

0 commit comments

Comments
 (0)