From nobody@FreeBSD.org  Sat Apr 11 02:37:18 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 3B9B61065670
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 11 Apr 2009 02:37:18 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 29ED98FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 11 Apr 2009 02:37:18 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n3B2bHkd015742
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 11 Apr 2009 02:37:17 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id n3B2bHvE015726;
	Sat, 11 Apr 2009 02:37:17 GMT
	(envelope-from nobody)
Message-Id: <200904110237.n3B2bHvE015726@www.freebsd.org>
Date: Sat, 11 Apr 2009 02:37:17 GMT
From: Jason Harmening <jason.harmening@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: busdma incorrectly calculates bounce buffer requirements for userspace buffers
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         133592
>Category:       amd64
>Synopsis:       [busdma] [patch] busdma incorrectly calculates bounce buffer requirements for userspace buffers
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kib
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Apr 11 02:40:00 UTC 2009
>Closed-Date:    Mon Jul 06 11:10:36 UTC 2009
>Last-Modified:  Mon Jul 06 11:10:36 UTC 2009
>Originator:     Jason Harmening
>Release:        7.2-PRERELEASE
>Organization:
>Environment:
FreeBSD CORONA 7.2-PRERELEASE FreeBSD 7.2-PRERELEASE #2: Sat Mar 21 00:30:34 CDT 2009     jason@CORONA:/usr/obj/usr/src/sys/CUSTOM  amd64

>Description:
The _bus_dmamap_load_buffer function in sys/amd64/amd64/busdma_machdep.c
takes a pmap_t param indicating the address space of the buffer
(NULL => KVA space).  When calculating the number of bounce buffers to
reserve, it always calls pmap_kextract() to get the physical address,
when it should call pmap_extract() if pmap != NULL.

The problem exists in both 7-STABLE and 8-CURRENT--the attached patch
is against 7-STABLE.
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

--- busdma_machdep.c.bkp	2009-04-10 21:27:51.000000000 -0500
+++ busdma_machdep.c	2009-04-10 21:30:58.000000000 -0500
@@ -602,7 +602,10 @@
 		vendaddr = (vm_offset_t)buf + buflen;
 
 		while (vaddr < vendaddr) {
-			paddr = pmap_kextract(vaddr);
+			if (pmap)
+				paddr = pmap_extract(pmap, vaddr);
+			else
+				paddr = pmap_kextract(vaddr);
 			if (run_filter(dmat, paddr) != 0)
 				map->pagesneeded++;
 			vaddr += PAGE_SIZE;


>Release-Note:
>Audit-Trail:

From: Scott Long <scottl@samsco.org>
To: bug-followup@FreeBSD.org, jason.harmening@gmail.com
Cc:  
Subject: Re: amd64/133592: [busdma] [patch] busdma incorrectly calculates
 bounce buffer requirements for userspace buffers
Date: Sun, 12 Apr 2009 08:53:47 -0600

 You're right, it's definitely a problem.  The patch looks correct, feel
 free to commit to i386, amd64, and ia64.  Arm needs a similar fix, but
 the code looks to be somewhat different.
 
 Scott

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: amd64/133592: commit references a PR
Date: Mon, 13 Apr 2009 19:39:17 +0000 (UTC)

 Author: kib
 Date: Mon Apr 13 19:20:32 2009
 New Revision: 191011
 URL: http://svn.freebsd.org/changeset/base/191011
 
 Log:
   The bus_dmamap_load_uio(9) shall use pmap of the thread recorded in the
   uio_td to extract pages from, instead of unconditionally use kernel
   pmap.
   
   Submitted by:	Jason Harmening <jason.harmening gmail com> (amd64 version)
   PR:	amd64/133592
   Reviewed by:	scottl (original patch), jhb
   MFC after:	2 weeks
 
 Modified:
   head/sys/amd64/amd64/busdma_machdep.c
   head/sys/arm/arm/busdma_machdep.c
   head/sys/i386/i386/busdma_machdep.c
   head/sys/ia64/ia64/busdma_machdep.c
 
 Modified: head/sys/amd64/amd64/busdma_machdep.c
 ==============================================================================
 --- head/sys/amd64/amd64/busdma_machdep.c	Mon Apr 13 19:12:28 2009	(r191010)
 +++ head/sys/amd64/amd64/busdma_machdep.c	Mon Apr 13 19:20:32 2009	(r191011)
 @@ -606,7 +606,10 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
  		vendaddr = (vm_offset_t)buf + buflen;
  
  		while (vaddr < vendaddr) {
 -			paddr = pmap_kextract(vaddr);
 +			if (pmap)
 +				paddr = pmap_extract(pmap, vaddr);
 +			else
 +				paddr = pmap_kextract(vaddr);
  			if (run_filter(dmat, paddr) != 0)
  				map->pagesneeded++;
  			vaddr += (PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK));
 
 Modified: head/sys/arm/arm/busdma_machdep.c
 ==============================================================================
 --- head/sys/arm/arm/busdma_machdep.c	Mon Apr 13 19:12:28 2009	(r191010)
 +++ head/sys/arm/arm/busdma_machdep.c	Mon Apr 13 19:20:32 2009	(r191011)
 @@ -669,8 +669,8 @@ bus_dmamem_free(bus_dma_tag_t dmat, void
  }
  
  static int
 -_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
 -			bus_size_t buflen, int flags)
 +_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap,
 +    void *buf, bus_size_t buflen, int flags)
  {
  	vm_offset_t vaddr;
  	vm_offset_t vendaddr;
 @@ -689,7 +689,10 @@ _bus_dmamap_count_pages(bus_dma_tag_t dm
  		vendaddr = (vm_offset_t)buf + buflen;
  
  		while (vaddr < vendaddr) {
 -			paddr = pmap_kextract(vaddr);
 +			if (pmap != NULL)
 +				paddr = pmap_extract(pmap, vaddr);
 +			else
 +				paddr = pmap_kextract(vaddr);
  			if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
  			    run_filter(dmat, paddr) != 0)
  				map->pagesneeded++;
 @@ -745,7 +748,8 @@ bus_dmamap_load_buffer(bus_dma_tag_t dma
  	bmask = ~(dmat->boundary - 1);
  
  	if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
 -		error = _bus_dmamap_count_pages(dmat, map, buf, buflen, flags);
 +		error = _bus_dmamap_count_pages(dmat, map, pmap, buf, buflen,
 +		    flags);
  		if (error)
  			return (error);
  	}
 
 Modified: head/sys/i386/i386/busdma_machdep.c
 ==============================================================================
 --- head/sys/i386/i386/busdma_machdep.c	Mon Apr 13 19:12:28 2009	(r191010)
 +++ head/sys/i386/i386/busdma_machdep.c	Mon Apr 13 19:20:32 2009	(r191011)
 @@ -142,8 +142,8 @@ static bus_addr_t add_bounce_page(bus_dm
  				   vm_offset_t vaddr, bus_size_t size);
  static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
  int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr);
 -int _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
 -			    bus_size_t buflen, int flags);
 +int _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap,
 +    void *buf, bus_size_t buflen, int flags);
  
  #ifdef XEN
  #undef pmap_kextract
 @@ -577,8 +577,8 @@ bus_dmamem_free(bus_dma_tag_t dmat, void
  }
  
  int
 -_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
 -			bus_size_t buflen, int flags)
 +_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap,
 +    void *buf, bus_size_t buflen, int flags)
  {
  	vm_offset_t vaddr;
  	vm_offset_t vendaddr;
 @@ -598,7 +598,10 @@ _bus_dmamap_count_pages(bus_dma_tag_t dm
  		vendaddr = (vm_offset_t)buf + buflen;
  
  		while (vaddr < vendaddr) {
 -			paddr = pmap_kextract(vaddr);
 +			if (pmap)
 +				paddr = pmap_extract(pmap, vaddr);
 +			else
 +				paddr = pmap_kextract(vaddr);
  			if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
  			    run_filter(dmat, paddr) != 0) {
  				map->pagesneeded++;
 @@ -660,7 +663,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
  		map = &nobounce_dmamap;
  
  	if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
 -		error = _bus_dmamap_count_pages(dmat, map, buf, buflen, flags);
 +		error = _bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, flags);
  		if (error)
  			return (error);
  	}
 
 Modified: head/sys/ia64/ia64/busdma_machdep.c
 ==============================================================================
 --- head/sys/ia64/ia64/busdma_machdep.c	Mon Apr 13 19:12:28 2009	(r191010)
 +++ head/sys/ia64/ia64/busdma_machdep.c	Mon Apr 13 19:20:32 2009	(r191011)
 @@ -527,7 +527,10 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
  		vendaddr = (vm_offset_t)buf + buflen;
  
  		while (vaddr < vendaddr) {
 -			paddr = pmap_kextract(vaddr);
 +			if (pmap != NULL)
 +				paddr = pmap_extract(pmap, vaddr);
 +			else
 +				paddr = pmap_kextract(vaddr);
  			if (run_filter(dmat, paddr, 0) != 0)
  				map->pagesneeded++;
  			vaddr += PAGE_SIZE;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: gavin 
State-Changed-When: Fri Apr 17 15:42:59 UTC 2009 
State-Changed-Why:  
Patch has been committed to HEAD, SVN r191011. 


Responsible-Changed-From-To: freebsd-amd64->kib 
Responsible-Changed-By: gavin 
Responsible-Changed-When: Fri Apr 17 15:42:59 UTC 2009 
Responsible-Changed-Why:  
Over to committer as MFC reminder 

http://www.freebsd.org/cgi/query-pr.cgi?pr=133592 
State-Changed-From-To: patched->closed 
State-Changed-By: kib 
State-Changed-When: Mon Jul 6 11:09:14 UTC 2009 
State-Changed-Why:  
Merged to 7 in r191809. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=133592 
>Unformatted:
