From: Simon Guo <redacted>
Accordingly to ISA specification for RFID, in MSR TM disabled and TS
suspended state(S0), if the target MSR is TM disabled and TS state is
inactive(N0), rfid should suppress this update.
This patch make RFID emulation of PR KVM to be consistent with this.
Signed-off-by: Simon Guo <redacted>
Reviewed-by: Paul Mackerras <redacted>
---
arch/powerpc/kvm/book3s_emulate.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
From: Simon Guo <redacted>
PR KVM host usually equipped with enabled TM in its host MSR value, and
with non-transactional TS value.
When a guest with TM active traps into PR KVM host, the rfid at the
tail of kvmppc_interrupt_pr() will try to switch TS bits from
S0 (Suspended & TM disabled) to N1 (Non-transactional & TM enabled).
That will leads to TM Bad Thing interrupt.
This patch manually sets target TS bits unchanged to avoid this
exception.
Signed-off-by: Simon Guo <redacted>
Reviewed-by: Paul Mackerras <redacted>
---
arch/powerpc/kvm/book3s_segment.S | 13 +++++++++++++
1 file changed, 13 insertions(+)
From: Simon Guo <redacted>
This patch adds 2 new APIs: kvmppc_copyto_vcpu_tm() and
kvmppc_copyfrom_vcpu_tm(). These 2 APIs will be used to copy from/to TM
data between VCPU_TM/VCPU area.
PR KVM will use these APIs for treclaim. or trchkpt. emulation.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/book3s_emulate.c | 41 +++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
From: Simon Guo <redacted>
This patch adds 2 new APIs kvmppc_save_tm_sprs()/kvmppc_restore_tm_sprs()
for the purpose of TEXASR/TFIAR/TFHAR save/restore.
Signed-off-by: Simon Guo <redacted>
Reviewed-by: Paul Mackerras <redacted>
---
arch/powerpc/kvm/book3s_pr.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
@@ -286,6 +287,27 @@ void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu,preempt_enable();}+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM+staticinlinevoidkvmppc_save_tm_sprs(structkvm_vcpu*vcpu)+{+tm_enable();+vcpu->arch.tfhar=mfspr(SPRN_TFHAR);+vcpu->arch.texasr=mfspr(SPRN_TEXASR);+vcpu->arch.tfiar=mfspr(SPRN_TFIAR);+tm_disable();+}++staticinlinevoidkvmppc_restore_tm_sprs(structkvm_vcpu*vcpu)+{+tm_enable();+mtspr(SPRN_TFHAR,vcpu->arch.tfhar);+mtspr(SPRN_TEXASR,vcpu->arch.texasr);+mtspr(SPRN_TFIAR,vcpu->arch.tfiar);+tm_disable();+}++#endif+staticintkvmppc_core_check_requests_pr(structkvm_vcpu*vcpu){intr=1;/* Indicate we want to get back into the guest */
From: Simon Guo <redacted>
The transaction memory checkpoint area save/restore behavior is
triggered when VCPU qemu process is switching out/into CPU. ie.
at kvmppc_core_vcpu_put_pr() and kvmppc_core_vcpu_load_pr().
MSR TM active state is determined by TS bits:
active: 10(transactional) or 01 (suspended)
inactive: 00 (non-transactional)
We don't "fake" TM functionality for guest. We "sync" guest virtual
MSR TM active state(10 or 01) with shadow MSR. That is to say,
we don't emulate a transactional guest with a TM inactive MSR.
TM SPR support(TFIAR/TFAR/TEXASR) has already been supported by
commit 9916d57e64a4 ("KVM: PPC: Book3S PR: Expose TM registers").
Math register support (FPR/VMX/VSX) will be done at subsequent
patch.
Whether TM context need to be saved/restored can be determined
by kvmppc_get_msr() TM active state:
* TM active - save/restore TM context
* TM inactive - no need to do so and only save/restore
TM SPRs.
Signed-off-by: Simon Guo <redacted>
Suggested-by: Paul Mackerras <redacted>
---
arch/powerpc/include/asm/kvm_book3s.h | 9 +++++++++
arch/powerpc/include/asm/kvm_host.h | 1 -
arch/powerpc/kvm/book3s_pr.c | 27 +++++++++++++++++++++++++++
3 files changed, 36 insertions(+), 1 deletion(-)
From: Simon Guo <redacted>
The math registers will be saved into vcpu->arch.fp/vr and corresponding
vcpu->arch.fp_tm/vr_tm area.
We flush or giveup the math regs into vcpu->arch.fp/vr before saving
transaction. After transaction is restored, the math regs will be loaded
back into regs.
If there is a FP/VEC/VSX unavailable exception during transaction active
state, the math checkpoint content might be incorrect and we need to do
treclaim./load the correct checkpoint val/trechkpt. sequence to retry the
transaction. That will make our solution complicated. To solve this issue,
we always make the hardware guest MSR math bits (shadow_msr) consistent
with the MSR val which guest sees (kvmppc_get_msr()) when guest msr is
with tm enabled. Then all FP/VEC/VSX unavailable exception can be delivered
to guest and guest handles the exception by itself.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/book3s_pr.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
@@ -310,6 +310,28 @@ static inline void kvmppc_restore_tm_sprs(struct kvm_vcpu *vcpu)tm_disable();}+/* loadup math bits which is enabled at kvmppc_get_msr() but not enabled at+*hardware.+*/+staticvoidkvmppc_handle_lost_math_exts(structkvm_vcpu*vcpu)+{+ulongexit_nr;+ulongext_diff=(kvmppc_get_msr(vcpu)&~vcpu->arch.guest_owned_ext)&+(MSR_FP|MSR_VEC|MSR_VSX);++if(!ext_diff)+return;++if(ext_diff==MSR_FP)+exit_nr=BOOK3S_INTERRUPT_FP_UNAVAIL;+elseif(ext_diff==MSR_VEC)+exit_nr=BOOK3S_INTERRUPT_ALTIVEC;+else+exit_nr=BOOK3S_INTERRUPT_VSX;++kvmppc_handle_ext(vcpu,exit_nr,ext_diff);+}+voidkvmppc_save_tm_pr(structkvm_vcpu*vcpu){if(!(MSR_TM_ACTIVE(kvmppc_get_msr(vcpu)))){
From: Simon Guo <redacted>
The mfspr/mtspr on TM SPRs(TEXASR/TFIAR/TFHAR) are non-privileged
instructions and can be executed at PR KVM guest without trapping
into host in problem state. We only emulate mtspr/mfspr
texasr/tfiar/tfhar at guest PR=0 state.
When we are emulating mtspr tm sprs at guest PR=0 state, the emulation
result need to be visible to guest PR=1 state. That is, the actual TM
SPR val should be loaded into actual registers.
We already flush TM SPRs into vcpu when switching out of CPU, and load
TM SPRs when switching back.
This patch corrects mfspr()/mtspr() emulation for TM SPRs to make the
actual source/dest based on actual TM SPRs.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/include/asm/kvm_book3s.h | 1 +
arch/powerpc/kvm/book3s_emulate.c | 54 ++++++++++++++++++++++++++++-------
arch/powerpc/kvm/book3s_pr.c | 2 +-
3 files changed, 46 insertions(+), 11 deletions(-)
@@ -523,13 +523,35 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)break;#ifdef CONFIG_PPC_TRANSACTIONAL_MEMcaseSPRN_TFHAR:-vcpu->arch.tfhar=spr_val;-break;caseSPRN_TEXASR:-vcpu->arch.texasr=spr_val;-break;caseSPRN_TFIAR:-vcpu->arch.tfiar=spr_val;+if(!cpu_has_feature(CPU_FTR_TM))+break;++if(!(kvmppc_get_msr(vcpu)&MSR_TM)){+kvmppc_trigger_fac_interrupt(vcpu,FSCR_TM_LG);+emulated=EMULATE_AGAIN;+break;+}++if(MSR_TM_ACTIVE(kvmppc_get_msr(vcpu))){+/* it is illegal to mtspr() TM regs in+*otherthannon-transactionalstate.+*/+kvmppc_core_queue_program(vcpu,SRR1_PROGTM);+emulated=EMULATE_AGAIN;+break;+}++tm_enable();+if(sprn==SPRN_TFHAR)+mtspr(SPRN_TFHAR,spr_val);+elseif(sprn==SPRN_TEXASR)+mtspr(SPRN_TEXASR,spr_val);+else+mtspr(SPRN_TFIAR,spr_val);+tm_disable();+break;#endif#endif
@@ -676,13 +698,25 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_valbreak;#ifdef CONFIG_PPC_TRANSACTIONAL_MEMcaseSPRN_TFHAR:-*spr_val=vcpu->arch.tfhar;-break;caseSPRN_TEXASR:-*spr_val=vcpu->arch.texasr;-break;caseSPRN_TFIAR:-*spr_val=vcpu->arch.tfiar;+if(!cpu_has_feature(CPU_FTR_TM))+break;++if(!(kvmppc_get_msr(vcpu)&MSR_TM)){+kvmppc_trigger_fac_interrupt(vcpu,FSCR_TM_LG);+emulated=EMULATE_AGAIN;+break;+}++tm_enable();+if(sprn==SPRN_TFHAR)+*spr_val=mfspr(SPRN_TFHAR);+elseif(sprn==SPRN_TEXASR)+*spr_val=mfspr(SPRN_TEXASR);+elseif(sprn==SPRN_TFIAR)+*spr_val=mfspr(SPRN_TFIAR);+tm_disable();break;#endif#endif
@@ -927,7 +927,7 @@ static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu)#ifdef CONFIG_PPC_BOOK3S_64-staticvoidkvmppc_trigger_fac_interrupt(structkvm_vcpu*vcpu,ulongfac)+voidkvmppc_trigger_fac_interrupt(structkvm_vcpu*vcpu,ulongfac){/* Inject the Interrupt Cause field and trigger a guest interrupt */vcpu->arch.fscr&=~(0xffULL<<56);
From: Simon Guo <redacted>
Currently kvmppc_handle_fac() will not update NV GPRs and thus it can
return with GUEST_RESUME.
However PR KVM guest always disables MSR_TM bit at privilege state. If PR
privilege guest are trying to read TM SPRs, it will trigger TM facility
unavailable exception and fall into kvmppc_handle_fac(). Then the emulation
will be done by kvmppc_core_emulate_mfspr_pr(). The mfspr instruction can
include a RT with NV reg. So it is necessary to restore NV GPRs at this
case, to reflect the update to NV RT.
This patch make kvmppc_handle_fac() return GUEST_RESUME_NV at TM fac
exception and with guest privilege state.
Signed-off-by: Simon Guo <redacted>
Reviewed-by: Paul Mackerras <redacted>
---
arch/powerpc/kvm/book3s_pr.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
@@ -998,6 +998,18 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac)break;}+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM+/* Since we disabled MSR_TM at privilege state, the mfspr instruction+*forTMsprcantriggerTMfacunavailable.Inthiscase,the+*emulationishandledbykvmppc_emulate_fac(),whichinvokes+*kvmppc_emulate_mfspr()finally.Butnotethemfsprcaninclude+*RTforNVregisters.SoitneedtorestorethoseNVregtoreflect+*theupdate.+*/+if((fac==FSCR_TM_LG)&&!(kvmppc_get_msr(vcpu)&MSR_PR))+returnRESUME_GUEST_NV;+#endif+returnRESUME_GUEST;}
From: Simon Guo <redacted>
Currently kernel doesn't use transaction memory.
And there is an issue for privilege guest that:
tbegin/tsuspend/tresume/tabort TM instructions can impact MSR TM bits
without trap into PR host. So following code will lead to a false mfmsr
result:
tbegin <- MSR bits update to Transaction active.
beq <- failover handler branch
mfmsr <- still read MSR bits from magic page with
transaction inactive.
It is not an issue for non-privilege guest since its mfmsr is not patched
with magic page and will always trap into PR host.
This patch will always fail tbegin attempt for privilege guest, so that
the above issue is prevented. It is benign since currently (guest) kernel
doesn't initiate a transaction.
Test case:
https://github.com/justdoitqd/publicFiles/blob/master/test_tbegin_pr.c
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/include/asm/kvm_book3s.h | 2 ++
arch/powerpc/kvm/book3s_emulate.c | 43 +++++++++++++++++++++++++++++++++++
arch/powerpc/kvm/book3s_pr.c | 11 ++++++++-
3 files changed, 55 insertions(+), 1 deletion(-)
@@ -47,6 +48,8 @@#define OP_31_XOP_EIOIO 854#define OP_31_XOP_SLBMFEE 915+#define OP_31_XOP_TBEGIN 654+/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */#define OP_31_XOP_DCBZ 1010
From: Simon Guo <redacted>
This patch adds support for "treclaim." emulation when PR KVM guest
executes treclaim. and traps to host.
We will firstly doing treclaim. and save TM checkpoint. Then it is
necessary to update vcpu current reg content with checkpointed vals.
When rfid into guest again, those vcpu current reg content(now the
checkpoint vals) will be loaded into regs.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/book3s_emulate.c | 77 +++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
@@ -50,6 +51,8 @@#define OP_31_XOP_TBEGIN 654+#define OP_31_XOP_TRECLAIM 942+/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */#define OP_31_XOP_DCBZ 1010
@@ -404,6 +447,40 @@ int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,emulated=EMULATE_FAIL;break;}+caseOP_31_XOP_TRECLAIM:+{+ulongguest_msr=kvmppc_get_msr(vcpu);+unsignedlongra_val=0;++if(!cpu_has_feature(CPU_FTR_TM))+break;++if(!(kvmppc_get_msr(vcpu)&MSR_TM)){+kvmppc_trigger_fac_interrupt(vcpu,FSCR_TM_LG);+emulated=EMULATE_AGAIN;+break;+}++/* generate interrupts based on priorities */+if(guest_msr&MSR_PR){+/* Privileged Instruction type Program Interrupt */+kvmppc_core_queue_program(vcpu,SRR1_PROGPRIV);+emulated=EMULATE_AGAIN;+break;+}++if(!MSR_TM_ACTIVE(guest_msr)){+/* TM bad thing interrupt */+kvmppc_core_queue_program(vcpu,SRR1_PROGTM);+emulated=EMULATE_AGAIN;+break;+}++if(ra)+ra_val=kvmppc_get_gpr(vcpu,ra);+kvmppc_emulate_treclaim(vcpu,ra_val);+break;+}#endifdefault:emulated=EMULATE_FAIL;
From: Simon Guo <redacted>
This patch adds host emulation when guest PR KVM executes "trechkpt.",
which is a privileged instruction and will trap into host.
We firstly copy vcpu ongoing content into vcpu tm checkpoint
content, then perform kvmppc_restore_tm_pr() to do trechkpt.
with updated vcpu tm checkpoint vals.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/include/asm/kvm_book3s.h | 2 ++
arch/powerpc/kvm/book3s_emulate.c | 61 +++++++++++++++++++++++++++++++++++
arch/powerpc/kvm/book3s_pr.c | 2 +-
3 files changed, 64 insertions(+), 1 deletion(-)
@@ -52,6 +52,7 @@#define OP_31_XOP_TBEGIN 654#define OP_31_XOP_TRECLAIM 942+#define OP_31_XOP_TRCHKPT 1006/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */#define OP_31_XOP_DCBZ 1010
@@ -481,6 +505,43 @@ int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,kvmppc_emulate_treclaim(vcpu,ra_val);break;}+caseOP_31_XOP_TRCHKPT:+{+ulongguest_msr=kvmppc_get_msr(vcpu);+unsignedlongtexasr;++if(!cpu_has_feature(CPU_FTR_TM))+break;++if(!(kvmppc_get_msr(vcpu)&MSR_TM)){+kvmppc_trigger_fac_interrupt(vcpu,FSCR_TM_LG);+emulated=EMULATE_AGAIN;+break;+}++/* generate interrupt based on priorities */+if(guest_msr&MSR_PR){+/* Privileged Instruction type Program Intr */+kvmppc_core_queue_program(vcpu,SRR1_PROGPRIV);+emulated=EMULATE_AGAIN;+break;+}++tm_enable();+texasr=mfspr(SPRN_TEXASR);+tm_disable();++if(MSR_TM_ACTIVE(guest_msr)||+!(texasr&(TEXASR_FS))){+/* TM bad thing interrupt */+kvmppc_core_queue_program(vcpu,SRR1_PROGTM);+emulated=EMULATE_AGAIN;+break;+}++kvmppc_emulate_trchkpt(vcpu);+break;+}#endifdefault:emulated=EMULATE_FAIL;
From: Simon Guo <redacted>
Currently privilege guest will be run with TM disabled.
Although the privilege guest cannot initiate a new transaction,
it can use tabort to terminate its problem state's transaction.
So it is still necessary to emulate tabort. for privilege guest.
This patch adds emulation for tabort. of privilege guest.
Tested with:
https://github.com/justdoitqd/publicFiles/blob/master/test_tabort.c
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/book3s_emulate.c | 68 +++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
@@ -196,6 +197,47 @@ static void kvmppc_emulate_trchkpt(struct kvm_vcpu *vcpu)kvmppc_restore_tm_pr(vcpu);preempt_enable();}++/* emulate tabort. at guest privilege state */+staticvoidkvmppc_emulate_tabort(structkvm_vcpu*vcpu,intra_val)+{+/* currently we only emulate tabort. but no emulation of other+*tabortvariantssincethereisnokernelusageofthemat+*present.+*/+unsignedlongguest_msr=kvmppc_get_msr(vcpu);++preempt_disable();+tm_enable();+tm_abort(ra_val);++/* CR0 = 0 | MSR[TS] | 0 */+vcpu->arch.cr=(vcpu->arch.cr&~(CR0_MASK<<CR0_SHIFT))|+(((guest_msr&MSR_TS_MASK)>>(MSR_TS_S_LG-1))+<<CR0_SHIFT);++vcpu->arch.texasr=mfspr(SPRN_TEXASR);+/* failure recording depends on Failure Summary bit,+*andtabortwillbetreatedasnopsinnon-transactional+*state.+*/+if(!(vcpu->arch.texasr&TEXASR_FS)&&+MSR_TM_ACTIVE(guest_msr)){+vcpu->arch.texasr&=~(TEXASR_PR|TEXASR_HV);+if(guest_msr&MSR_PR)+vcpu->arch.texasr|=TEXASR_PR;++if(guest_msr&MSR_HV)+vcpu->arch.texasr|=TEXASR_HV;++vcpu->arch.tfiar=kvmppc_get_pc(vcpu);+mtspr(SPRN_TEXASR,vcpu->arch.texasr);+mtspr(SPRN_TFIAR,vcpu->arch.tfiar);+}+tm_disable();+preempt_enable();+}+#endifintkvmppc_core_emulate_op_pr(structkvm_run*run,structkvm_vcpu*vcpu,
@@ -471,6 +513,32 @@ int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,emulated=EMULATE_FAIL;break;}+caseOP_31_XOP_TABORT:+{+ulongguest_msr=kvmppc_get_msr(vcpu);+unsignedlongra_val=0;++if(!cpu_has_feature(CPU_FTR_TM))+break;++if(!(kvmppc_get_msr(vcpu)&MSR_TM)){+kvmppc_trigger_fac_interrupt(vcpu,FSCR_TM_LG);+emulated=EMULATE_AGAIN;+break;+}++/* only emulate for privilege guest, since problem state+*guestcanrunwithTMenabledandwedon'texpectto+*trapathereforthatcase.+*/+WARN_ON(guest_msr&MSR_PR);++if(ra)+ra_val=kvmppc_get_gpr(vcpu,ra);++kvmppc_emulate_tabort(vcpu,ra_val);+break;+}caseOP_31_XOP_TRECLAIM:{ulongguest_msr=kvmppc_get_msr(vcpu);
From: Simon Guo <redacted>
Currently PR KVM doesn't support transaction memory at guest privilege
state.
This patch adds a check at setting guest msr, so that we can never return
to guest with PR=0 and TS=0b10. A tabort will be emulated to indicate
this and fail transaction immediately.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/include/uapi/asm/tm.h | 2 +-
arch/powerpc/kvm/book3s.h | 6 ++++++
arch/powerpc/kvm/book3s_emulate.c | 2 +-
arch/powerpc/kvm/book3s_pr.c | 13 ++++++++++++-
4 files changed, 20 insertions(+), 3 deletions(-)
@@ -199,7 +199,7 @@ static void kvmppc_emulate_trchkpt(struct kvm_vcpu *vcpu)}/* emulate tabort. at guest privilege state */-staticvoidkvmppc_emulate_tabort(structkvm_vcpu*vcpu,intra_val)+voidkvmppc_emulate_tabort(structkvm_vcpu*vcpu,intra_val){/* currently we only emulate tabort. but no emulation of other*tabortvariantssincethereisnokernelusageofthemat
@@ -457,12 +457,23 @@ static void kvm_set_spte_hva_pr(struct kvm *kvm, unsigned long hva, pte_t pte)staticvoidkvmppc_set_msr_pr(structkvm_vcpu*vcpu,u64msr){-ulongold_msr=kvmppc_get_msr(vcpu);+ulongold_msr;#ifdef EXIT_DEBUGprintk(KERN_INFO"KVM: Set MSR to 0x%llx\n",msr);#endif+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM+/* We should never target guest MSR to TS=10 && PR=0,+*sincewealwaysfailtransactionforguestprivilege+*state.+*/+if(!(msr&MSR_PR)&&MSR_TM_TRANSACTIONAL(msr))+kvmppc_emulate_tabort(vcpu,+TM_CAUSE_PRIV_T|TM_CAUSE_PERSISTENT);+#endif++old_msr=kvmppc_get_msr(vcpu);msr&=to_book3s(vcpu)->msr_mask;kvmppc_set_msr_fast(vcpu,msr);kvmppc_recalc_shadow_msr(vcpu);
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(-)
@@ -828,7 +834,7 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)}/* Give up facility (TAR / EBB / DSCR) */-staticvoidkvmppc_giveup_fac(structkvm_vcpu*vcpu,ulongfac)+voidkvmppc_giveup_fac(structkvm_vcpu*vcpu,ulongfac){#ifdef CONFIG_PPC_BOOK3S_64if(!(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);+}elseif(!(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
From: Simon Guo <redacted>
With current patch set, PR KVM now supports HTM. So this patch turns it
on for PR KVM.
Tested with:
https://github.com/justdoitqd/publicFiles/blob/master/test_kvm_htm_cap.c
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/powerpc.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
@@ -648,8 +648,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)break;#endifcaseKVM_CAP_PPC_HTM:-r=hv_enabled&&-(cur_cpu_spec->cpu_user_features2&PPC_FEATURE2_HTM_COMP);+r=(cur_cpu_spec->cpu_user_features2&PPC_FEATURE2_HTM_COMP);break;default:r=0;
From: Simon Guo <redacted>
Although we already have kvm_arch_vcpu_async_ioctl() which doesn't require
ioctl to load vcpu, the sync ioctl code need to be cleaned up when
CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL is not configured.
This patch moves vcpu_load/vcpu_put down to each ioctl switch case so that
each ioctl can decide to do vcpu_load/vcpu_put or not independently.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/powerpc.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
From: Simon Guo <redacted>
Due to the vcpu mutex locking/unlock has been moved out of vcpu_load()
/vcpu_put(), KVM_GET_ONE_REG and KVM_SET_ONE_REG doesn't need to do
ioctl with loading vcpu anymore. This patch removes vcpu_load()/vcpu_put()
from KVM_GET_ONE_REG and KVM_SET_ONE_REG ioctl.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/powerpc.c | 2 --
1 file changed, 2 deletions(-)
From: Simon Guo <redacted>
In both HV/PR KVM, the KVM_SET_REGS/KVM_GET_REGS ioctl should
be able to perform without load vcpu. This patch adds
KVM_SET_ONE_REG/KVM_GET_ONE_REG implementation to async ioctl
function.
Due to the vcpu mutex locking/unlock has been moved out of vcpu_load()
/vcpu_put(), KVM_SET_REGS/KVM_GET_REGS don't need to do
ioctl with loading vcpu anymore. This patch removes vcpu_load()/vcpu_put()
from KVM_SET_REGS/KVM_GET_REGS ioctl.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/book3s.c | 6 ------
1 file changed, 6 deletions(-)
From: Simon Guo <redacted>
In both HV/PR KVM, the KVM_SET_ONE_REG/KVM_GET_ONE_REG ioctl should
be able to perform without load vcpu. This patch adds
KVM_SET_ONE_REG/KVM_GET_ONE_REG implementation to async ioctl
function.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/powerpc.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
From: Simon Guo <redacted>
We need to migrate PR KVM during transaction and qemu will use
kvmppc_get_one_reg_pr()/kvmppc_set_one_reg_pr() APIs to get/set
transaction checkpoint state. This patch adds support for that.
So far PPC PR qemu doesn't fully function for migration but the
savevm/loadvm can be done against a RHEL72 guest. During savevm/
loadvm procedure, the kvm ioctls will be invoked as well.
Test has been performed to savevm/loadvm for a guest running
a HTM test program:
https://github.com/justdoitqd/publicFiles/blob/master/test-tm-mig.c
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/book3s_pr.c | 133 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 133 insertions(+)
From: Paul Mackerras <hidden> Date: 2018-05-15 06:15:33
On Wed, Feb 28, 2018 at 01:52:25AM +0800, wei.guo.simon@gmail.com wrote:
quoted hunk
From: Simon Guo <redacted>
The mfspr/mtspr on TM SPRs(TEXASR/TFIAR/TFHAR) are non-privileged
instructions and can be executed at PR KVM guest without trapping
into host in problem state. We only emulate mtspr/mfspr
texasr/tfiar/tfhar at guest PR=0 state.
When we are emulating mtspr tm sprs at guest PR=0 state, the emulation
result need to be visible to guest PR=1 state. That is, the actual TM
SPR val should be loaded into actual registers.
We already flush TM SPRs into vcpu when switching out of CPU, and load
TM SPRs when switching back.
This patch corrects mfspr()/mtspr() emulation for TM SPRs to make the
actual source/dest based on actual TM SPRs.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/include/asm/kvm_book3s.h | 1 +
arch/powerpc/kvm/book3s_emulate.c | 54 ++++++++++++++++++++++++++++-------
arch/powerpc/kvm/book3s_pr.c | 2 +-
3 files changed, 46 insertions(+), 11 deletions(-)
@@ -523,13 +523,35 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)break;#ifdef CONFIG_PPC_TRANSACTIONAL_MEMcaseSPRN_TFHAR:-vcpu->arch.tfhar=spr_val;-break;caseSPRN_TEXASR:-vcpu->arch.texasr=spr_val;-break;caseSPRN_TFIAR:-vcpu->arch.tfiar=spr_val;+if(!cpu_has_feature(CPU_FTR_TM))+break;++if(!(kvmppc_get_msr(vcpu)&MSR_TM)){+kvmppc_trigger_fac_interrupt(vcpu,FSCR_TM_LG);+emulated=EMULATE_AGAIN;+break;+}++if(MSR_TM_ACTIVE(kvmppc_get_msr(vcpu))){+/* it is illegal to mtspr() TM regs in+*otherthannon-transactionalstate.+*/+kvmppc_core_queue_program(vcpu,SRR1_PROGTM);+emulated=EMULATE_AGAIN;
According to the architecture, mtspr to TFHAR is permitted in
suspended state.
Paul.
From: Paul Mackerras <hidden> Date: 2018-05-15 06:15:33
On Wed, Feb 28, 2018 at 01:52:26AM +0800, wei.guo.simon@gmail.com wrote:
quoted hunk
From: Simon Guo <redacted>
Currently kernel doesn't use transaction memory.
And there is an issue for privilege guest that:
tbegin/tsuspend/tresume/tabort TM instructions can impact MSR TM bits
without trap into PR host. So following code will lead to a false mfmsr
result:
tbegin <- MSR bits update to Transaction active.
beq <- failover handler branch
mfmsr <- still read MSR bits from magic page with
transaction inactive.
It is not an issue for non-privilege guest since its mfmsr is not patched
with magic page and will always trap into PR host.
This patch will always fail tbegin attempt for privilege guest, so that
the above issue is prevented. It is benign since currently (guest) kernel
doesn't initiate a transaction.
Test case:
https://github.com/justdoitqd/publicFiles/blob/master/test_tbegin_pr.c
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/include/asm/kvm_book3s.h | 2 ++
arch/powerpc/kvm/book3s_emulate.c | 43 +++++++++++++++++++++++++++++++++++
arch/powerpc/kvm/book3s_pr.c | 11 ++++++++-
3 files changed, 55 insertions(+), 1 deletion(-)
@@ -47,6 +48,8 @@#define OP_31_XOP_EIOIO 854#define OP_31_XOP_SLBMFEE 915+#define OP_31_XOP_TBEGIN 654+/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */#define OP_31_XOP_DCBZ 1010
From: Paul Mackerras <hidden> Date: 2018-05-15 06:15:33
On Wed, Feb 28, 2018 at 01:52:37AM +0800, wei.guo.simon@gmail.com wrote:
quoted hunk
From: Simon Guo <redacted>
In both HV/PR KVM, the KVM_SET_ONE_REG/KVM_GET_ONE_REG ioctl should
be able to perform without load vcpu. This patch adds
KVM_SET_ONE_REG/KVM_GET_ONE_REG implementation to async ioctl
function.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/powerpc.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
@@ -1619,6 +1619,19 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp,return-EFAULT;returnkvm_vcpu_ioctl_interrupt(vcpu,&irq);}++if((ioctl==KVM_SET_ONE_REG)||(ioctl==KVM_GET_ONE_REG)){+structkvm_one_regreg;++if(copy_from_user(®,argp,sizeof(reg)))+return-EFAULT;++if(ioctl==KVM_SET_ONE_REG)+returnkvm_vcpu_ioctl_set_one_reg(vcpu,®);+else+returnkvm_vcpu_ioctl_get_one_reg(vcpu,®);+}+return-ENOIOCTLCMD;}
This seems dangerous to me, since now we can have set/get one_reg
running in parallel with vcpu execution. Is there a really compelling
reason to do this? If not I'd rather not make this change.
Paul.
From: Simon Guo <hidden> Date: 2018-05-15 12:58:28
On Tue, May 15, 2018 at 04:07:03PM +1000, Paul Mackerras wrote:
On Wed, Feb 28, 2018 at 01:52:25AM +0800, wei.guo.simon@gmail.com wrote:
quoted
From: Simon Guo <redacted>
The mfspr/mtspr on TM SPRs(TEXASR/TFIAR/TFHAR) are non-privileged
instructions and can be executed at PR KVM guest without trapping
into host in problem state. We only emulate mtspr/mfspr
texasr/tfiar/tfhar at guest PR=0 state.
When we are emulating mtspr tm sprs at guest PR=0 state, the emulation
result need to be visible to guest PR=1 state. That is, the actual TM
SPR val should be loaded into actual registers.
We already flush TM SPRs into vcpu when switching out of CPU, and load
TM SPRs when switching back.
This patch corrects mfspr()/mtspr() emulation for TM SPRs to make the
actual source/dest based on actual TM SPRs.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/include/asm/kvm_book3s.h | 1 +
arch/powerpc/kvm/book3s_emulate.c | 54 ++++++++++++++++++++++++++++-------
arch/powerpc/kvm/book3s_pr.c | 2 +-
3 files changed, 46 insertions(+), 11 deletions(-)
@@ -523,13 +523,35 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)break;#ifdef CONFIG_PPC_TRANSACTIONAL_MEMcaseSPRN_TFHAR:-vcpu->arch.tfhar=spr_val;-break;caseSPRN_TEXASR:-vcpu->arch.texasr=spr_val;-break;caseSPRN_TFIAR:-vcpu->arch.tfiar=spr_val;+if(!cpu_has_feature(CPU_FTR_TM))+break;++if(!(kvmppc_get_msr(vcpu)&MSR_TM)){+kvmppc_trigger_fac_interrupt(vcpu,FSCR_TM_LG);+emulated=EMULATE_AGAIN;+break;+}++if(MSR_TM_ACTIVE(kvmppc_get_msr(vcpu))){+/* it is illegal to mtspr() TM regs in+*otherthannon-transactionalstate.+*/+kvmppc_core_queue_program(vcpu,SRR1_PROGTM);+emulated=EMULATE_AGAIN;
According to the architecture, mtspr to TFHAR is permitted in
suspended state.
oh.. I rescan the ISA and find the corresponding statement:
"If an attempt is made to execute mtspr specifying a TM
SPR in other than Non-transactional state, with the
exception of TFAR in suspended state, a TM Bad Thing
type Program interrupt is generated."
It mentiones "TFAR" instead of "TFHAR" -- So it looks a typo
in the ISA book. I will correct the code.
Thanks,
- Simon
From: Simon Guo <hidden> Date: 2018-05-16 01:35:14
Hi Paul,
On Tue, May 15, 2018 at 04:07:55PM +1000, Paul Mackerras wrote:
On Wed, Feb 28, 2018 at 01:52:26AM +0800, wei.guo.simon@gmail.com wrote:
quoted
From: Simon Guo <redacted>
Currently kernel doesn't use transaction memory.
And there is an issue for privilege guest that:
tbegin/tsuspend/tresume/tabort TM instructions can impact MSR TM bits
without trap into PR host. So following code will lead to a false mfmsr
result:
tbegin <- MSR bits update to Transaction active.
beq <- failover handler branch
mfmsr <- still read MSR bits from magic page with
transaction inactive.
It is not an issue for non-privilege guest since its mfmsr is not patched
with magic page and will always trap into PR host.
This patch will always fail tbegin attempt for privilege guest, so that
the above issue is prevented. It is benign since currently (guest) kernel
doesn't initiate a transaction.
Test case:
https://github.com/justdoitqd/publicFiles/blob/master/test_tbegin_pr.c
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/include/asm/kvm_book3s.h | 2 ++
arch/powerpc/kvm/book3s_emulate.c | 43 +++++++++++++++++++++++++++++++++++
arch/powerpc/kvm/book3s_pr.c | 11 ++++++++-
3 files changed, 55 insertions(+), 1 deletion(-)
@@ -47,6 +48,8 @@#define OP_31_XOP_EIOIO 854#define OP_31_XOP_SLBMFEE 915+#define OP_31_XOP_TBEGIN 654+/* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */#define OP_31_XOP_DCBZ 1010
From: Simon Guo <hidden> Date: 2018-05-16 02:13:36
Hi Paul,
On Tue, May 15, 2018 at 04:15:26PM +1000, Paul Mackerras wrote:
On Wed, Feb 28, 2018 at 01:52:37AM +0800, wei.guo.simon@gmail.com wrote:
quoted
From: Simon Guo <redacted>
In both HV/PR KVM, the KVM_SET_ONE_REG/KVM_GET_ONE_REG ioctl should
be able to perform without load vcpu. This patch adds
KVM_SET_ONE_REG/KVM_GET_ONE_REG implementation to async ioctl
function.
Signed-off-by: Simon Guo <redacted>
---
arch/powerpc/kvm/powerpc.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
@@ -1619,6 +1619,19 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp,return-EFAULT;returnkvm_vcpu_ioctl_interrupt(vcpu,&irq);}++if((ioctl==KVM_SET_ONE_REG)||(ioctl==KVM_GET_ONE_REG)){+structkvm_one_regreg;++if(copy_from_user(®,argp,sizeof(reg)))+return-EFAULT;++if(ioctl==KVM_SET_ONE_REG)+returnkvm_vcpu_ioctl_set_one_reg(vcpu,®);+else+returnkvm_vcpu_ioctl_get_one_reg(vcpu,®);+}+return-ENOIOCTLCMD;}
This seems dangerous to me, since now we can have set/get one_reg
running in parallel with vcpu execution. Is there a really compelling
reason to do this? If not I'd rather not make this change.