aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/mmu.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index ef5d140a2705..064ddfbde108 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1337,7 +1337,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
1337 unsigned index; 1337 unsigned index;
1338 unsigned quadrant; 1338 unsigned quadrant;
1339 struct hlist_head *bucket; 1339 struct hlist_head *bucket;
1340 struct kvm_mmu_page *sp; 1340 struct kvm_mmu_page *sp, *unsync_sp = NULL;
1341 struct hlist_node *node, *tmp; 1341 struct hlist_node *node, *tmp;
1342 1342
1343 role = vcpu->arch.mmu.base_role; 1343 role = vcpu->arch.mmu.base_role;
@@ -1356,20 +1356,30 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
1356 hlist_for_each_entry_safe(sp, node, tmp, bucket, hash_link) 1356 hlist_for_each_entry_safe(sp, node, tmp, bucket, hash_link)
1357 if (sp->gfn == gfn) { 1357 if (sp->gfn == gfn) {
1358 if (sp->unsync) 1358 if (sp->unsync)
1359 if (kvm_sync_page(vcpu, sp)) 1359 unsync_sp = sp;
1360 continue;
1361 1360
1362 if (sp->role.word != role.word) 1361 if (sp->role.word != role.word)
1363 continue; 1362 continue;
1364 1363
1364 if (!direct && unsync_sp &&
1365 kvm_sync_page_transient(vcpu, unsync_sp)) {
1366 unsync_sp = NULL;
1367 break;
1368 }
1369
1365 mmu_page_add_parent_pte(vcpu, sp, parent_pte); 1370 mmu_page_add_parent_pte(vcpu, sp, parent_pte);
1366 if (sp->unsync_children) { 1371 if (sp->unsync_children) {
1367 set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); 1372 set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests);
1368 kvm_mmu_mark_parents_unsync(sp); 1373 kvm_mmu_mark_parents_unsync(sp);
1369 } 1374 } else if (sp->unsync)
1375 kvm_mmu_mark_parents_unsync(sp);
1376
1370 trace_kvm_mmu_get_page(sp, false); 1377 trace_kvm_mmu_get_page(sp, false);
1371 return sp; 1378 return sp;
1372 } 1379 }
1380 if (!direct && unsync_sp)
1381 kvm_sync_page(vcpu, unsync_sp);
1382
1373 ++vcpu->kvm->stat.mmu_cache_miss; 1383 ++vcpu->kvm->stat.mmu_cache_miss;
1374 sp = kvm_mmu_alloc_page(vcpu, parent_pte); 1384 sp = kvm_mmu_alloc_page(vcpu, parent_pte);
1375 if (!sp) 1385 if (!sp)