aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2014-07-31 04:21:59 -0400
committerAlexander Graf <agraf@suse.de>2014-07-31 04:23:46 -0400
commit8e6afa36e754be84b468d7df9e5aa71cf4003f3b (patch)
tree2f41e8d6c34ee35306c1f65bfd87e8960fe43a60 /arch/powerpc/kvm
parent29577fc00ba40a89fc824f030bcc80c583259346 (diff)
KVM: PPC: PR: Handle FSCR feature deselects
We handle FSCR feature bits (well, TAR only really today) lazily when the guest starts using them. So when a guest activates the bit and later uses that feature we enable it for real in hardware. However, when the guest stops using that bit we don't stop setting it in hardware. That means we can potentially lose a trap that the guest expects to happen because it thinks a feature is not active. This patch adds support to drop TAR when then guest turns it off in FSCR. While at it it also restricts FSCR access to 64bit systems - 32bit ones don't have it. Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c6
-rw-r--r--arch/powerpc/kvm/book3s_pr.c9
2 files changed, 12 insertions, 3 deletions
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 84fddcd6c1f8..5a2bc4b0dfe5 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c
@@ -449,10 +449,10 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
449 case SPRN_GQR7: 449 case SPRN_GQR7:
450 to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; 450 to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val;
451 break; 451 break;
452#ifdef CONFIG_PPC_BOOK3S_64
452 case SPRN_FSCR: 453 case SPRN_FSCR:
453 vcpu->arch.fscr = spr_val; 454 kvmppc_set_fscr(vcpu, spr_val);
454 break; 455 break;
455#ifdef CONFIG_PPC_BOOK3S_64
456 case SPRN_BESCR: 456 case SPRN_BESCR:
457 vcpu->arch.bescr = spr_val; 457 vcpu->arch.bescr = spr_val;
458 break; 458 break;
@@ -593,10 +593,10 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
593 case SPRN_GQR7: 593 case SPRN_GQR7:
594 *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]; 594 *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0];
595 break; 595 break;
596#ifdef CONFIG_PPC_BOOK3S_64
596 case SPRN_FSCR: 597 case SPRN_FSCR:
597 *spr_val = vcpu->arch.fscr; 598 *spr_val = vcpu->arch.fscr;
598 break; 599 break;
599#ifdef CONFIG_PPC_BOOK3S_64
600 case SPRN_BESCR: 600 case SPRN_BESCR:
601 *spr_val = vcpu->arch.bescr; 601 *spr_val = vcpu->arch.bescr;
602 break; 602 break;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index e7a1fa2517b1..faffb27badd9 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -871,6 +871,15 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac)
871 871
872 return RESUME_GUEST; 872 return RESUME_GUEST;
873} 873}
874
875void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr)
876{
877 if ((vcpu->arch.fscr & FSCR_TAR) && !(fscr & FSCR_TAR)) {
878 /* TAR got dropped, drop it in shadow too */
879 kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
880 }
881 vcpu->arch.fscr = fscr;
882}
874#endif 883#endif
875 884
876int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, 885int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,