svn commit: r290176 - head/sys/contrib/vchiq/interface/vchiq_arm

Oleksandr Tymoshenko gonzo at FreeBSD.org
Fri Oct 30 01:19:06 UTC 2015


Author: gonzo
Date: Fri Oct 30 01:19:04 2015
New Revision: 290176
URL: https://svnweb.freebsd.org/changeset/base/290176

Log:
  Fix BULK read transfer if destination buffer is not cache line-aligned.
  
  We can't use copyout because destination memory is userland address
  in another process but we have reference to respective page so map
  the page into kernel address space and copy fragments there

Modified:
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c

Modified: head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c
==============================================================================
--- head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c	Fri Oct 30 01:18:07 2015	(r290175)
+++ head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c	Fri Oct 30 01:19:04 2015	(r290176)
@@ -109,6 +109,22 @@ vchiq_dmamap_cb(void *arg, bus_dma_segme
 	*addr = PHYS_TO_VCBUS(segs[0].ds_addr);
 }
 
+static int
+copyout_page(vm_page_t p, size_t offset, void *kaddr, size_t size)
+{
+        uint8_t *dst;
+
+        dst = pmap_mapdev(VM_PAGE_TO_PHYS(p), PAGE_SIZE);
+        if (!dst)
+                return ENOMEM;
+
+        memcpy(dst + offset, kaddr, size);
+
+        pmap_unmapdev((vm_offset_t)dst, PAGE_SIZE);
+
+        return 0;
+}
+
 int __init
 vchiq_platform_init(VCHIQ_STATE_T *state)
 {
@@ -560,15 +576,19 @@ free_pagelist(BULKINFO_T *bi, int actual
 			if (head_bytes > actual)
 				head_bytes = actual;
 
-			memcpy((char *)bi->buf,
+			copyout_page(pages[0],
+				pagelist->offset,
 				fragments->headbuf,
 				head_bytes);
 		}
 
 		if ((actual >= 0) && (head_bytes < actual) &&
 			(tail_bytes != 0)) {
-			memcpy((char *)bi->buf + actual - tail_bytes, 
-					 fragments->tailbuf, tail_bytes);
+
+			copyout_page(pages[num_pages-1],
+				(((vm_offset_t)bi->buf + actual) % PAGE_SIZE) - tail_bytes,
+				fragments->tailbuf,
+				tail_bytes);
 		}
 
 		down(&g_free_fragments_mutex);


More information about the svn-src-head mailing list