aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorBharat Bhushan <r65777@freescale.com>2013-11-15 00:31:13 -0500
committerAlexander Graf <agraf@suse.de>2014-01-09 04:15:04 -0500
commit30a91fe24b7a6475d22d22fb0f772318ed435a1d (patch)
tree0c01cb9668342e5ce0bd15ff3e34e353a922bb92 /arch/powerpc/kvm
parent595e4f7e697e2e6fb252f6be6a83d5b9460b59a3 (diff)
kvm: booke: clear host tlb reference flag on guest tlb invalidation
On booke, "struct tlbe_ref" contains host tlb mapping information (pfn: for guest-pfn to pfn, flags: attribute associated with this mapping) for a guest tlb entry. So when a guest creates a TLB entry then "struct tlbe_ref" is set to point to valid "pfn" and set attributes in "flags" field of the above said structure. When a guest TLB entry is invalidated then flags field of corresponding "struct tlbe_ref" is updated to point that this is no more valid, also we selectively clear some other attribute bits, example: if E500_TLB_BITMAP was set then we clear E500_TLB_BITMAP, if E500_TLB_TLB0 is set then we clear this. Ideally we should clear complete "flags" as this entry is invalid and does not have anything to re-used. The other part of the problem is that when we use the same entry again then also we do not clear (started doing or-ing etc). So far it was working because the selectively clearing mentioned above actually clears "flags" what was set during TLB mapping. But the problem starts coming when we add more attributes to this then we need to selectively clear them and which is not needed. Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com> Reviewed-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/e500_mmu_host.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c
index ecf2247b13be..a45e25cd78fc 100644
--- a/arch/powerpc/kvm/e500_mmu_host.c
+++ b/arch/powerpc/kvm/e500_mmu_host.c
@@ -231,15 +231,15 @@ void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel,
231 ref->flags &= ~(E500_TLB_TLB0 | E500_TLB_VALID); 231 ref->flags &= ~(E500_TLB_TLB0 | E500_TLB_VALID);
232 } 232 }
233 233
234 /* Already invalidated in between */ 234 /*
235 if (!(ref->flags & E500_TLB_VALID)) 235 * If TLB entry is still valid then it's a TLB0 entry, and thus
236 return; 236 * backed by at most one host tlbe per shadow pid
237 237 */
238 /* Guest tlbe is backed by at most one host tlbe per shadow pid. */ 238 if (ref->flags & E500_TLB_VALID)
239 kvmppc_e500_tlbil_one(vcpu_e500, gtlbe); 239 kvmppc_e500_tlbil_one(vcpu_e500, gtlbe);
240 240
241 /* Mark the TLB as not backed by the host anymore */ 241 /* Mark the TLB as not backed by the host anymore */
242 ref->flags &= ~E500_TLB_VALID; 242 ref->flags = 0;
243} 243}
244 244
245static inline int tlbe_is_writable(struct kvm_book3e_206_tlb_entry *tlbe) 245static inline int tlbe_is_writable(struct kvm_book3e_206_tlb_entry *tlbe)
@@ -252,7 +252,7 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref,
252 pfn_t pfn) 252 pfn_t pfn)
253{ 253{
254 ref->pfn = pfn; 254 ref->pfn = pfn;
255 ref->flags |= E500_TLB_VALID; 255 ref->flags = E500_TLB_VALID;
256 256
257 /* Mark the page accessed */ 257 /* Mark the page accessed */
258 kvm_set_pfn_accessed(pfn); 258 kvm_set_pfn_accessed(pfn);