Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+14 -4
+1
arch/powerpc/include/asm/kvm_book3s.h
··· 182 182 struct kvm_memory_slot *memslot, unsigned long *map); 183 183 extern void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr, 184 184 unsigned long mask); 185 + extern void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr); 185 186 186 187 extern void kvmppc_entry_trampoline(void); 187 188 extern void kvmppc_hv_entry_trampoline(void);
+4 -4
arch/powerpc/kvm/book3s_emulate.c
··· 449 449 case SPRN_GQR7: 450 450 to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; 451 451 break; 452 - case SPRN_FSCR: 453 - vcpu->arch.fscr = spr_val; 454 - break; 455 452 #ifdef CONFIG_PPC_BOOK3S_64 453 + case SPRN_FSCR: 454 + kvmppc_set_fscr(vcpu, spr_val); 455 + break; 456 456 case SPRN_BESCR: 457 457 vcpu->arch.bescr = spr_val; 458 458 break; ··· 593 593 case SPRN_GQR7: 594 594 *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]; 595 595 break; 596 + #ifdef CONFIG_PPC_BOOK3S_64 596 597 case SPRN_FSCR: 597 598 *spr_val = vcpu->arch.fscr; 598 599 break; 599 - #ifdef CONFIG_PPC_BOOK3S_64 600 600 case SPRN_BESCR: 601 601 *spr_val = vcpu->arch.bescr; 602 602 break;
+9
arch/powerpc/kvm/book3s_pr.c
··· 871 871 872 872 return RESUME_GUEST; 873 873 } 874 + 875 + void 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 883 #endif 875 884 876 885 int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,