aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/paging_tmpl.h
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-06-06 07:31:27 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 23:40:17 -0400
commitbe38d276b0189fa86231fc311428622a1981ad62 (patch)
tree4706819e23ade99c43bb676830071da9bd2d0abd /arch/x86/kvm/paging_tmpl.h
parentdd180b3e90253cb4ca95d603a8c17413f8daec69 (diff)
KVM: MMU: Introduce drop_spte()
When we call rmap_remove(), we (almost) always immediately follow it by an __set_spte() to a nonpresent pte. Since we need to perform the two operations atomically, to avoid losing the dirty and accessed bits, introduce a helper drop_spte() and convert all call sites. The operation is still nonatomic at this point. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/paging_tmpl.h')
-rw-r--r--arch/x86/kvm/paging_tmpl.h13
1 files changed, 6 insertions, 7 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 59e750c1a269..796a325c7e59 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -353,8 +353,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
353 } 353 }
354 354
355 if (is_large_pte(*sptep)) { 355 if (is_large_pte(*sptep)) {
356 rmap_remove(vcpu->kvm, sptep); 356 drop_spte(vcpu->kvm, sptep, shadow_trap_nonpresent_pte);
357 __set_spte(sptep, shadow_trap_nonpresent_pte);
358 kvm_flush_remote_tlbs(vcpu->kvm); 357 kvm_flush_remote_tlbs(vcpu->kvm);
359 } 358 }
360 359
@@ -516,12 +515,13 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
516 pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t); 515 pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t);
517 516
518 if (is_shadow_present_pte(*sptep)) { 517 if (is_shadow_present_pte(*sptep)) {
519 rmap_remove(vcpu->kvm, sptep);
520 if (is_large_pte(*sptep)) 518 if (is_large_pte(*sptep))
521 --vcpu->kvm->stat.lpages; 519 --vcpu->kvm->stat.lpages;
520 drop_spte(vcpu->kvm, sptep,
521 shadow_trap_nonpresent_pte);
522 need_flush = 1; 522 need_flush = 1;
523 } 523 } else
524 __set_spte(sptep, shadow_trap_nonpresent_pte); 524 __set_spte(sptep, shadow_trap_nonpresent_pte);
525 break; 525 break;
526 } 526 }
527 527
@@ -637,12 +637,11 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
637 !is_present_gpte(gpte) || !(gpte & PT_ACCESSED_MASK)) { 637 !is_present_gpte(gpte) || !(gpte & PT_ACCESSED_MASK)) {
638 u64 nonpresent; 638 u64 nonpresent;
639 639
640 rmap_remove(vcpu->kvm, &sp->spt[i]);
641 if (is_present_gpte(gpte) || !clear_unsync) 640 if (is_present_gpte(gpte) || !clear_unsync)
642 nonpresent = shadow_trap_nonpresent_pte; 641 nonpresent = shadow_trap_nonpresent_pte;
643 else 642 else
644 nonpresent = shadow_notrap_nonpresent_pte; 643 nonpresent = shadow_notrap_nonpresent_pte;
645 __set_spte(&sp->spt[i], nonpresent); 644 drop_spte(vcpu->kvm, &sp->spt[i], nonpresent);
646 continue; 645 continue;
647 } 646 }
648 647