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

KVM: PPC: e500: Add emulation helper for getting instruction ea

Add emulation helper for getting instruction ea and refactor tlb instruction
emulation to use it.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
[agraf: keep rt variable around]
Signed-off-by: Alexander Graf <agraf@suse.de>

authored by

Mihai Caraman and committed by
Alexander Graf
7cdd7a95 e51f8f32

+35 -29
+11
arch/powerpc/include/asm/kvm_ppc.h
··· 295 295 #endif 296 296 } 297 297 298 + static inline ulong kvmppc_get_ea_indexed(struct kvm_vcpu *vcpu, int ra, int rb) 299 + { 300 + ulong ea; 301 + 302 + ea = kvmppc_get_gpr(vcpu, rb); 303 + if (ra) 304 + ea += kvmppc_get_gpr(vcpu, ra); 305 + 306 + return ea; 307 + } 308 + 298 309 #endif /* __POWERPC_KVM_PPC_H__ */
+3 -3
arch/powerpc/kvm/e500.h
··· 129 129 ulong value); 130 130 int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu); 131 131 int kvmppc_e500_emul_tlbre(struct kvm_vcpu *vcpu); 132 - int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb); 133 - int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int rt, int ra, int rb); 134 - int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb); 132 + int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, gva_t ea); 133 + int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int type, gva_t ea); 134 + int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, gva_t ea); 135 135 int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500); 136 136 void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500); 137 137
+10 -4
arch/powerpc/kvm/e500_emulate.c
··· 89 89 int ra = get_ra(inst); 90 90 int rb = get_rb(inst); 91 91 int rt = get_rt(inst); 92 + gva_t ea; 92 93 93 94 switch (get_op(inst)) { 94 95 case 31: ··· 114 113 break; 115 114 116 115 case XOP_TLBSX: 117 - emulated = kvmppc_e500_emul_tlbsx(vcpu,rb); 116 + ea = kvmppc_get_ea_indexed(vcpu, ra, rb); 117 + emulated = kvmppc_e500_emul_tlbsx(vcpu, ea); 118 118 break; 119 119 120 - case XOP_TLBILX: 121 - emulated = kvmppc_e500_emul_tlbilx(vcpu, rt, ra, rb); 120 + case XOP_TLBILX: { 121 + int type = rt & 0x3; 122 + ea = kvmppc_get_ea_indexed(vcpu, ra, rb); 123 + emulated = kvmppc_e500_emul_tlbilx(vcpu, type, ea); 122 124 break; 125 + } 123 126 124 127 case XOP_TLBIVAX: 125 - emulated = kvmppc_e500_emul_tlbivax(vcpu, ra, rb); 128 + ea = kvmppc_get_ea_indexed(vcpu, ra, rb); 129 + emulated = kvmppc_e500_emul_tlbivax(vcpu, ea); 126 130 break; 127 131 128 132 default:
+11 -22
arch/powerpc/kvm/e500_tlb.c
··· 689 689 return EMULATE_DONE; 690 690 } 691 691 692 - int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb) 692 + int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, gva_t ea) 693 693 { 694 694 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 695 695 unsigned int ia; 696 696 int esel, tlbsel; 697 - gva_t ea; 698 - 699 - ea = ((ra) ? kvmppc_get_gpr(vcpu, ra) : 0) + kvmppc_get_gpr(vcpu, rb); 700 697 701 698 ia = (ea >> 2) & 0x1; 702 699 ··· 720 723 } 721 724 722 725 static void tlbilx_all(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, 723 - int pid, int rt) 726 + int pid, int type) 724 727 { 725 728 struct kvm_book3e_206_tlb_entry *tlbe; 726 729 int tid, esel; ··· 729 732 for (esel = 0; esel < vcpu_e500->gtlb_params[tlbsel].entries; esel++) { 730 733 tlbe = get_entry(vcpu_e500, tlbsel, esel); 731 734 tid = get_tlb_tid(tlbe); 732 - if (rt == 0 || tid == pid) { 735 + if (type == 0 || tid == pid) { 733 736 inval_gtlbe_on_host(vcpu_e500, tlbsel, esel); 734 737 kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel); 735 738 } ··· 737 740 } 738 741 739 742 static void tlbilx_one(struct kvmppc_vcpu_e500 *vcpu_e500, int pid, 740 - int ra, int rb) 743 + gva_t ea) 741 744 { 742 745 int tlbsel, esel; 743 - gva_t ea; 744 - 745 - ea = kvmppc_get_gpr(&vcpu_e500->vcpu, rb); 746 - if (ra) 747 - ea += kvmppc_get_gpr(&vcpu_e500->vcpu, ra); 748 746 749 747 for (tlbsel = 0; tlbsel < 2; tlbsel++) { 750 748 esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, -1); ··· 751 759 } 752 760 } 753 761 754 - int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int rt, int ra, int rb) 762 + int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int type, gva_t ea) 755 763 { 756 764 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 757 765 int pid = get_cur_spid(vcpu); 758 766 759 - if (rt == 0 || rt == 1) { 760 - tlbilx_all(vcpu_e500, 0, pid, rt); 761 - tlbilx_all(vcpu_e500, 1, pid, rt); 762 - } else if (rt == 3) { 763 - tlbilx_one(vcpu_e500, pid, ra, rb); 767 + if (type == 0 || type == 1) { 768 + tlbilx_all(vcpu_e500, 0, pid, type); 769 + tlbilx_all(vcpu_e500, 1, pid, type); 770 + } else if (type == 3) { 771 + tlbilx_one(vcpu_e500, pid, ea); 764 772 } 765 773 766 774 return EMULATE_DONE; ··· 785 793 return EMULATE_DONE; 786 794 } 787 795 788 - int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb) 796 + int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, gva_t ea) 789 797 { 790 798 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 791 799 int as = !!get_cur_sas(vcpu); 792 800 unsigned int pid = get_cur_spid(vcpu); 793 801 int esel, tlbsel; 794 802 struct kvm_book3e_206_tlb_entry *gtlbe = NULL; 795 - gva_t ea; 796 - 797 - ea = kvmppc_get_gpr(vcpu, rb); 798 803 799 804 for (tlbsel = 0; tlbsel < 2; tlbsel++) { 800 805 esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, as);