From owner-svn-src-all@freebsd.org Wed Nov 18 16:07:03 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 432D3A2BCC9; Wed, 18 Nov 2015 16:07:03 +0000 (UTC) (envelope-from mmel@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1B2291A65; Wed, 18 Nov 2015 16:07:03 +0000 (UTC) (envelope-from mmel@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tAIG72TZ073816; Wed, 18 Nov 2015 16:07:02 GMT (envelope-from mmel@FreeBSD.org) Received: (from mmel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tAIG72qu073815; Wed, 18 Nov 2015 16:07:02 GMT (envelope-from mmel@FreeBSD.org) Message-Id: <201511181607.tAIG72qu073815@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mmel set sender to mmel@FreeBSD.org using -f From: Michal Meloun Date: Wed, 18 Nov 2015 16:07:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r291018 - head/sys/arm/arm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Nov 2015 16:07:03 -0000 Author: mmel Date: Wed Nov 18 16:07:01 2015 New Revision: 291018 URL: https://svnweb.freebsd.org/changeset/base/291018 Log: ARM: Fix dma_dcache_sync() for early allocated memory. Drivers can request DMA to buffers that are not in memory represented in the vm page arrays. Because of this, store KVA of already mapped buffer to synclist and use it in dma_dcache_sync(). Reviewed by: jah Approved by: kib (mentor) Differential Revision: https://reviews.freebsd.org/D4120 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 Wed Nov 18 15:12:24 2015 (r291017) +++ head/sys/arm/arm/busdma_machdep-v6.c Wed Nov 18 16:07:01 2015 (r291018) @@ -117,8 +117,8 @@ struct bounce_page { struct sync_list { vm_offset_t vaddr; /* kva of client data */ + bus_addr_t paddr; /* physical address */ vm_page_t pages; /* starting page of client data */ - vm_offset_t dataoffs; /* page offset of client data */ bus_size_t datacount; /* client data count */ }; @@ -1076,17 +1076,19 @@ _bus_dmamap_load_phys(bus_dma_tag_t dmat sgsize); } else { if (map->sync_count > 0) - sl_end = VM_PAGE_TO_PHYS(sl->pages) + - sl->dataoffs + sl->datacount; + sl_end = sl->paddr + sl->datacount; if (map->sync_count == 0 || curaddr != sl_end) { if (++map->sync_count > dmat->nsegments) break; sl++; sl->vaddr = 0; + sl->paddr = curaddr; sl->datacount = sgsize; sl->pages = PHYS_TO_VM_PAGE(curaddr); - sl->dataoffs = curaddr & PAGE_MASK; + KASSERT(sl->pages != NULL, + ("%s: page at PA:0x%08lx is not in " + "vm_page_array", __func__, curaddr)); } else sl->datacount += sgsize; } @@ -1188,8 +1190,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm sgsize); } else { if (map->sync_count > 0) { - sl_pend = VM_PAGE_TO_PHYS(sl->pages) + - sl->dataoffs + sl->datacount; + sl_pend = sl->paddr + sl->datacount; sl_vend = sl->vaddr + sl->datacount; } @@ -1201,9 +1202,17 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm goto cleanup; sl++; sl->vaddr = kvaddr; + sl->paddr = curaddr; + if (kvaddr != 0) { + sl->pages = NULL; + } else { + sl->pages = PHYS_TO_VM_PAGE(curaddr); + KASSERT(sl->pages != NULL, + ("%s: page at PA:0x%08lx is not " + "in vm_page_array", __func__, + curaddr)); + } sl->datacount = sgsize; - sl->pages = PHYS_TO_VM_PAGE(curaddr); - sl->dataoffs = curaddr & PAGE_MASK; } else sl->datacount += sgsize; } @@ -1299,10 +1308,10 @@ dma_dcache_sync(struct sync_list *sl, bu vm_offset_t va, tempva; bus_size_t size; - offset = sl->dataoffs; + offset = sl->paddr & PAGE_MASK; m = sl->pages; size = sl->datacount; - pa = VM_PAGE_TO_PHYS(m) | offset; + pa = sl->paddr; for ( ; size != 0; size -= len, pa += len, offset = 0, ++m) { tempva = 0; @@ -1310,13 +1319,13 @@ dma_dcache_sync(struct sync_list *sl, bu len = min(PAGE_SIZE - offset, size); tempva = pmap_quick_enter_page(m); va = tempva | offset; + KASSERT(pa == (VM_PAGE_TO_PHYS(m) | offset), + ("unexpected vm_page_t phys: 0x%08x != 0x%08x", + VM_PAGE_TO_PHYS(m) | offset, pa)); } else { len = sl->datacount; va = sl->vaddr; } - KASSERT(pa == (VM_PAGE_TO_PHYS(m) | offset), - ("unexpected vm_page_t phys: 0x%08x != 0x%08x", - VM_PAGE_TO_PHYS(m) | offset, pa)); switch (op) { case BUS_DMASYNC_PREWRITE: