Re: [PATCH V2 3/10] KVM/MMU: Add last_level in the struct mmu_spte_page

From: Paolo Bonzini
Date: Thu Feb 14 2019 - 11:32:43 EST


On 02/02/19 02:38, lantianyu1986@xxxxxxxxx wrote:
> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> index ce770b446238..70cafd3f95ab 100644
> --- a/arch/x86/kvm/mmu.c
> +++ b/arch/x86/kvm/mmu.c
> @@ -2918,6 +2918,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
>
> if (level > PT_PAGE_TABLE_LEVEL)
> spte |= PT_PAGE_SIZE_MASK;
> +
> + sp->last_level = is_last_spte(spte, level);

Wait, I wasn't thinking straight. If a struct kvm_mmu_page exists, it
is never the last level. Page table entries for the last level do not
have a struct kvm_mmu_page.

Therefore you don't need the flag after all. I suspect your
calculations in patch 2 are off by one, and you actually need

hlist_for_each_entry(sp, range->flush_list, flush_link) {
int pages = KVM_PAGES_PER_HPAGE(sp->role.level + 1);
...
}

For example, if sp->role.level is 1 then the struct kvm_mmu_page is for
a page containing PTEs and covers an area of 2 MiB.

Thanks,

Paolo

> if (tdp_enabled)
> spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn,
> kvm_is_mmio_pfn(pfn));