aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiao Guangrong <guangrong.xiao@linux.intel.com>2016-02-24 04:51:12 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2016-03-03 08:36:22 -0500
commite5691a81e830c12d396b3f219ab999be87a1208f (patch)
treeb916b2799982fa81d5f01dda0f48360263691f61
parent3d0c27ad6ee465f174b09ee99fcaf189c57d567a (diff)
KVM: MMU: clear write-flooding on the fast path of tracked page
If the page fault is caused by write access on write tracked page, the real shadow page walking is skipped, we lost the chance to clear write flooding for the page structure current vcpu is using Fix it by locklessly waking shadow page table to clear write flooding on the shadow page structure out of mmu-lock. So that we change the count to atomic_t Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/kvm/mmu.c22
-rw-r--r--arch/x86/kvm/paging_tmpl.h4
3 files changed, 24 insertions, 4 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 71e43fe04bbc..e2fc5c0ec86a 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -285,7 +285,7 @@ struct kvm_mmu_page {
285#endif 285#endif
286 286
287 /* Number of writes since the last time traversal visited this page. */ 287 /* Number of writes since the last time traversal visited this page. */
288 int write_flooding_count; 288 atomic_t write_flooding_count;
289}; 289};
290 290
291struct kvm_pio_request { 291struct kvm_pio_request {
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index dd8e3ca2d79b..58c067da6efc 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2063,7 +2063,7 @@ static void mmu_sync_children(struct kvm_vcpu *vcpu,
2063 2063
2064static void __clear_sp_write_flooding_count(struct kvm_mmu_page *sp) 2064static void __clear_sp_write_flooding_count(struct kvm_mmu_page *sp)
2065{ 2065{
2066 sp->write_flooding_count = 0; 2066 atomic_set(&sp->write_flooding_count, 0);
2067} 2067}
2068 2068
2069static void clear_sp_write_flooding_count(u64 *spte) 2069static void clear_sp_write_flooding_count(u64 *spte)
@@ -3406,6 +3406,23 @@ static bool page_fault_handle_page_track(struct kvm_vcpu *vcpu,
3406 return false; 3406 return false;
3407} 3407}
3408 3408
3409static void shadow_page_table_clear_flood(struct kvm_vcpu *vcpu, gva_t addr)
3410{
3411 struct kvm_shadow_walk_iterator iterator;
3412 u64 spte;
3413
3414 if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
3415 return;
3416
3417 walk_shadow_page_lockless_begin(vcpu);
3418 for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) {
3419 clear_sp_write_flooding_count(iterator.sptep);
3420 if (!is_shadow_present_pte(spte))
3421 break;
3422 }
3423 walk_shadow_page_lockless_end(vcpu);
3424}
3425
3409static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva, 3426static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
3410 u32 error_code, bool prefault) 3427 u32 error_code, bool prefault)
3411{ 3428{
@@ -4221,7 +4238,8 @@ static bool detect_write_flooding(struct kvm_mmu_page *sp)
4221 if (sp->role.level == PT_PAGE_TABLE_LEVEL) 4238 if (sp->role.level == PT_PAGE_TABLE_LEVEL)
4222 return false; 4239 return false;
4223 4240
4224 return ++sp->write_flooding_count >= 3; 4241 atomic_inc(&sp->write_flooding_count);
4242 return atomic_read(&sp->write_flooding_count) >= 3;
4225} 4243}
4226 4244
4227/* 4245/*
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 52ae2d94cc9e..4174cf290fa3 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -728,8 +728,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
728 return 0; 728 return 0;
729 } 729 }
730 730
731 if (page_fault_handle_page_track(vcpu, error_code, walker.gfn)) 731 if (page_fault_handle_page_track(vcpu, error_code, walker.gfn)) {
732 shadow_page_table_clear_flood(vcpu, addr);
732 return 1; 733 return 1;
734 }
733 735
734 vcpu->arch.write_fault_to_shadow_pgtable = false; 736 vcpu->arch.write_fault_to_shadow_pgtable = false;
735 737