arm/160431: commit references a PR

dfilter service dfilter at FreeBSD.ORG
Mon Dec 31 21:10:01 UTC 2012


The following reply was made to PR arm/160431; it has been noted by GNATS.

From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: arm/160431: commit references a PR
Date: Mon, 31 Dec 2012 21:00:46 +0000 (UTC)

 Author: gonzo
 Date: Mon Dec 31 21:00:38 2012
 New Revision: 244912
 URL: http://svnweb.freebsd.org/changeset/base/244912
 
 Log:
   Merge r234561 from busdma_machdep.c to ARMv6 version of busdma:
   
   Interrupts must be disabled while handling a partial cache line flush,
   as otherwise the interrupt handling code may modify data in the non-DMA
   part of the cache line while we have it stashed away in the temporary
   stack buffer, then we end up restoring a stale value.
   
   PR:             160431
   Submitted by:   Ian Lepore
 
 Modified:
   head/sys/arm/arm/busdma_machdep-v6.c
 
 Modified: head/sys/arm/arm/busdma_machdep-v6.c
 ==============================================================================
 --- head/sys/arm/arm/busdma_machdep-v6.c	Mon Dec 31 16:52:52 2012	(r244911)
 +++ head/sys/arm/arm/busdma_machdep-v6.c	Mon Dec 31 21:00:38 2012	(r244912)
 @@ -1347,35 +1347,49 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
  			while (sl != NULL) {
  					/* write back the unaligned portions */
  				vm_paddr_t physaddr;
 +				register_t s = 0;
 +
  				buf = sl->vaddr;
  				len = sl->datacount;
  				physaddr = sl->busaddr;
  				bbuf = buf & ~arm_dcache_align_mask;
  				ebuf = buf + len;
  				physaddr = physaddr & ~arm_dcache_align_mask;
 -				unalign = buf & arm_dcache_align_mask;
 -				if (unalign) {
 -					memcpy(_tmp_cl, (void *)bbuf, unalign);
 -					len += unalign; /* inv entire cache line */
 -				}
 -				unalign = ebuf & arm_dcache_align_mask;
 -				if (unalign) {
 -					unalign = arm_dcache_align - unalign;
 -					memcpy(_tmp_clend, (void *)ebuf, unalign);
 -					len += unalign; /* inv entire cache line */
 +
 +
 +				if ((buf & arm_dcache_align_mask) ||
 +				    (ebuf & arm_dcache_align_mask)) {
 +					s = intr_disable();
 +					unalign = buf & arm_dcache_align_mask;
 +					if (unalign) {
 +						memcpy(_tmp_cl, (void *)bbuf, unalign);
 +						len += unalign; /* inv entire cache line */
 +					}
 +
 +					unalign = ebuf & arm_dcache_align_mask;
 +					if (unalign) {
 +						unalign = arm_dcache_align - unalign;
 +						memcpy(_tmp_clend, (void *)ebuf, unalign);
 +						len += unalign; /* inv entire cache line */
 +					}
  				}
 -					/* inv are cache length aligned */
 +
 +				/* inv are cache length aligned */
  				cpu_dcache_inv_range(bbuf, len);
  				l2cache_inv_range(bbuf, physaddr, len);
  
 -				unalign = (vm_offset_t)buf & arm_dcache_align_mask;
 -				if (unalign) {
 -					memcpy((void *)bbuf, _tmp_cl, unalign);
 -				}
 -				unalign = ebuf & arm_dcache_align_mask;
 -				if (unalign) {
 -					unalign = arm_dcache_align - unalign;
 -					memcpy((void *)ebuf, _tmp_clend, unalign);
 +				if ((buf & arm_dcache_align_mask) ||
 +				    (ebuf & arm_dcache_align_mask)) {
 +					unalign = (vm_offset_t)buf & arm_dcache_align_mask;
 +					if (unalign)
 +						memcpy((void *)bbuf, _tmp_cl, unalign);
 +
 +					unalign = ebuf & arm_dcache_align_mask;
 +					if (unalign)
 +						memcpy((void *)ebuf, _tmp_clend,
 +						    arm_dcache_align - unalign);
 +
 +					intr_restore(s);
  				}
  				sl = STAILQ_NEXT(sl, slinks);
  			}
 _______________________________________________
 svn-src-all at freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
 


More information about the freebsd-arm mailing list