From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marcelo Tosatti Subject: [patch 10/13] KVM: MMU: sync roots on mmu reload Date: Sat, 06 Sep 2008 15:48:32 -0300 Message-ID: <20080906192431.294978056@localhost.localdomain> References: <20080906184822.560099087@localhost.localdomain> Cc: kvm@vger.kernel.org To: Avi Kivity Return-path: Received: from mx1.redhat.com ([66.187.233.31]:57356 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752546AbYIFT1j (ORCPT ); Sat, 6 Sep 2008 15:27:39 -0400 Content-Disposition: inline; filename=kvm-oos-hook-cr3 Sender: kvm-owner@vger.kernel.org List-ID: Bring the pages for the root being switched to back in sync. Index: kvm/arch/x86/kvm/mmu.c =================================================================== --- kvm.orig/arch/x86/kvm/mmu.c +++ kvm/arch/x86/kvm/mmu.c @@ -1065,6 +1065,20 @@ static int kvm_unsync_page(struct kvm_vc return mmu_unsync_page(vcpu, sp); } +static int mmu_sync_root(struct kvm_vcpu *vcpu, struct kvm_mmu_page *root_sp) +{ + struct kvm_mmu_page *sp, *n; + int ret = 0; + + list_for_each_entry_safe(sp, n, &root_sp->unsync_pages, oos_link) { + ret = 1; + kvm_sync_page(vcpu, sp); + } + + OOS_ASSERT(list_empty(&root_sp->unsync_pages)); + return ret; +} + static int set_shared_mmu_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) { struct kvm_mmu_page *root_sp; @@ -1075,6 +1089,8 @@ static int set_shared_mmu_page(struct kv kvm_sync_page(vcpu, sp); } else if (sp->root_gfn != -1) { root_sp = kvm_mmu_lookup_page_root(vcpu, sp->root_gfn); + if (root_sp) + ret = mmu_sync_root(vcpu, root_sp); } sp->root_gfn = -1; @@ -1716,6 +1732,37 @@ static void mmu_alloc_roots(struct kvm_v vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root); } +static void mmu_sync_roots(struct kvm_vcpu *vcpu) +{ + int i; + struct kvm_mmu_page *sp; + + if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) + return; + if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) { + hpa_t root = vcpu->arch.mmu.root_hpa; + sp = page_header(root); + mmu_sync_root(vcpu, sp); + return; + } + for (i = 0; i < 4; ++i) { + hpa_t root = vcpu->arch.mmu.pae_root[i]; + + if (root) { + root &= PT64_BASE_ADDR_MASK; + sp = page_header(root); + mmu_sync_root(vcpu, sp); + } + } +} + +void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu) +{ + spin_lock(&vcpu->kvm->mmu_lock); + mmu_sync_roots(vcpu); + spin_unlock(&vcpu->kvm->mmu_lock); +} + static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr) { return vaddr; @@ -1960,6 +2007,7 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu) spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_free_some_pages(vcpu); mmu_alloc_roots(vcpu); + mmu_sync_roots(vcpu); spin_unlock(&vcpu->kvm->mmu_lock); kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa); kvm_mmu_flush_tlb(vcpu); Index: kvm/arch/x86/kvm/x86.c =================================================================== --- kvm.orig/arch/x86/kvm/x86.c +++ kvm/arch/x86/kvm/x86.c @@ -582,6 +582,7 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4); void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { if (cr3 == vcpu->arch.cr3 && !pdptrs_changed(vcpu)) { + kvm_mmu_sync_roots(vcpu); kvm_mmu_flush_tlb(vcpu); return; } Index: kvm/include/asm-x86/kvm_host.h =================================================================== --- kvm.orig/include/asm-x86/kvm_host.h +++ kvm/include/asm-x86/kvm_host.h @@ -610,6 +610,7 @@ int kvm_mmu_unprotect_page_virt(struct k void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu); int kvm_mmu_load(struct kvm_vcpu *vcpu); void kvm_mmu_unload(struct kvm_vcpu *vcpu); +void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu); int kvm_emulate_hypercall(struct kvm_vcpu *vcpu); --