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-all
mailing list