On Fri, Nov 12, 2010 at 06:35:38PM +0800, Xiao Guangrong wrote:
> Some operation of these functions is very similar, so introduce a
> common function to cleanup them
> 
> Signed-off-by: Xiao Guangrong <[email protected]>
> ---
>  arch/x86/kvm/mmu.c         |    3 -
>  arch/x86/kvm/paging_tmpl.h |  191 ++++++++++++++++++++++++-------------------
>  2 files changed, 107 insertions(+), 87 deletions(-)

This makes the code more complicated and error prone IMO, because there
are specialities of 

> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> index 94d157f..d0bcca2 100644
> --- a/arch/x86/kvm/mmu.c
> +++ b/arch/x86/kvm/mmu.c
> @@ -3108,9 +3108,6 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
>               return;
>          }
>  
> -     if (is_rsvd_bits_set(&vcpu->arch.mmu, *(u64 *)new, PT_PAGE_TABLE_LEVEL))
> -             return;
> -
>       ++vcpu->kvm->stat.mmu_pte_updated;
>       if (!sp->role.cr4_pae)
>               paging32_update_pte(vcpu, sp, spte, new);
> diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
> index 952357a..1a1a0b9 100644
> --- a/arch/x86/kvm/paging_tmpl.h
> +++ b/arch/x86/kvm/paging_tmpl.h
> @@ -299,42 +299,90 @@ static int FNAME(walk_addr_nested)(struct guest_walker 
> *walker,
>                                       addr, access);
>  }
>  
> -static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
> -                           u64 *spte, const void *pte)
> +static bool FNAME(fetch_guest_pte)(struct kvm_vcpu *vcpu,
> +                                struct kvm_mmu_page *sp, u64 *spte,
> +                                bool clear_unsync, pt_element_t gpte,
> +                                pfn_t (get_pfn)(struct kvm_vcpu *, u64 *,
> +                                       pt_element_t, unsigned, bool *))
>  {
> -     pt_element_t gpte;
>       unsigned pte_access;
> +     u64 nonpresent = shadow_trap_nonpresent_pte;
> +     gfn_t gfn;
>       pfn_t pfn;
> -     u64 new_spte;
> +     bool dirty, host_writeable;
>  
> -     gpte = *(const pt_element_t *)pte;
> -     if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) {
> -             if (!is_present_gpte(gpte)) {
> -                     if (sp->unsync)
> -                             new_spte = shadow_trap_nonpresent_pte;
> -                     else
> -                             new_spte = shadow_notrap_nonpresent_pte;
> -                     __set_spte(spte, new_spte);
> -             }
> -             return;
> +     if (!is_present_gpte(gpte) ||
> +           is_rsvd_bits_set(&vcpu->arch.mmu, gpte, PT_PAGE_TABLE_LEVEL)) {
> +             if (!sp->unsync && !clear_unsync)
> +                     nonpresent = shadow_notrap_nonpresent_pte;
> +             goto no_present;
>       }
> -     pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte);
> +
> +     if (!(gpte & PT_ACCESSED_MASK))
> +             goto no_present;
> +
>       pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
> +     gfn = gpte_to_gfn(gpte);
> +     dirty = is_dirty_gpte(gpte);
> +     pfn = get_pfn(vcpu, spte, gpte, pte_access, &host_writeable);
> +
> +     if (is_error_pfn(pfn))
> +             goto no_present;
> +
> +     if (!host_writeable)
> +             pte_access &= ~ACC_WRITE_MASK;
> +
> +     if (spte_to_pfn(*spte) == pfn)
> +             set_spte(vcpu, spte, pte_access, 0, 0,
> +                      dirty, PT_PAGE_TABLE_LEVEL, gfn,
> +                      pfn, true, false, host_writeable);
> +     else
> +             mmu_set_spte(vcpu, spte, sp->role.access, pte_access, 0, 0,
> +                          dirty, NULL, PT_PAGE_TABLE_LEVEL, gfn,
> +                          pfn, true, host_writeable);

For example, the update path should always go through mmu_set_spte to
update last_pte_updated, last_pte_gfn.

Also the callbacks make it harder to read the code. Maybe the
unification works if you use common functions for common parts.

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to