aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiao Guangrong <xiaoguangrong@cn.fujitsu.com>2010-05-12 22:08:08 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:35:46 -0400
commitf55c3f419ab1f0a9d66f44ceeefe752975ae4233 (patch)
tree9553bcf0c3af3ceac9bf6ce6c28ee0fdac28f525
parent6d74229f013ed8e4a00d74cfa7a3fa6a2315c467 (diff)
KVM: MMU: unalias gfn before sp->gfns[] comparison in sync_page
sp->gfns[] contain unaliased gfns, but gpte might contain pointer to aliased region. Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--arch/x86/kvm/paging_tmpl.h7
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 15e379eaf3b0..22f13797f521 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -586,7 +586,7 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
586 unsigned pte_access; 586 unsigned pte_access;
587 pt_element_t gpte; 587 pt_element_t gpte;
588 gpa_t pte_gpa; 588 gpa_t pte_gpa;
589 gfn_t gfn = sp->gfns[i]; 589 gfn_t gfn;
590 590
591 if (!is_shadow_present_pte(sp->spt[i])) 591 if (!is_shadow_present_pte(sp->spt[i]))
592 continue; 592 continue;
@@ -597,8 +597,9 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
597 sizeof(pt_element_t))) 597 sizeof(pt_element_t)))
598 return -EINVAL; 598 return -EINVAL;
599 599
600 if (gpte_to_gfn(gpte) != gfn || !is_present_gpte(gpte) || 600 gfn = gpte_to_gfn(gpte);
601 !(gpte & PT_ACCESSED_MASK)) { 601 if (unalias_gfn(vcpu->kvm, gfn) != sp->gfns[i] ||
602 !is_present_gpte(gpte) || !(gpte & PT_ACCESSED_MASK)) {
602 u64 nonpresent; 603 u64 nonpresent;
603 604
604 rmap_remove(vcpu->kvm, &sp->spt[i]); 605 rmap_remove(vcpu->kvm, &sp->spt[i]);