svn commit: r304685 - head/sys/arm64/arm64

Alan Cox alc at rice.edu
Tue Aug 23 16:17:34 UTC 2016


On 08/23/2016 10:48, Andrew Turner wrote:
> Author: andrew
> Date: Tue Aug 23 15:48:27 2016
> New Revision: 304685
> URL: https://svnweb.freebsd.org/changeset/base/304685
>
> Log:
>   Include the offset the virtual address is within an L1 or L2 block when
>   finding the vm_page_t in pmap_extract_and_hold. Previously it would return
>   the vm_page_t of the first page in a block. This would cause issues when,
>   for example, fsck reads from a device into the middle of a superpage. In
>   this case the read call would write to the start of the block, and not to
>   the buffer passed in.
>   
>   Obtained from:	ABT Systems Ltd
>   MFC after:	1 month
>   Sponsored by:	The FreeBSD Foundation
>
> Modified:
>   head/sys/arm64/arm64/pmap.c
>
> Modified: head/sys/arm64/arm64/pmap.c
> ==============================================================================
> --- head/sys/arm64/arm64/pmap.c	Tue Aug 23 15:46:20 2016	(r304684)
> +++ head/sys/arm64/arm64/pmap.c	Tue Aug 23 15:48:27 2016	(r304685)
> @@ -995,6 +995,7 @@ vm_page_t
>  pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
>  {
>  	pt_entry_t *pte, tpte;
> +	vm_offset_t off;
>  	vm_paddr_t pa;
>  	vm_page_t m;
>  	int lvl;
> @@ -1016,9 +1017,20 @@ retry:
>  		     tpte & ATTR_DESCR_MASK));
>  		if (((tpte & ATTR_AP_RW_BIT) == ATTR_AP(ATTR_AP_RW)) ||
>  		    ((prot & VM_PROT_WRITE) == 0)) {
> +			switch(lvl) {
> +			case 1:
> +				off = va & L1_OFFSET;
> +				break;
> +			case 2:
> +				off = va & L2_OFFSET;
> +				break;
> +			case 3:
> +			default:
> +				off = 0;
> +			}

I would strongly suggest that you also include the page offset in the
value passed to vm_page_pa_tryrelock().  Otherwise, if we ever change
the mapping from physical addresses to page locks, this code will be
acquiring the wrong lock.  Other pmap implementations, e.g., amd64, do
include the offset.

>  			if (vm_page_pa_tryrelock(pmap, tpte & ~ATTR_MASK, &pa))
>  				goto retry;
> -			m = PHYS_TO_VM_PAGE(tpte & ~ATTR_MASK);
> +			m = PHYS_TO_VM_PAGE((tpte & ~ATTR_MASK) | off);
>  			vm_page_hold(m);
>  		}
>  	}
>
>




More information about the svn-src-head mailing list