From owner-svn-src-head@FreeBSD.ORG Sun Apr 22 00:58:05 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 71F2D106566C; Sun, 22 Apr 2012 00:58:05 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 534A08FC17; Sun, 22 Apr 2012 00:58:05 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q3M0w5K8012264; Sun, 22 Apr 2012 00:58:05 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q3M0w5nd012262; Sun, 22 Apr 2012 00:58:05 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201204220058.q3M0w5nd012262@svn.freebsd.org> From: Marius Strobl Date: Sun, 22 Apr 2012 00:58:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r234561 - head/sys/arm/arm X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Apr 2012 00:58:05 -0000 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); + } } }