diff options
| -rw-r--r-- | arch/powerpc/kvm/book3s_hv_rmhandlers.S | 212 |
1 files changed, 126 insertions, 86 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 245f5c972030..3f6fd78cccd2 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
| @@ -175,6 +175,19 @@ kvmppc_primary_no_guest: | |||
| 175 | /* put the HDEC into the DEC, since HDEC interrupts don't wake us */ | 175 | /* put the HDEC into the DEC, since HDEC interrupts don't wake us */ |
| 176 | mfspr r3, SPRN_HDEC | 176 | mfspr r3, SPRN_HDEC |
| 177 | mtspr SPRN_DEC, r3 | 177 | mtspr SPRN_DEC, r3 |
| 178 | /* | ||
| 179 | * Make sure the primary has finished the MMU switch. | ||
| 180 | * We should never get here on a secondary thread, but | ||
| 181 | * check it for robustness' sake. | ||
| 182 | */ | ||
| 183 | ld r5, HSTATE_KVM_VCORE(r13) | ||
| 184 | 65: lbz r0, VCORE_IN_GUEST(r5) | ||
| 185 | cmpwi r0, 0 | ||
| 186 | beq 65b | ||
| 187 | /* Set LPCR. */ | ||
| 188 | ld r8,VCORE_LPCR(r5) | ||
| 189 | mtspr SPRN_LPCR,r8 | ||
| 190 | isync | ||
| 178 | /* set our bit in napping_threads */ | 191 | /* set our bit in napping_threads */ |
| 179 | ld r5, HSTATE_KVM_VCORE(r13) | 192 | ld r5, HSTATE_KVM_VCORE(r13) |
| 180 | lbz r7, HSTATE_PTID(r13) | 193 | lbz r7, HSTATE_PTID(r13) |
| @@ -206,7 +219,7 @@ kvm_novcpu_wakeup: | |||
| 206 | 219 | ||
| 207 | /* check the wake reason */ | 220 | /* check the wake reason */ |
| 208 | bl kvmppc_check_wake_reason | 221 | bl kvmppc_check_wake_reason |
| 209 | 222 | ||
| 210 | /* see if any other thread is already exiting */ | 223 | /* see if any other thread is already exiting */ |
| 211 | lwz r0, VCORE_ENTRY_EXIT(r5) | 224 | lwz r0, VCORE_ENTRY_EXIT(r5) |
| 212 | cmpwi r0, 0x100 | 225 | cmpwi r0, 0x100 |
| @@ -244,7 +257,15 @@ kvm_novcpu_wakeup: | |||
| 244 | b kvmppc_got_guest | 257 | b kvmppc_got_guest |
| 245 | 258 | ||
| 246 | kvm_novcpu_exit: | 259 | kvm_novcpu_exit: |
| 247 | b hdec_soon | 260 | #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING |
| 261 | ld r4, HSTATE_KVM_VCPU(r13) | ||
| 262 | cmpdi r4, 0 | ||
| 263 | beq 13f | ||
| 264 | addi r3, r4, VCPU_TB_RMEXIT | ||
| 265 | bl kvmhv_accumulate_time | ||
| 266 | #endif | ||
| 267 | 13: bl kvmhv_commence_exit | ||
| 268 | b kvmhv_switch_to_host | ||
| 248 | 269 | ||
| 249 | /* | 270 | /* |
| 250 | * We come in here when wakened from nap mode. | 271 | * We come in here when wakened from nap mode. |
| @@ -422,7 +443,7 @@ kvmppc_hv_entry: | |||
| 422 | /* Primary thread switches to guest partition. */ | 443 | /* Primary thread switches to guest partition. */ |
| 423 | ld r9,VCORE_KVM(r5) /* pointer to struct kvm */ | 444 | ld r9,VCORE_KVM(r5) /* pointer to struct kvm */ |
| 424 | cmpwi r6,0 | 445 | cmpwi r6,0 |
| 425 | bne 20f | 446 | bne 10f |
| 426 | ld r6,KVM_SDR1(r9) | 447 | ld r6,KVM_SDR1(r9) |
| 427 | lwz r7,KVM_LPID(r9) | 448 | lwz r7,KVM_LPID(r9) |
| 428 | li r0,LPID_RSVD /* switch to reserved LPID */ | 449 | li r0,LPID_RSVD /* switch to reserved LPID */ |
| @@ -493,26 +514,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
| 493 | 514 | ||
| 494 | li r0,1 | 515 | li r0,1 |
| 495 | stb r0,VCORE_IN_GUEST(r5) /* signal secondaries to continue */ | 516 | stb r0,VCORE_IN_GUEST(r5) /* signal secondaries to continue */ |
| 496 | b 10f | ||
| 497 | |||
| 498 | /* Secondary threads wait for primary to have done partition switch */ | ||
| 499 | 20: lbz r0,VCORE_IN_GUEST(r5) | ||
| 500 | cmpwi r0,0 | ||
| 501 | beq 20b | ||
| 502 | |||
| 503 | /* Set LPCR. */ | ||
| 504 | 10: ld r8,VCORE_LPCR(r5) | ||
| 505 | mtspr SPRN_LPCR,r8 | ||
| 506 | isync | ||
| 507 | |||
| 508 | /* Check if HDEC expires soon */ | ||
| 509 | mfspr r3,SPRN_HDEC | ||
| 510 | cmpwi r3,512 /* 1 microsecond */ | ||
| 511 | li r12,BOOK3S_INTERRUPT_HV_DECREMENTER | ||
| 512 | blt hdec_soon | ||
| 513 | 517 | ||
| 514 | /* Do we have a guest vcpu to run? */ | 518 | /* Do we have a guest vcpu to run? */ |
| 515 | cmpdi r4, 0 | 519 | 10: cmpdi r4, 0 |
| 516 | beq kvmppc_primary_no_guest | 520 | beq kvmppc_primary_no_guest |
| 517 | kvmppc_got_guest: | 521 | kvmppc_got_guest: |
| 518 | 522 | ||
| @@ -837,6 +841,30 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) | |||
| 837 | clrrdi r6,r6,1 | 841 | clrrdi r6,r6,1 |
| 838 | mtspr SPRN_CTRLT,r6 | 842 | mtspr SPRN_CTRLT,r6 |
| 839 | 4: | 843 | 4: |
| 844 | /* Secondary threads wait for primary to have done partition switch */ | ||
| 845 | ld r5, HSTATE_KVM_VCORE(r13) | ||
| 846 | lbz r6, HSTATE_PTID(r13) | ||
| 847 | cmpwi r6, 0 | ||
| 848 | beq 21f | ||
| 849 | lbz r0, VCORE_IN_GUEST(r5) | ||
| 850 | cmpwi r0, 0 | ||
| 851 | bne 21f | ||
| 852 | HMT_LOW | ||
| 853 | 20: lbz r0, VCORE_IN_GUEST(r5) | ||
| 854 | cmpwi r0, 0 | ||
| 855 | beq 20b | ||
| 856 | HMT_MEDIUM | ||
| 857 | 21: | ||
| 858 | /* Set LPCR. */ | ||
| 859 | ld r8,VCORE_LPCR(r5) | ||
| 860 | mtspr SPRN_LPCR,r8 | ||
| 861 | isync | ||
| 862 | |||
| 863 | /* Check if HDEC expires soon */ | ||
| 864 | mfspr r3, SPRN_HDEC | ||
| 865 | cmpwi r3, 512 /* 1 microsecond */ | ||
| 866 | blt hdec_soon | ||
| 867 | |||
| 840 | ld r6, VCPU_CTR(r4) | 868 | ld r6, VCPU_CTR(r4) |
| 841 | lwz r7, VCPU_XER(r4) | 869 | lwz r7, VCPU_XER(r4) |
| 842 | 870 | ||
| @@ -942,22 +970,26 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | |||
| 942 | hrfid | 970 | hrfid |
| 943 | b . | 971 | b . |
| 944 | 972 | ||
| 945 | #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING | ||
| 946 | secondary_too_late: | 973 | secondary_too_late: |
| 974 | li r12, 0 | ||
| 947 | cmpdi r4, 0 | 975 | cmpdi r4, 0 |
| 948 | beq 11f | 976 | beq 11f |
| 977 | stw r12, VCPU_TRAP(r4) | ||
| 978 | #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING | ||
| 949 | addi r3, r4, VCPU_TB_RMEXIT | 979 | addi r3, r4, VCPU_TB_RMEXIT |
| 950 | bl kvmhv_accumulate_time | 980 | bl kvmhv_accumulate_time |
| 981 | #endif | ||
| 951 | 11: b kvmhv_switch_to_host | 982 | 11: b kvmhv_switch_to_host |
| 952 | 983 | ||
| 953 | hdec_soon: | 984 | hdec_soon: |
| 954 | ld r4, HSTATE_KVM_VCPU(r13) | 985 | li r12, BOOK3S_INTERRUPT_HV_DECREMENTER |
| 955 | cmpdi r4, 0 | 986 | stw r12, VCPU_TRAP(r4) |
| 956 | beq 12f | 987 | mr r9, r4 |
| 988 | #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING | ||
| 957 | addi r3, r4, VCPU_TB_RMEXIT | 989 | addi r3, r4, VCPU_TB_RMEXIT |
| 958 | bl kvmhv_accumulate_time | 990 | bl kvmhv_accumulate_time |
| 959 | 12: b kvmhv_do_exit | ||
| 960 | #endif | 991 | #endif |
| 992 | b guest_exit_cont | ||
| 961 | 993 | ||
| 962 | /****************************************************************************** | 994 | /****************************************************************************** |
| 963 | * * | 995 | * * |
| @@ -1113,7 +1145,7 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */ | |||
| 1113 | stw r7, VCPU_DSISR(r9) | 1145 | stw r7, VCPU_DSISR(r9) |
| 1114 | /* don't overwrite fault_dar/fault_dsisr if HDSI */ | 1146 | /* don't overwrite fault_dar/fault_dsisr if HDSI */ |
| 1115 | cmpwi r12,BOOK3S_INTERRUPT_H_DATA_STORAGE | 1147 | cmpwi r12,BOOK3S_INTERRUPT_H_DATA_STORAGE |
| 1116 | beq 6f | 1148 | beq mc_cont |
| 1117 | std r6, VCPU_FAULT_DAR(r9) | 1149 | std r6, VCPU_FAULT_DAR(r9) |
| 1118 | stw r7, VCPU_FAULT_DSISR(r9) | 1150 | stw r7, VCPU_FAULT_DSISR(r9) |
| 1119 | 1151 | ||
| @@ -1127,8 +1159,11 @@ mc_cont: | |||
| 1127 | bl kvmhv_accumulate_time | 1159 | bl kvmhv_accumulate_time |
| 1128 | #endif | 1160 | #endif |
| 1129 | 1161 | ||
| 1162 | /* Increment exit count, poke other threads to exit */ | ||
| 1163 | bl kvmhv_commence_exit | ||
| 1164 | |||
| 1130 | /* Save guest CTRL register, set runlatch to 1 */ | 1165 | /* Save guest CTRL register, set runlatch to 1 */ |
| 1131 | 6: mfspr r6,SPRN_CTRLF | 1166 | mfspr r6,SPRN_CTRLF |
| 1132 | stw r6,VCPU_CTRL(r9) | 1167 | stw r6,VCPU_CTRL(r9) |
| 1133 | andi. r0,r6,1 | 1168 | andi. r0,r6,1 |
| 1134 | bne 4f | 1169 | bne 4f |
| @@ -1470,68 +1505,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
| 1470 | slbia | 1505 | slbia |
| 1471 | ptesync | 1506 | ptesync |
| 1472 | 1507 | ||
| 1473 | #ifndef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING | ||
| 1474 | hdec_soon: | ||
| 1475 | #endif | ||
| 1476 | kvmhv_do_exit: /* r12 = trap, r13 = paca */ | ||
