diff options
Diffstat (limited to 'arch/powerpc/kvm/book3s.c')
-rw-r--r-- | arch/powerpc/kvm/book3s.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 42037d46a416..3e294bd9b8c6 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -281,6 +281,7 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) | |||
281 | 281 | ||
282 | void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) | 282 | void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) |
283 | { | 283 | { |
284 | vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB; | ||
284 | vcpu->arch.pvr = pvr; | 285 | vcpu->arch.pvr = pvr; |
285 | if ((pvr >= 0x330000) && (pvr < 0x70330000)) { | 286 | if ((pvr >= 0x330000) && (pvr < 0x70330000)) { |
286 | kvmppc_mmu_book3s_64_init(vcpu); | 287 | kvmppc_mmu_book3s_64_init(vcpu); |
@@ -762,14 +763,62 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
762 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | 763 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, |
763 | struct kvm_sregs *sregs) | 764 | struct kvm_sregs *sregs) |
764 | { | 765 | { |
766 | struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); | ||
767 | int i; | ||
768 | |||
765 | sregs->pvr = vcpu->arch.pvr; | 769 | sregs->pvr = vcpu->arch.pvr; |
770 | |||
771 | sregs->u.s.sdr1 = to_book3s(vcpu)->sdr1; | ||
772 | if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) { | ||
773 | for (i = 0; i < 64; i++) { | ||
774 | sregs->u.s.ppc64.slb[i].slbe = vcpu3s->slb[i].orige | i; | ||
775 | sregs->u.s.ppc64.slb[i].slbv = vcpu3s->slb[i].origv; | ||
776 | } | ||
777 | } else { | ||
778 | for (i = 0; i < 16; i++) { | ||
779 | sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw; | ||
780 | sregs->u.s.ppc32.sr[i] = vcpu3s->sr[i].raw; | ||
781 | } | ||
782 | for (i = 0; i < 8; i++) { | ||
783 | sregs->u.s.ppc32.ibat[i] = vcpu3s->ibat[i].raw; | ||
784 | sregs->u.s.ppc32.dbat[i] = vcpu3s->dbat[i].raw; | ||
785 | } | ||
786 | } | ||
766 | return 0; | 787 | return 0; |
767 | } | 788 | } |
768 | 789 | ||
769 | int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | 790 | int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, |
770 | struct kvm_sregs *sregs) | 791 | struct kvm_sregs *sregs) |
771 | { | 792 | { |
793 | struct kvmppc_vcpu_book3s *vcpu3s = to_book3s(vcpu); | ||
794 | int i; | ||
795 | |||
772 | kvmppc_set_pvr(vcpu, sregs->pvr); | 796 | kvmppc_set_pvr(vcpu, sregs->pvr); |
797 | |||
798 | vcpu3s->sdr1 = sregs->u.s.sdr1; | ||
799 | if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) { | ||
800 | for (i = 0; i < 64; i++) { | ||
801 | vcpu->arch.mmu.slbmte(vcpu, sregs->u.s.ppc64.slb[i].slbv, | ||
802 | sregs->u.s.ppc64.slb[i].slbe); | ||
803 | } | ||
804 | } else { | ||
805 | for (i = 0; i < 16; i++) { | ||
806 | vcpu->arch.mmu.mtsrin(vcpu, i, sregs->u.s.ppc32.sr[i]); | ||
807 | } | ||
808 | for (i = 0; i < 8; i++) { | ||
809 | kvmppc_set_bat(vcpu, &(vcpu3s->ibat[i]), false, | ||
810 | (u32)sregs->u.s.ppc32.ibat[i]); | ||
811 | kvmppc_set_bat(vcpu, &(vcpu3s->ibat[i]), true, | ||
812 | (u32)(sregs->u.s.ppc32.ibat[i] >> 32)); | ||
813 | kvmppc_set_bat(vcpu, &(vcpu3s->dbat[i]), false, | ||
814 | (u32)sregs->u.s.ppc32.dbat[i]); | ||
815 | kvmppc_set_bat(vcpu, &(vcpu3s->dbat[i]), true, | ||
816 | (u32)(sregs->u.s.ppc32.dbat[i] >> 32)); | ||
817 | } | ||
818 | } | ||
819 | |||
820 | /* Flush the MMU after messing with the segments */ | ||
821 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | ||
773 | return 0; | 822 | return 0; |
774 | } | 823 | } |
775 | 824 | ||