Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Oct 2015 01:19:04 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r290176 - head/sys/contrib/vchiq/interface/vchiq_arm
Message-ID:  <201510300119.t9U1J482012882@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



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