There is a race where VCPU0 is shadowing a pagetable entry while VCPU1 is updating it, which results in a stale shadow copy.
Fix that by comparing the contents of the cached guest pte with the current guest pte after write-protecting the guest pagetable. Attached program kvm_shadow_race.c demonstrates the problem. Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]> diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index 72d4816..4fece01 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h @@ -66,6 +66,7 @@ struct guest_walker { int level; gfn_t table_gfn[PT_MAX_FULL_LEVELS]; pt_element_t pte; + gpa_t pte_gpa; unsigned pt_access; unsigned pte_access; gfn_t gfn; @@ -212,6 +213,7 @@ walk: } walker->pte = pte; + walker->pte_gpa = pte_gpa; walker->pt_access = pt_access; walker->pte_access = pte_access; pgprintk("%s: pte %llx pte_access %x pt_access %x\n", @@ -267,6 +269,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, int level; u64 *shadow_ent; unsigned access = walker->pt_access; + pt_element_t curr_pte; if (!is_present_pte(walker->pte)) return NULL; @@ -316,6 +319,11 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, *shadow_ent = shadow_pte; } + kvm_read_guest(vcpu->kvm, walker->pte_gpa, &curr_pte, sizeof(curr_pte)); + + if (curr_pte != walker->pte) + return 0; + mmu_set_spte(vcpu, shadow_ent, access, walker->pte_access & access, user_fault, write_fault, walker->pte & PT_DIRTY_MASK, ptwrite, walker->gfn); @@ -382,10 +390,11 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, /* * mmio: emulate if accessible, otherwise its a guest fault. */ - if (is_io_pte(*shadow_pte)) + if (shadow_pte && is_io_pte(*shadow_pte)) return 1; - ++vcpu->stat.pf_fixed; + if (shadow_pte) + ++vcpu->stat.pf_fixed; kvm_mmu_audit(vcpu, "post page fault (fixed)"); return write_pt; ------------------------------------------------------------------------- SF.Net email is sponsored by: Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel