diff options
author | Scott Wood <scottwood@freescale.com> | 2011-08-18 16:25:14 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-03-05 07:52:23 -0500 |
commit | 3bf3cdcc148abcd0e9d398393d390ff136d6eb9a (patch) | |
tree | 6a315d5d4398144d0f7f876cec2d52d27e8cef4e | |
parent | 59674c1a6a35d56ae5197cbc9abe7bfec6762ba9 (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.c | 36 |
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 */ | ||
510 | static inline void kvmppc_e500_setup_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500, | 511 | static 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 */ | ||
815 | static 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 | |||
819 | int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) | 832 | int 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 | ||
969 | int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu, | 979 | int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu, |