[PATCH v2 24/30] KVM: PPC: Book3S PR: Support TAR handling for PR KVM HTM.
From: <hidden>
Date: 2018-02-27 18:01:40
Also in:
kvm
Subsystem:
kernel virtual machine for powerpc (kvm/powerpc), linux for powerpc (32-bit and 64-bit), the rest · Maintainers:
Madhavan Srinivasan, Linus Torvalds
From: Simon Guo <redacted> Currently guest kernel doesn't handle TAR fac unavailable and it always runs with TAR bit on. PR KVM will lazily enable TAR. TAR is not a frequent-use reg and it is not included in SVCPU struct. Due to the above, the checkpointed TAR val might be a bogus TAR val. To solve this issue, we will make vcpu->arch.fscr tar bit consistent with shadow_fscr when TM enabled. At the end of emulating treclaim., the correct TAR val need to be loaded into reg if FSCR_TAR bit is on. At the beginning of emulating trechkpt., TAR needs to be flushed so that the right tar val can be copy into tar_tm. Tested with: tools/testing/selftests/powerpc/tm/tm-tar tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar (remove DSCR/PPR related testing). Signed-off-by: Simon Guo <redacted> --- arch/powerpc/include/asm/kvm_book3s.h | 2 ++ arch/powerpc/kvm/book3s_emulate.c | 4 ++++ arch/powerpc/kvm/book3s_pr.c | 21 ++++++++++++++++----- arch/powerpc/kvm/tm.S | 16 ++++++++++++++-- 4 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index 5873906..4148a3d 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h@@ -267,6 +267,8 @@ static inline void kvmppc_save_tm_sprs(struct kvm_vcpu *vcpu) {} static inline void kvmppc_restore_tm_sprs(struct kvm_vcpu *vcpu) {} #endif +void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac); + extern int kvm_irq_bypass; static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 6c5ef8c..8fd3af6a 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -173,6 +173,9 @@ static void kvmppc_emulate_treclaim(struct kvm_vcpu *vcpu, int ra_val) guest_msr &= ~(MSR_TS_MASK); kvmppc_set_msr(vcpu, guest_msr); preempt_enable(); + + if (vcpu->arch.shadow_fscr & FSCR_TAR) + mtspr(SPRN_TAR, vcpu->arch.tar); } static void kvmppc_emulate_trchkpt(struct kvm_vcpu *vcpu)
@@ -185,6 +188,7 @@ static void kvmppc_emulate_trchkpt(struct kvm_vcpu *vcpu) * copy. */ kvmppc_giveup_ext(vcpu, MSR_VSX); + kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); kvmppc_copyto_vcpu_tm(vcpu); kvmppc_save_tm_sprs(vcpu);
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 29ec92e..19f9934 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c@@ -55,7 +55,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, ulong msr); -static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac); +static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac); /* Some compatibility defines */ #ifdef CONFIG_PPC_BOOK3S_32
@@ -348,6 +348,7 @@ void kvmppc_save_tm_pr(struct kvm_vcpu *vcpu) return; } + kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); kvmppc_giveup_ext(vcpu, MSR_VSX); preempt_disable();
@@ -359,8 +360,11 @@ void kvmppc_restore_tm_pr(struct kvm_vcpu *vcpu) { if (!MSR_TM_ACTIVE(kvmppc_get_msr(vcpu))) { kvmppc_restore_tm_sprs(vcpu); - if (kvmppc_get_msr(vcpu) & MSR_TM) + if (kvmppc_get_msr(vcpu) & MSR_TM) { kvmppc_handle_lost_math_exts(vcpu); + if (vcpu->arch.fscr & FSCR_TAR) + kvmppc_handle_fac(vcpu, FSCR_TAR_LG); + } return; }
@@ -368,9 +372,11 @@ void kvmppc_restore_tm_pr(struct kvm_vcpu *vcpu) _kvmppc_restore_tm_pr(vcpu, kvmppc_get_msr(vcpu)); preempt_enable(); - if (kvmppc_get_msr(vcpu) & MSR_TM) + if (kvmppc_get_msr(vcpu) & MSR_TM) { kvmppc_handle_lost_math_exts(vcpu); - + if (vcpu->arch.fscr & FSCR_TAR) + kvmppc_handle_fac(vcpu, FSCR_TAR_LG); + } } #endif
@@ -828,7 +834,7 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) } /* Give up facility (TAR / EBB / DSCR) */ -static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac) +void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac) { #ifdef CONFIG_PPC_BOOK3S_64 if (!(vcpu->arch.shadow_fscr & (1ULL << fac))) {
@@ -1029,7 +1035,12 @@ void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr) if ((vcpu->arch.fscr & FSCR_TAR) && !(fscr & FSCR_TAR)) { /* TAR got dropped, drop it in shadow too */ kvmppc_giveup_fac(vcpu, FSCR_TAR_LG); + } else if (!(vcpu->arch.fscr & FSCR_TAR) && (fscr & FSCR_TAR)) { + vcpu->arch.fscr = fscr; + kvmppc_handle_fac(vcpu, FSCR_TAR_LG); + return; } + vcpu->arch.fscr = fscr; } #endif
diff --git a/arch/powerpc/kvm/tm.S b/arch/powerpc/kvm/tm.S
index 269dd11..aa84e4a 100644
--- a/arch/powerpc/kvm/tm.S
+++ b/arch/powerpc/kvm/tm.S@@ -164,15 +164,21 @@ _GLOBAL(_kvmppc_save_tm_pr) mfmsr r5 SAVE_GPR(5, r1) - /* also save DSCR/CR so that it can be recovered later */ + /* also save DSCR/CR/TAR so that it can be recovered later */ mfspr r6, SPRN_DSCR SAVE_GPR(6, r1) mfcr r7 stw r7, _CCR(r1) + mfspr r8, SPRN_TAR + SAVE_GPR(8, r1) + bl __kvmppc_save_tm + REST_GPR(8, r1) + mtspr SPRN_TAR, r8 + ld r7, _CCR(r1) mtcr r7
@@ -335,15 +341,21 @@ _GLOBAL(_kvmppc_restore_tm_pr) mfmsr r5 SAVE_GPR(5, r1) - /* also save DSCR/CR so that it can be recovered later */ + /* also save DSCR/CR/TAR so that it can be recovered later */ mfspr r6, SPRN_DSCR SAVE_GPR(6, r1) mfcr r7 stw r7, _CCR(r1) + mfspr r8, SPRN_TAR + SAVE_GPR(8, r1) + bl __kvmppc_restore_tm + REST_GPR(8, r1) + mtspr SPRN_TAR, r8 + ld r7, _CCR(r1) mtcr r7
--
1.8.3.1