mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
KVM: MMU: use page track for non-leaf shadow pages
non-leaf shadow pages are always write protected, it can be the user of page track Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
0eb05bf290
commit
56ca57f9fe
1 changed files with 21 additions and 5 deletions
|
@ -806,11 +806,17 @@ static void account_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
|
|||
struct kvm_memory_slot *slot;
|
||||
gfn_t gfn;
|
||||
|
||||
kvm->arch.indirect_shadow_pages++;
|
||||
gfn = sp->gfn;
|
||||
slots = kvm_memslots_for_spte_role(kvm, sp->role);
|
||||
slot = __gfn_to_memslot(slots, gfn);
|
||||
|
||||
/* the non-leaf shadow pages are keeping readonly. */
|
||||
if (sp->role.level > PT_PAGE_TABLE_LEVEL)
|
||||
return kvm_slot_page_track_add_page(kvm, slot, gfn,
|
||||
KVM_PAGE_TRACK_WRITE);
|
||||
|
||||
kvm_mmu_gfn_disallow_lpage(slot, gfn);
|
||||
kvm->arch.indirect_shadow_pages++;
|
||||
}
|
||||
|
||||
static void unaccount_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
|
||||
|
@ -819,11 +825,15 @@ static void unaccount_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
|
|||
struct kvm_memory_slot *slot;
|
||||
gfn_t gfn;
|
||||
|
||||
kvm->arch.indirect_shadow_pages--;
|
||||
gfn = sp->gfn;
|
||||
slots = kvm_memslots_for_spte_role(kvm, sp->role);
|
||||
slot = __gfn_to_memslot(slots, gfn);
|
||||
if (sp->role.level > PT_PAGE_TABLE_LEVEL)
|
||||
return kvm_slot_page_track_remove_page(kvm, slot, gfn,
|
||||
KVM_PAGE_TRACK_WRITE);
|
||||
|
||||
kvm_mmu_gfn_allow_lpage(slot, gfn);
|
||||
kvm->arch.indirect_shadow_pages--;
|
||||
}
|
||||
|
||||
static bool __mmu_gfn_lpage_is_disallowed(gfn_t gfn, int level,
|
||||
|
@ -2132,12 +2142,18 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
|
|||
hlist_add_head(&sp->hash_link,
|
||||
&vcpu->kvm->arch.mmu_page_hash[kvm_page_table_hashfn(gfn)]);
|
||||
if (!direct) {
|
||||
if (rmap_write_protect(vcpu, gfn))
|
||||
/*
|
||||
* we should do write protection before syncing pages
|
||||
* otherwise the content of the synced shadow page may
|
||||
* be inconsistent with guest page table.
|
||||
*/
|
||||
account_shadowed(vcpu->kvm, sp);
|
||||
if (level == PT_PAGE_TABLE_LEVEL &&
|
||||
rmap_write_protect(vcpu, gfn))
|
||||
kvm_flush_remote_tlbs(vcpu->kvm);
|
||||
|
||||
if (level > PT_PAGE_TABLE_LEVEL && need_sync)
|
||||
kvm_sync_pages(vcpu, gfn);
|
||||
|
||||
account_shadowed(vcpu->kvm, sp);
|
||||
}
|
||||
sp->mmu_valid_gen = vcpu->kvm->arch.mmu_valid_gen;
|
||||
clear_page(sp->spt);
|
||||
|
|
Loading…
Reference in a new issue