Re: [PATCH 1/3 v6] kvm: powerpc: keep only pte search logic in lookup_linux_pte

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux