aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/paging_tmpl.h8
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 22f13797f521..0671d7a29c3c 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -461,6 +461,7 @@ out_unlock:
461static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) 461static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
462{ 462{
463 struct kvm_shadow_walk_iterator iterator; 463 struct kvm_shadow_walk_iterator iterator;
464 struct kvm_mmu_page *sp;
464 gpa_t pte_gpa = -1; 465 gpa_t pte_gpa = -1;
465 int level; 466 int level;
466 u64 *sptep; 467 u64 *sptep;
@@ -472,10 +473,13 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
472 level = iterator.level; 473 level = iterator.level;
473 sptep = iterator.sptep; 474 sptep = iterator.sptep;
474 475
476 sp = page_header(__pa(sptep));
475 if (is_last_spte(*sptep, level)) { 477 if (is_last_spte(*sptep, level)) {
476 struct kvm_mmu_page *sp = page_header(__pa(sptep));
477 int offset, shift; 478 int offset, shift;
478 479
480 if (!sp->unsync)
481 break;
482
479 shift = PAGE_SHIFT - 483 shift = PAGE_SHIFT -
480 (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level; 484 (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level;
481 offset = sp->role.quadrant << shift; 485 offset = sp->role.quadrant << shift;
@@ -493,7 +497,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
493 break; 497 break;
494 } 498 }
495 499
496 if (!is_shadow_present_pte(*sptep)) 500 if (!is_shadow_present_pte(*sptep) || !sp->unsync_children)
497 break; 501 break;
498 } 502 }
499 503