summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSimon Guo <wei.guo.simon@gmail.com>2018-05-23 09:01:54 +0200
committerPaul Mackerras <paulus@ozlabs.org>2018-06-01 02:29:38 +0200
commit401a89e9375c011de4e3271d50f27648b734a7cb (patch)
tree53c0d063a9321787bbe75445ae617077254197cc /arch
parentKVM: PPC: Book3S PR: Sync TM bits to shadow msr for problem state guest (diff)
downloadlinux-401a89e9375c011de4e3271d50f27648b734a7cb.tar.xz
linux-401a89e9375c011de4e3271d50f27648b734a7cb.zip
KVM: PPC: Book3S PR: Implement RFID TM behavior to suppress change from S0 to N0
According 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 makes the RFID emulation of PR KVM consistent with this. Signed-off-by: Simon Guo <wei.guo.simon@gmail.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 68d68983948e..2eb457bc7b6e 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c
@@ -117,11 +117,28 @@ int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,
case 19:
switch (get_xop(inst)) {
case OP_19_XOP_RFID:
- case OP_19_XOP_RFI:
+ case OP_19_XOP_RFI: {
+ unsigned long srr1 = kvmppc_get_srr1(vcpu);
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ unsigned long cur_msr = kvmppc_get_msr(vcpu);
+
+ /*
+ * add rules to fit in ISA specification regarding TM
+ * state transistion in TM disable/Suspended state,
+ * and target TM state is TM inactive(00) state. (the
+ * change should be suppressed).
+ */
+ if (((cur_msr & MSR_TM) == 0) &&
+ ((srr1 & MSR_TM) == 0) &&
+ MSR_TM_SUSPENDED(cur_msr) &&
+ !MSR_TM_ACTIVE(srr1))
+ srr1 |= MSR_TS_S;
+#endif
kvmppc_set_pc(vcpu, kvmppc_get_srr0(vcpu));
- kvmppc_set_msr(vcpu, kvmppc_get_srr1(vcpu));
+ kvmppc_set_msr(vcpu, srr1);
*advance = 0;
break;
+ }
default:
emulated = EMULATE_FAIL;