On 04.10.2013, at 16:55, Bharat Bhushan wrote: > lookup_linux_pte() was searching for a pte and also sets access > flags is writable. This function now searches only pte while > access flag setting is done explicitly. > > This pte lookup is not kvm specific, so moved to common code (asm/pgtable.h) > My Followup patch will use this on booke. > > Signed-off-by: Bharat Bhushan <bharat.bhushan@xxxxxxxxxxxxx> Paul, please ack. Alex > --- > v5->v6 > - return NULL rather than _pte(0) as this was > giving compilation error with STRICT_MM_TYPECHECKS > - Also not only check for NULL pointer in caller rather than > calling pte_present() twice > > arch/powerpc/include/asm/pgtable.h | 24 +++++++++++++++++++++++ > arch/powerpc/kvm/book3s_hv_rm_mmu.c | 36 +++++++++++----------------------- > 2 files changed, 36 insertions(+), 24 deletions(-) > > diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h > index 7d6eacf..5e41a31 100644 > --- a/arch/powerpc/include/asm/pgtable.h > +++ b/arch/powerpc/include/asm/pgtable.h > @@ -223,6 +223,30 @@ extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, > #endif > pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, > unsigned *shift); > + > +static inline pte_t *lookup_linux_pte(pgd_t *pgdir, unsigned long hva, > + unsigned long *pte_sizep) > +{ > + pte_t *ptep; > + unsigned long ps = *pte_sizep; > + unsigned int shift; > + > + ptep = find_linux_pte_or_hugepte(pgdir, hva, &shift); > + if (!ptep) > + return NULL; > + if (shift) > + *pte_sizep = 1ul << shift; > + else > + *pte_sizep = PAGE_SIZE; > + > + if (ps > *pte_sizep) > + return NULL; > + > + if (!pte_present(*ptep)) > + return NULL; > + > + return ptep; > +} > #endif /* __ASSEMBLY__ */ > > #endif /* __KERNEL__ */ > diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c > index 45e30d6..8ab54e8 100644 > --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c > +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c > @@ -134,25 +134,6 @@ static void remove_revmap_chain(struct kvm *kvm, long pte_index, > unlock_rmap(rmap); > } > > -static pte_t lookup_linux_pte(pgd_t *pgdir, unsigned long hva, > - int writing, unsigned long *pte_sizep) > -{ > - pte_t *ptep; > - unsigned long ps = *pte_sizep; > - unsigned int hugepage_shift; > - > - ptep = find_linux_pte_or_hugepte(pgdir, hva, &hugepage_shift); > - if (!ptep) > - return __pte(0); > - if (hugepage_shift) > - *pte_sizep = 1ul << hugepage_shift; > - else > - *pte_sizep = PAGE_SIZE; > - if (ps > *pte_sizep) > - return __pte(0); > - return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift); > -} > - > static inline void unlock_hpte(unsigned long *hpte, unsigned long hpte_v) > { > asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); > @@ -173,6 +154,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, > unsigned long is_io; > unsigned long *rmap; > pte_t pte; > + pte_t *ptep; > unsigned int writing; > unsigned long mmu_seq; > unsigned long rcbits; > @@ -231,8 +213,9 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, > > /* Look up the Linux PTE for the backing page */ > pte_size = psize; > - pte = lookup_linux_pte(pgdir, hva, writing, &pte_size); > - if (pte_present(pte)) { > + ptep = lookup_linux_pte(pgdir, hva, &pte_size); > + if (ptep) { > + pte = kvmppc_read_update_linux_pte(ptep, writing); > if (writing && !pte_write(pte)) > /* make the actual HPTE be read-only */ > ptel = hpte_make_readonly(ptel); > @@ -661,15 +644,20 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, > struct kvm_memory_slot *memslot; > pgd_t *pgdir = vcpu->arch.pgdir; > pte_t pte; > + pte_t *ptep; > > psize = hpte_page_size(v, r); > gfn = ((r & HPTE_R_RPN) & ~(psize - 1)) >> PAGE_SHIFT; > memslot = __gfn_to_memslot(kvm_memslots(kvm), gfn); > if (memslot) { > hva = __gfn_to_hva_memslot(memslot, gfn); > - pte = lookup_linux_pte(pgdir, hva, 1, &psize); > - if (pte_present(pte) && !pte_write(pte)) > - r = hpte_make_readonly(r); > + ptep = lookup_linux_pte(pgdir, hva, &psize); > + if (ptep) { > + pte = kvmppc_read_update_linux_pte(ptep, > + 1); > + if (pte_present(pte) && !pte_write(pte)) > + r = hpte_make_readonly(r); > + } > } > } > } > -- > 1.7.0.4 > > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html