aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2011-08-18 16:25:14 -0400
committerAvi Kivity <avi@redhat.com>2012-03-05 07:52:23 -0500
commit3bf3cdcc148abcd0e9d398393d390ff136d6eb9a (patch)
tree6a315d5d4398144d0f7f876cec2d52d27e8cef4e
parent59674c1a6a35d56ae5197cbc9abe7bfec6762ba9 (diff)
KVM: PPC: e500: don't translate gfn to pfn with preemption disabled
Delay allocation of the shadow pid until we're ready to disable preemption and write the entry. Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/powerpc/kvm/e500_tlb.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 13c432ea2fa8..22624a7ae821 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -507,21 +507,16 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
507 vcpu_e500->mas7 = 0; 507 vcpu_e500->mas7 = 0;
508} 508}
509 509
510/* TID must be supplied by the caller */
510static inline void kvmppc_e500_setup_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500, 511static inline void kvmppc_e500_setup_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
511 struct tlbe *gtlbe, int tsize, 512 struct tlbe *gtlbe, int tsize,
512 struct tlbe_priv *priv, 513 struct tlbe_priv *priv,
513 u64 gvaddr, struct tlbe *stlbe) 514 u64 gvaddr, struct tlbe *stlbe)
514{ 515{
515 pfn_t pfn = priv->pfn; 516 pfn_t pfn = priv->pfn;
516 unsigned int stid;
517
518 stid = kvmppc_e500_get_sid(vcpu_e500, get_tlb_ts(gtlbe),
519 get_tlb_tid(gtlbe),
520 get_cur_pr(&vcpu_e500->vcpu), 0);
521 517
522 /* Force TS=1 IPROT=0 for all guest mappings. */ 518 /* Force TS=1 IPROT=0 for all guest mappings. */
523 stlbe->mas1 = MAS1_TSIZE(tsize) 519 stlbe->mas1 = MAS1_TSIZE(tsize) | MAS1_TS | MAS1_VALID;
524 | MAS1_TID(stid) | MAS1_TS | MAS1_VALID;
525 stlbe->mas2 = (gvaddr & MAS2_EPN) 520 stlbe->mas2 = (gvaddr & MAS2_EPN)
526 | e500_shadow_mas2_attrib(gtlbe->mas2, 521 | e500_shadow_mas2_attrib(gtlbe->mas2,
527 vcpu_e500->vcpu.arch.shared->msr & MSR_PR); 522 vcpu_e500->vcpu.arch.shared->msr & MSR_PR);
@@ -816,6 +811,24 @@ int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb)
816 return EMULATE_DONE; 811 return EMULATE_DONE;
817} 812}
818 813
814/* sesel is index into the set, not the whole array */
815static void write_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
816 struct tlbe *gtlbe,
817 struct tlbe *stlbe,
818 int stlbsel, int sesel)
819{
820 int stid;
821
822 preempt_disable();
823 stid = kvmppc_e500_get_sid(vcpu_e500, get_tlb_ts(gtlbe),
824 get_tlb_tid(gtlbe),
825 get_cur_pr(&vcpu_e500->vcpu), 0);
826
827 stlbe->mas1 |= MAS1_TID(stid);
828 write_host_tlbe(vcpu_e500, stlbsel, sesel, stlbe);
829 preempt_enable();
830}
831
819int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) 832int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
820{ 833{
821 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 834 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
@@ -845,7 +858,6 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
845 u64 eaddr; 858 u64 eaddr;
846 u64 raddr; 859 u64 raddr;
847 860
848 preempt_disable();
849 switch (tlbsel) { 861 switch (tlbsel) {
850 case 0: 862 case 0:
851 /* TLB0 */ 863 /* TLB0 */
@@ -874,8 +886,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
874 default: 886 default:
875 BUG(); 887 BUG();
876 } 888 }
877 write_host_tlbe(vcpu_e500, stlbsel, sesel, &stlbe); 889
878 preempt_enable(); 890 write_stlbe(vcpu_e500, gtlbe, &stlbe, stlbsel, sesel);
879 } 891 }
880 892
881 kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); 893 kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS);
@@ -937,7 +949,6 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
937 949
938 gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel]; 950 gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel];
939 951
940 preempt_disable();
941 switch (tlbsel) { 952 switch (tlbsel) {
942 case 0: 953 case 0:
943 stlbsel = 0; 954 stlbsel = 0;
@@ -962,8 +973,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
962 break; 973 break;
963 } 974 }
964 975
965 write_host_tlbe(vcpu_e500, stlbsel, sesel, &stlbe); 976 write_stlbe(vcpu_e500, gtlbe, &stlbe, stlbsel, sesel);
966 preempt_enable();
967} 977}
968 978
969int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu, 979int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,