kvm/ppc/e500: g2h_tlb1_map: clear old bit before setting new bit
authorScott Wood <scottwood@freescale.com>
Wed, 13 Feb 2013 19:37:49 +0000 (19:37 +0000)
committerAlexander Graf <agraf@suse.de>
Fri, 22 Mar 2013 00:21:13 +0000 (01:21 +0100)
It's possible that we're using the same host TLB1 slot to map (a
presumably different portion of) the same guest TLB1 entry.  Clear
the bit in the map before setting it, so that if the esels are the same
the bit will remain set.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
arch/powerpc/kvm/e500_mmu_host.c

index 35fb80ec1f571bb7692acc12c43faea98006022f..8e72b2124f631065b42582f3893db97ddd5426f3 100644 (file)
@@ -507,13 +507,14 @@ static int kvmppc_e500_tlb1_map_tlb1(struct kvmppc_vcpu_e500 *vcpu_e500,
        if (unlikely(vcpu_e500->host_tlb1_nv >= tlb1_max_shadow_size()))
                vcpu_e500->host_tlb1_nv = 0;
 
-       vcpu_e500->tlb_refs[1][sesel] = *ref;
-       vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel;
-       vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP;
        if (vcpu_e500->h2g_tlb1_rmap[sesel]) {
                unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel] - 1;
                vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << sesel);
        }
+
+       vcpu_e500->tlb_refs[1][sesel] = *ref;
+       vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP;
+       vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel;
        vcpu_e500->h2g_tlb1_rmap[sesel] = esel + 1;
 
        return sesel;