aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2014-01-08 05:25:21 -0500
committerAlexander Graf <agraf@suse.de>2014-01-27 10:01:00 -0500
commitb005255e12a311d2c87ea70a7c7b192b2187c22c (patch)
tree739892c411d395a7e4181bc2dc58c54d851d595f /arch/powerpc/kvm
parente0b7ec058c0eb7ba8d5d937d81de2bd16db6970e (diff)
KVM: PPC: Book3S HV: Context-switch new POWER8 SPRs
This adds fields to the struct kvm_vcpu_arch to store the new guest-accessible SPRs on POWER8, adds code to the get/set_one_reg functions to allow userspace to access this state, and adds code to the guest entry and exit to context-switch these SPRs between host and guest. Note that DPDES (Directed Privileged Doorbell Exception State) is shared between threads on a core; hence we store it in struct kvmppc_vcore and have the master thread save and restore it. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/book3s_hv.c153
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S145
2 files changed, 296 insertions, 2 deletions
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 7da53cd215db..5b08ddf91d2d 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -800,7 +800,7 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
800 case KVM_REG_PPC_UAMOR: 800 case KVM_REG_PPC_UAMOR:
801 *val = get_reg_val(id, vcpu->arch.uamor); 801 *val = get_reg_val(id, vcpu->arch.uamor);
802 break; 802 break;
803 case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRA: 803 case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRS:
804 i = id - KVM_REG_PPC_MMCR0; 804 i = id - KVM_REG_PPC_MMCR0;
805 *val = get_reg_val(id, vcpu->arch.mmcr[i]); 805 *val = get_reg_val(id, vcpu->arch.mmcr[i]);
806 break; 806 break;
@@ -808,12 +808,85 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
808 i = id - KVM_REG_PPC_PMC1; 808 i = id - KVM_REG_PPC_PMC1;
809 *val = get_reg_val(id, vcpu->arch.pmc[i]); 809 *val = get_reg_val(id, vcpu->arch.pmc[i]);
810 break; 810 break;
811 case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2:
812 i = id - KVM_REG_PPC_SPMC1;
813 *val = get_reg_val(id, vcpu->arch.spmc[i]);
814 break;
811 case KVM_REG_PPC_SIAR: 815 case KVM_REG_PPC_SIAR:
812 *val = get_reg_val(id, vcpu->arch.siar); 816 *val = get_reg_val(id, vcpu->arch.siar);
813 break; 817 break;
814 case KVM_REG_PPC_SDAR: 818 case KVM_REG_PPC_SDAR:
815 *val = get_reg_val(id, vcpu->arch.sdar); 819 *val = get_reg_val(id, vcpu->arch.sdar);
816 break; 820 break;
821 case KVM_REG_PPC_SIER:
822 *val = get_reg_val(id, vcpu->arch.sier);
823 break;
824 case KVM_REG_PPC_IAMR:
825 *val = get_reg_val(id, vcpu->arch.iamr);
826 break;
827 case KVM_REG_PPC_TFHAR:
828 *val = get_reg_val(id, vcpu->arch.tfhar);
829 break;
830 case KVM_REG_PPC_TFIAR:
831 *val = get_reg_val(id, vcpu->arch.tfiar);
832 break;
833 case KVM_REG_PPC_TEXASR:
834 *val = get_reg_val(id, vcpu->arch.texasr);
835 break;
836 case KVM_REG_PPC_FSCR:
837 *val = get_reg_val(id, vcpu->arch.fscr);
838 break;
839 case KVM_REG_PPC_PSPB:
840 *val = get_reg_val(id, vcpu->arch.pspb);
841 break;
842 case KVM_REG_PPC_EBBHR:
843 *val = get_reg_val(id, vcpu->arch.ebbhr);
844 break;
845 case KVM_REG_PPC_EBBRR:
846 *val = get_reg_val(id, vcpu->arch.ebbrr);
847 break;
848 case KVM_REG_PPC_BESCR:
849 *val = get_reg_val(id, vcpu->arch.bescr);
850 break;
851 case KVM_REG_PPC_TAR:
852 *val = get_reg_val(id, vcpu->arch.tar);
853 break;
854 case KVM_REG_PPC_DPDES:
855 *val = get_reg_val(id, vcpu->arch.vcore->dpdes);
856 break;
857 case KVM_REG_PPC_DAWR:
858 *val = get_reg_val(id, vcpu->arch.dawr);
859 break;
860 case KVM_REG_PPC_DAWRX:
861 *val = get_reg_val(id, vcpu->arch.dawrx);
862 break;
863 case KVM_REG_PPC_CIABR:
864 *val = get_reg_val(id, vcpu->arch.ciabr);
865 break;
866 case KVM_REG_PPC_IC:
867 *val = get_reg_val(id, vcpu->arch.ic);
868 break;
869 case KVM_REG_PPC_VTB:
870 *val = get_reg_val(id, vcpu->arch.vtb);
871 break;
872 case KVM_REG_PPC_CSIGR:
873 *val = get_reg_val(id, vcpu->arch.csigr);
874 break;
875 case KVM_REG_PPC_TACR:
876 *val = get_reg_val(id, vcpu->arch.tacr);
877 break;
878 case KVM_REG_PPC_TCSCR:
879 *val = get_reg_val(id, vcpu->arch.tcscr);
880 break;
881 case KVM_REG_PPC_PID:
882 *val = get_reg_val(id, vcpu->arch.pid);
883 break;
884 case KVM_REG_PPC_ACOP:
885 *val = get_reg_val(id, vcpu->arch.acop);
886 break;
887 case KVM_REG_PPC_WORT:
888 *val = get_reg_val(id, vcpu->arch.wort);
889 break;
817 case KVM_REG_PPC_VPA_ADDR: 890 case KVM_REG_PPC_VPA_ADDR:
818 spin_lock(&vcpu->arch.vpa_update_lock); 891 spin_lock(&vcpu->arch.vpa_update_lock);
819 *val = get_reg_val(id, vcpu->arch.vpa.next_gpa); 892 *val = get_reg_val(id, vcpu->arch.vpa.next_gpa);
@@ -882,7 +955,7 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
882 case KVM_REG_PPC_UAMOR: 955 case KVM_REG_PPC_UAMOR:
883 vcpu->arch.uamor = set_reg_val(id, *val); 956 vcpu->arch.uamor = set_reg_val(id, *val);
884 break; 957 break;
885 case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRA: 958 case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCRS:
886 i = id - KVM_REG_PPC_MMCR0; 959 i = id - KVM_REG_PPC_MMCR0;
887 vcpu->arch.mmcr[i] = set_reg_val(id, *val); 960 vcpu->arch.mmcr[i] = set_reg_val(id, *val);
888 break; 961 break;
@@ -890,12 +963,88 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
890 i = id - KVM_REG_PPC_PMC1; 963 i = id - KVM_REG_PPC_PMC1;
891 vcpu->arch.pmc[i] = set_reg_val(id, *val); 964 vcpu->arch.pmc[i] = set_reg_val(id, *val);
892 break; 965 break;
966 case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2:
967 i = id - KVM_REG_PPC_SPMC1;
968 vcpu->arch.spmc[i] = set_reg_val(id, *val);
969 break;
893 case KVM_REG_PPC_SIAR: 970 case KVM_REG_PPC_SIAR:
894 vcpu->arch.siar = set_reg_val(id, *val); 971 vcpu->arch.siar = set_reg_val(id, *val);
895 break; 972 break;
896 case KVM_REG_PPC_SDAR: 973 case KVM_REG_PPC_SDAR:
897 vcpu->arch.sdar = set_reg_val(id, *val); 974 vcpu->arch.sdar = set_reg_val(id, *val);
898 break; 975 break;
976 case KVM_REG_PPC_SIER:
977 vcpu->arch.sier = set_reg_val(id, *val);
978 break;
979 case KVM_REG_PPC_IAMR:
980 vcpu->arch.iamr = set_reg_val(id, *val);
981 break;
982 case KVM_REG_PPC_TFHAR:
983 vcpu->arch.tfhar = set_reg_val(id, *val);
984 break;
985 case KVM_REG_PPC_TFIAR:
986 vcpu->arch.tfiar = set_reg_val(id, *val);
987 break;
988 case KVM_REG_PPC_TEXASR:
989 vcpu->arch.texasr = set_reg_val(id, *val);
990 break;
991 case KVM_REG_PPC_FSCR:
992 vcpu->arch.fscr = set_reg_val(id, *val);
993 break;
994 case KVM_REG_PPC_PSPB:
995 vcpu->arch.pspb = set_reg_val(id, *val);
996 break;
997 case KVM_REG_PPC_EBBHR:
998 vcpu->arch.ebbhr = set_reg_val(id, *val);
999 break;
1000 case KVM_REG_PPC_EBBRR:
1001 vcpu->arch.ebbrr = set_reg_val(id, *val);
1002 break;
1003 case KVM_REG_PPC_BESCR:
1004 vcpu->arch.bescr = set_reg_val(id, *val);
1005 break;
1006 case KVM_REG_PPC_TAR:
1007 vcpu->arch.tar = set_reg_val(id, *val);
1008 break;
1009 case KVM_REG_PPC_DPDES:
1010 vcpu->arch.vcore->dpdes = set_reg_val(id, *val);
1011 break;
1012 case KVM_REG_PPC_DAWR:
1013 vcpu->arch.dawr = set_reg_val(id, *val);
1014 break;
1015 case KVM_REG_PPC_DAWRX:
1016 vcpu->arch.dawrx = set_reg_val(id, *val) & ~DAWRX_HYP;
1017 break;
1018 case KVM_REG_PPC_CIABR:
1019 vcpu->arch.ciabr = set_reg_val(id, *val);
1020 /* Don't allow setting breakpoints in hypervisor code */
1021 if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER)
1022 vcpu->arch.ciabr &= ~CIABR_PRIV; /* disable */
1023 break;
1024 case KVM_REG_PPC_IC:
1025 vcpu->arch.ic = set_reg_val(id, *val);
1026 break;
1027 case KVM_REG_PPC_VTB:
1028 vcpu->arch.vtb = set_reg_val(id, *val);
1029 break;
1030 case KVM_REG_PPC_CSIGR:
1031 vcpu->arch.csigr = set_reg_val(id, *val);
1032 break;
1033 case KVM_REG_PPC_TACR:
1034 vcpu->arch.tacr = set_reg_val(id, *val);
1035 break;
1036 case KVM_REG_PPC_TCSCR:
1037 vcpu->arch.tcscr = set_reg_val(id, *val);
1038 break;
1039 case KVM_REG_PPC_PID:
1040 vcpu->arch.pid = set_reg_val(id, *val);
1041 break;
1042 case KVM_REG_PPC_ACOP:
1043 vcpu->arch.acop = set_reg_val(id, *val);
1044 break;
1045 case KVM_REG_PPC_WORT:
1046 vcpu->arch.wort = set_reg_val(id, *val);
1047 break;
899 case KVM_REG_PPC_VPA_ADDR: 1048 case KVM_REG_PPC_VPA_ADDR:
900 addr = set_reg_val(id, *val); 1049 addr = set_reg_val(id, *val);
901 r = -EINVAL; 1050 r = -EINVAL;
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 8bbe91bdb6da..691dd1ef555b 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -460,6 +460,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
460 beq 38f 460 beq 38f
461 mtspr SPRN_PCR, r7 461 mtspr SPRN_PCR, r7
46238: 46238:
463
464BEGIN_FTR_SECTION
465 /* DPDES is shared between threads */
466 ld r8, VCORE_DPDES(r5)
467 mtspr SPRN_DPDES, r8
468END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
469
463 li r0,1 470 li r0,1
464 stb r0,VCORE_IN_GUEST(r5) /* signal secondaries to continue */ 471 stb r0,VCORE_IN_GUEST(r5) /* signal secondaries to continue */
465 b 10f 472 b 10f
@@ -659,6 +666,18 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
659 mtspr SPRN_MMCRA, r6 666 mtspr SPRN_MMCRA, r6
660 mtspr SPRN_SIAR, r7 667 mtspr SPRN_SIAR, r7
661 mtspr SPRN_SDAR, r8 668 mtspr SPRN_SDAR, r8
669BEGIN_FTR_SECTION
670 ld r5, VCPU_MMCR + 24(r4)
671 ld r6, VCPU_SIER(r4)
672 lwz r7, VCPU_PMC + 24(r4)
673 lwz r8, VCPU_PMC + 28(r4)
674 ld r9, VCPU_MMCR + 32(r4)
675 mtspr SPRN_MMCR2, r5
676 mtspr SPRN_SIER, r6
677 mtspr SPRN_SPMC1, r7
678 mtspr SPRN_SPMC2, r8
679 mtspr SPRN_MMCRS, r9
680END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
662 mtspr SPRN_MMCR0, r3 681 mtspr SPRN_MMCR0, r3
663 isync 682 isync
664 683
@@ -690,6 +709,61 @@ BEGIN_FTR_SECTION
690 mtspr SPRN_DSCR, r5 709 mtspr SPRN_DSCR, r5
691END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) 710END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
692 711
712BEGIN_FTR_SECTION
713 /* Skip next section on POWER7 or PPC970 */
714 b 8f
715END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
716 /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
717 mfmsr r8
718 li r0, 1
719 rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG
720 mtmsrd r8
721
722 /* Load up POWER8-specific registers */
723 ld r5, VCPU_IAMR(r4)
724 lwz r6, VCPU_PSPB(r4)
725 ld r7, VCPU_FSCR(r4)
726 mtspr SPRN_IAMR, r5
727 mtspr SPRN_PSPB, r6
728 mtspr SPRN_FSCR, r7
729 ld r5, VCPU_DAWR(r4)
730 ld r6, VCPU_DAWRX(r4)
731 ld r7, VCPU_CIABR(r4)
732 ld r8, VCPU_TAR(r4)
733 mtspr SPRN_DAWR, r5
734 mtspr SPRN_DAWRX, r6
735 mtspr SPRN_CIABR, r7
736 mtspr SPRN_TAR, r8
737 ld r5, VCPU_IC(r4)
738 ld r6, VCPU_VTB(r4)
739 mtspr SPRN_IC, r5
740 mtspr SPRN_VTB, r6
741 ld r5, VCPU_TFHAR(r4)
742 ld r6, VCPU_TFIAR(r4)
743 ld r7, VCPU_TEXASR(r4)
744 ld r8, VCPU_EBBHR(r4)
745 mtspr SPRN_TFHAR, r5
746 mtspr SPRN_TFIAR, r6
747 mtspr SPRN_TEXASR, r7
748 mtspr SPRN_EBBHR, r8
749 ld r5, VCPU_EBBRR(r4)
750 ld r6, VCPU_BESCR(r4)
751 ld r7, VCPU_CSIGR(r4)
752 ld r8, VCPU_TACR(r4)
753 mtspr SPRN_EBBRR, r5
754 mtspr SPRN_BESCR, r6
755 mtspr SPRN_CSIGR, r7
756 mtspr SPRN_TACR, r8
757 ld r5, VCPU_TCSCR(r4)
758 ld r6, VCPU_ACOP(r4)
759 lwz r7, VCPU_GUEST_PID(r4)
760 ld r8, VCPU_WORT(r4)
761 mtspr SPRN_TCSCR, r5
762 mtspr SPRN_ACOP, r6
763 mtspr SPRN_PID, r7
764 mtspr SPRN_WORT, r8
7658:
766
693 /* 767 /*
694 * Set the decrementer to the guest decrementer. 768 * Set the decrementer to the guest decrementer.
695 */ 769 */
@@ -1081,6 +1155,54 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_201)
1081 add r5,r5,r6 1155 add r5,r5,r6
1082 std r5,VCPU_DEC_EXPIRES(r9) 1156 std r5,VCPU_DEC_EXPIRES(r9)
1083 1157
1158BEGIN_FTR_SECTION
1159 b 8f
1160END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
1161 /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */
1162 mfmsr r8
1163 li r0, 1
1164 rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG
1165 mtmsrd r8
1166
1167 /* Save POWER8-specific registers */
1168 mfspr r5, SPRN_IAMR
1169 mfspr r6, SPRN_PSPB
1170 mfspr r7, SPRN_FSCR
1171 std r5, VCPU_IAMR(r9)
1172 stw r6, VCPU_PSPB(r9)
1173 std r7, VCPU_FSCR(r9)
1174 mfspr r5, SPRN_IC
1175 mfspr r6, SPRN_VTB
1176 mfspr r7, SPRN_TAR
1177 std r5, VCPU_IC(r9)
1178 std r6, VCPU_VTB(r9)
1179 std r7, VCPU_TAR(r9)
1180 mfspr r5, SPRN_TFHAR
1181 mfspr r6, SPRN_TFIAR
1182 mfspr r7, SPRN_TEXASR
1183 mfspr r8, SPRN_EBBHR
1184 std r5, VCPU_TFHAR(r9)
1185 std r6, VCPU_TFIAR(r9)
1186 std r7, VCPU_TEXASR(r9)
1187 std r8, VCPU_EBBHR(r9)
1188 mfspr r5, SPRN_EBBRR
1189 mfspr r6, SPRN_BESCR
1190 mfspr r7, SPRN_CSIGR
1191 mfspr r8, SPRN_TACR
1192 std r5, VCPU_EBBRR(r9)
1193 std r6, VCPU_BESCR(r9)
1194 std r7, VCPU_CSIGR(r9)
1195 std r8, VCPU_TACR(r9)
1196 mfspr r5, SPRN_TCSCR
1197 mfspr r6, SPRN_ACOP
1198 mfspr r7, SPRN_PID
1199 mfspr r8, SPRN_WORT
1200 std r5, VCPU_TCSCR(r9)
1201 std r6, VCPU_ACOP(r9)
1202 stw r7, VCPU_GUEST_PID(r9)
1203 std r8, VCPU_WORT(r9)
12048:
1205
1084 /* Save and reset AMR and UAMOR before turning on the MMU */ 1206 /* Save and reset AMR and UAMOR before turning on the MMU */
1085BEGIN_FTR_SECTION 1207BEGIN_FTR_SECTION
1086 mfspr r5,SPRN_AMR 1208 mfspr r5,SPRN_AMR
@@ -1190,6 +1312,20 @@ BEGIN_FTR_SECTION
1190 stw r10, VCPU_PMC + 24(r9) 1312 stw r10, VCPU_PMC + 24(r9)
1191 stw r11, VCPU_PMC + 28(r9) 1313 stw r11, VCPU_PMC + 28(r9)
1192END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) 1314END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
1315BEGIN_FTR_SECTION
1316 mfspr r4, SPRN_MMCR2
1317 mfspr r5, SPRN_SIER
1318 mfspr r6, SPRN_SPMC1
1319 mfspr r7, SPRN_SPMC2
1320 mfspr r8, SPRN_MMCRS
1321 std r4, VCPU_MMCR + 24(r9)
1322 std r5, VCPU_SIER(r9)
1323 stw r6, VCPU_PMC + 24(r9)
1324 stw r7, VCPU_PMC + 28(r9)
1325 std r8, VCPU_MMCR + 32(r9)
1326 lis r4, 0x8000
1327 mtspr SPRN_MMCRS, r4
1328END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
119322: 132922:
1194 /* Clear out SLB */ 1330 /* Clear out SLB */
1195 li r5,0 1331 li r5,0
@@ -1290,6 +1426,15 @@ secondary_too_late:
1290 mtspr SPRN_LPID,r7 1426 mtspr SPRN_LPID,r7
1291 isync 1427 isync
1292 1428
1429BEGIN_FTR_SECTION
1430 /* DPDES is shared between threads */
1431 mfspr r7, SPRN_DPDES
1432 std r7, VCORE_DPDES(r5)
1433 /* clear DPDES so we don't get guest doorbells in the host */
1434 li r8, 0
1435 mtspr SPRN_DPDES, r8
1436END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
1437
1293 /* Subtract timebase offset from timebase */ 1438 /* Subtract timebase offset from timebase */
1294 ld r8,VCORE_TB_OFFSET(r5) 1439 ld r8,VCORE_TB_OFFSET(r5)
1295 cmpdi r8,0 1440 cmpdi r8,0