summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Pledge <Roy.Pledge@freescale.com>2014-04-22 14:36:23 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-04-25 23:03:46 (GMT)
commit2ed28dd78c4bce7924b941ae6f2ef28776f83780 (patch)
treebe47d0febf99dbcb9d2c23a93a432ef0f7d53006
parent379ef7526e54ae59e7a927cf2bb92de4826d024c (diff)
downloadlinux-fsl-qoriq-2ed28dd78c4bce7924b941ae6f2ef28776f83780.tar.xz
Fix issue where shared mapping was only partialy mapped
USDPAA DMA memory mappings can consist of multiple segments to avoid power of 4 restrictions imposed by TLB1 hardware. The total size of the mapping must be tracked so that a shared mapping will cover all pages when it is mapped by another process Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com> Change-Id: I9f55f3f876e0ca8fc8aa7eb81ec461414eebea27 Reviewed-on: http://git.am.freescale.net:8181/11408 Reviewed-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com> Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Geoff Thorpe <Geoff.Thorpe@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
-rw-r--r--drivers/staging/fsl_qbman/fsl_usdpaa.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c
index 8ed79af..5033f2a 100644
--- a/drivers/staging/fsl_qbman/fsl_usdpaa.c
+++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
@@ -55,6 +55,7 @@ struct mem_fragment {
/* if mapped, flags+name captured at creation time */
u32 flags;
char name[USDPAA_DMA_NAME_MAX];
+ u64 map_len;
/* support multi-process locks per-memory-fragment. */
int has_locking;
wait_queue_head_t wq;
@@ -877,15 +878,16 @@ static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
tmp->refs++;
kfree(map);
i->did_create = 0;
- i->len = frag->len;
+ i->len = tmp->total_size;
i->phys_addr = frag->base;
i->ptr = tmp->virt_addr;
spin_unlock(&mem_lock);
return 0;
}
+ /* Matching entry - just need to map */
i->has_locking = frag->has_locking;
i->did_create = 0;
- i->len = frag->len;
+ i->len = frag->map_len;
start_frag = frag;
goto do_map;
}
@@ -976,13 +978,14 @@ do_map:
next_frag = list_entry(next_frag->list.prev,
struct mem_fragment, list);
}
-
- start_frag->flags = i->flags;
- strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
- start_frag->has_locking = i->has_locking;
- init_waitqueue_head(&start_frag->wq);
- if (i->did_create == 1)
+ if (i->did_create) {
+ start_frag->flags = i->flags;
+ strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
+ start_frag->map_len = i->len;
+ start_frag->has_locking = i->has_locking;
+ init_waitqueue_head(&start_frag->wq);
start_frag->owner = NULL;
+ }
/* Setup the map entry */
map->root_frag = start_frag;
@@ -1006,9 +1009,9 @@ out:
start_frag->pfn_base,
&populate);
up_write(&current->mm->mmap_sem);
- if (longret & ~PAGE_MASK)
+ if (longret & ~PAGE_MASK) {
ret = (int)longret;
- else {
+ } else {
i->ptr = (void *)longret;
map->virt_addr = i->ptr;
}