KVM: PPC: Book3S HV P9: Fix guest TM support

The conversion to C introduced several bugs in TM handling that can
cause host crashes with TM bad thing interrupts. Mostly just simple
typos or missed logic in the conversion that got through due to my
not testing TM in the guest sufficiently.

- Early TM emulation for the softpatch interrupt should be done if fake
suspend mode is _not_ active.

- Early TM emulation wants to return immediately to the guest so as to
not doom transactions unnecessarily.

- And if exiting from the guest, the host MSR should include the TM[S]
bit if the guest was T/S, before it is treclaimed.

After this fix, all the TM selftests pass when running on a P9 processor
that implements TM with softpatch interrupt.

Fixes: 89d35b2391015 ("KVM: PPC: Book3S HV P9: Implement the rest of the P9 path in C")
Reported-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210712013650.376325-1-npiggin@gmail.com

authored by Nicholas Piggin and committed by Michael Ellerman e44fbdb6 e73f0f0e

+22 -3
+22 -3
arch/powerpc/kvm/book3s_hv_p9_entry.c
··· 317 317 */ 318 318 mtspr(SPRN_HDEC, hdec); 319 319 320 + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM 321 + tm_return_to_guest: 322 + #endif 320 323 mtspr(SPRN_DAR, vcpu->arch.shregs.dar); 321 324 mtspr(SPRN_DSISR, vcpu->arch.shregs.dsisr); 322 325 mtspr(SPRN_SRR0, vcpu->arch.shregs.srr0); ··· 418 415 * is in real suspend mode and is trying to transition to 419 416 * transactional mode. 420 417 */ 421 - if (local_paca->kvm_hstate.fake_suspend && 418 + if (!local_paca->kvm_hstate.fake_suspend && 422 419 (vcpu->arch.shregs.msr & MSR_TS_S)) { 423 420 if (kvmhv_p9_tm_emulation_early(vcpu)) { 424 - /* Prevent it being handled again. */ 425 - trap = 0; 421 + /* 422 + * Go straight back into the guest with the 423 + * new NIP/MSR as set by TM emulation. 424 + */ 425 + mtspr(SPRN_HSRR0, vcpu->arch.regs.nip); 426 + mtspr(SPRN_HSRR1, vcpu->arch.shregs.msr); 427 + 428 + /* 429 + * tm_return_to_guest re-loads SRR0/1, DAR, 430 + * DSISR after RI is cleared, in case they had 431 + * been clobbered by a MCE. 432 + */ 433 + __mtmsrd(0, 1); /* clear RI */ 434 + goto tm_return_to_guest; 426 435 } 427 436 } 428 437 #endif ··· 514 499 * If we are in real mode, only switch MMU on after the MMU is 515 500 * switched to host, to avoid the P9_RADIX_PREFETCH_BUG. 516 501 */ 502 + if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && 503 + vcpu->arch.shregs.msr & MSR_TS_MASK) 504 + msr |= MSR_TS_S; 505 + 517 506 __mtmsrd(msr, 0); 518 507 519 508 end_timing(vcpu);