Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Apr 2012 01:00:31 GMT
From:      dfilter@FreeBSD.ORG (dfilter service)
To:        freebsd-arm@FreeBSD.org
Subject:   Re: arm/160431: commit references a PR
Message-ID:  <201204220100.q3M10VoB069517@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR arm/160431; it has been noted by GNATS.

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: arm/160431: commit references a PR
Date: Sun, 22 Apr 2012 00:58:20 +0000 (UTC)

 Author: marius
 Date: Sun Apr 22 00:58:04 2012
 New Revision: 234561
 URL: http://svn.freebsd.org/changeset/base/234561
 
 Log:
   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
   MFC after:	1 week
 
 Modified:
   head/sys/arm/arm/busdma_machdep.c
 
 Modified: head/sys/arm/arm/busdma_machdep.c
 ==============================================================================
 --- head/sys/arm/arm/busdma_machdep.c	Sun Apr 22 00:43:32 2012	(r234560)
 +++ head/sys/arm/arm/busdma_machdep.c	Sun Apr 22 00:58:04 2012	(r234561)
 @@ -1091,14 +1091,16 @@ static void
  bus_dmamap_sync_buf(void *buf, int len, bus_dmasync_op_t op)
  {
  	char _tmp_cl[arm_dcache_align], _tmp_clend[arm_dcache_align];
 +	register_t s;
 +	int partial; 
  
  	if ((op & BUS_DMASYNC_PREWRITE) && !(op & BUS_DMASYNC_PREREAD)) {
  		cpu_dcache_wb_range((vm_offset_t)buf, len);
  		cpu_l2cache_wb_range((vm_offset_t)buf, len);
  	}
 +	partial = (((vm_offset_t)buf) | len) & arm_dcache_align_mask;
  	if (op & BUS_DMASYNC_PREREAD) {
 -		if (!(op & BUS_DMASYNC_PREWRITE) &&
 -		    ((((vm_offset_t)(buf) | len) & arm_dcache_align_mask) == 0)) {
 +		if (!(op & BUS_DMASYNC_PREWRITE) && !partial) {
  			cpu_dcache_inv_range((vm_offset_t)buf, len);
  			cpu_l2cache_inv_range((vm_offset_t)buf, len);
  		} else {
 @@ -1107,27 +1109,32 @@ bus_dmamap_sync_buf(void *buf, int len, 
  		}
  	}
  	if (op & BUS_DMASYNC_POSTREAD) {
 -		if ((vm_offset_t)buf & arm_dcache_align_mask) {
 -			memcpy(_tmp_cl, (void *)((vm_offset_t)buf & ~
 -			    arm_dcache_align_mask),
 -			    (vm_offset_t)buf & arm_dcache_align_mask);
 -		}
 -		if (((vm_offset_t)buf + len) & arm_dcache_align_mask) {
 -			memcpy(_tmp_clend, (void *)((vm_offset_t)buf + len),
 -			    arm_dcache_align - (((vm_offset_t)(buf) + len) &
 -			   arm_dcache_align_mask));
 +		if (partial) {
 +			s = intr_disable();
 +			if ((vm_offset_t)buf & arm_dcache_align_mask)
 +				memcpy(_tmp_cl, (void *)((vm_offset_t)buf &
 +				    ~arm_dcache_align_mask),
 +				    (vm_offset_t)buf & arm_dcache_align_mask);
 +			if (((vm_offset_t)buf + len) & arm_dcache_align_mask)
 +				memcpy(_tmp_clend, 
 +				    (void *)((vm_offset_t)buf + len),
 +				    arm_dcache_align - (((vm_offset_t)(buf) +
 +				    len) & arm_dcache_align_mask));
  		}
  		cpu_dcache_inv_range((vm_offset_t)buf, len);
  		cpu_l2cache_inv_range((vm_offset_t)buf, len);
 -
 -		if ((vm_offset_t)buf & arm_dcache_align_mask)
 -			memcpy((void *)((vm_offset_t)buf &
 -			    ~arm_dcache_align_mask), _tmp_cl, 
 -			    (vm_offset_t)buf & arm_dcache_align_mask);
 -		if (((vm_offset_t)buf + len) & arm_dcache_align_mask)
 -			memcpy((void *)((vm_offset_t)buf + len), _tmp_clend,
 -			    arm_dcache_align - (((vm_offset_t)(buf) + len) &
 -			   arm_dcache_align_mask));
 +		if (partial) {
 +			if ((vm_offset_t)buf & arm_dcache_align_mask)
 +				memcpy((void *)((vm_offset_t)buf &
 +				    ~arm_dcache_align_mask), _tmp_cl, 
 +				    (vm_offset_t)buf & arm_dcache_align_mask);
 +			if (((vm_offset_t)buf + len) & arm_dcache_align_mask)
 +				memcpy((void *)((vm_offset_t)buf + len), 
 +				    _tmp_clend, arm_dcache_align - 
 +				    (((vm_offset_t)(buf) + len) &
 +				    arm_dcache_align_mask));
 +			intr_restore(s);
 +		}
  	}
  }
  
 _______________________________________________
 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"
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204220100.q3M10VoB069517>