On Mon, Sep 06, 2010 at 05:56:01PM +0200, Joerg Roedel wrote:
> This patch factors out the direct-mapping paths of the
> mmu_alloc_roots function into a seperate function. This
> makes it a lot easier to avoid all the unnecessary checks
> done in the shadow path which may break when running direct.
> In fact, this patch already fixes a problem when running PAE
> guests on a PAE shadow page table.
> 
> Signed-off-by: Joerg Roedel <[email protected]>
> ---
>  arch/x86/kvm/mmu.c |   82 
> ++++++++++++++++++++++++++++++++++++++--------------
>  1 files changed, 60 insertions(+), 22 deletions(-)
> 
> diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> index 3663d1c..e7e5527 100644
> --- a/arch/x86/kvm/mmu.c
> +++ b/arch/x86/kvm/mmu.c

> +
> +static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
>  {
>       int i;
>       gfn_t root_gfn;
>       struct kvm_mmu_page *sp;
> -     int direct = 0;
>       u64 pdptr;
>  
>       root_gfn = vcpu->arch.mmu.get_cr3(vcpu) >> PAGE_SHIFT;
>  
> -     if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
> +     if (mmu_check_root(vcpu, root_gfn))
> +             return 1;
> +
> +     /*
> +      * Do we shadow a long mode page table? If so we need to
> +      * write-protect the guests page table root.
> +      */
> +     if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) {
>               hpa_t root = vcpu->arch.mmu.root_hpa;
>  
>               ASSERT(!VALID_PAGE(root));
> -             if (mmu_check_root(vcpu, root_gfn))
> -                     return 1;
> -             if (vcpu->arch.mmu.direct_map) {
> -                     direct = 1;
> -                     root_gfn = 0;
> -             }
> +
>               spin_lock(&vcpu->kvm->mmu_lock);
>               kvm_mmu_free_some_pages(vcpu);
> -             sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
> -                                   PT64_ROOT_LEVEL, direct,
> -                                   ACC_ALL, NULL);
> +             sp = kvm_mmu_get_page(vcpu, root_gfn, 0, PT64_ROOT_LEVEL,
> +                                   0, ACC_ALL, NULL);
>               root = __pa(sp->spt);
>               ++sp->root_count;
>               spin_unlock(&vcpu->kvm->mmu_lock);
>               vcpu->arch.mmu.root_hpa = root;
>               return 0;
>       }
> -     direct = !is_paging(vcpu);
> -
> -     if (mmu_check_root(vcpu, root_gfn))
> -             return 1;
>  
> +     /*
> +      * We shadow a 32 bit page table. This may be a legacy 2-level
> +      * or a PAE 3-level page table.
> +      */
>       for (i = 0; i < 4; ++i) {
>               hpa_t root = vcpu->arch.mmu.pae_root[i];
>  
> @@ -2406,16 +2441,11 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
>                       root_gfn = pdptr >> PAGE_SHIFT;
>                       if (mmu_check_root(vcpu, root_gfn))
>                               return 1;
> -             } else if (vcpu->arch.mmu.root_level == 0)
> -                     root_gfn = 0;
> -             if (vcpu->arch.mmu.direct_map) {
> -                     direct = 1;
> -                     root_gfn = i << 30;
>               }
>               spin_lock(&vcpu->kvm->mmu_lock);
>               kvm_mmu_free_some_pages(vcpu);
>               sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
> -                                   PT32_ROOT_LEVEL, direct,
> +                                   PT32_ROOT_LEVEL, 0,
>                                     ACC_ALL, NULL);

Should not write protect the gfn for nonpaging mode.

--
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