drm/msm: Set IOMMU map attributes

Remove the IOMMU_WRITE bit from buffer objects that are
marked MSM_BO_GPU_READONLY.  Add a new flag (MSM_BO_PRIVILEGED)
to pass through IOMMU_PRIV for those IOMMU targets that support
it.

Change-Id: Ic0dedbad8d9d3f461a47ea093fad3fdd90f46535
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
Jordan Crouse 2017-02-13 10:14:26 -07:00
parent 76eb0ae231
commit 425372c0ba
5 changed files with 24 additions and 11 deletions

View file

@ -408,7 +408,8 @@ void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
void *priv);
int msm_gem_map_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt,
void *priv);
void *priv, unsigned int flags);
void msm_gem_address_space_destroy(struct msm_gem_address_space *aspace);
/* For GPU and legacy display */

View file

@ -330,6 +330,10 @@ static struct msm_gem_vma *obj_get_domain(struct drm_gem_object *obj,
return NULL;
}
#ifndef IOMMU_PRIV
#define IOMMU_PRIV 0
#endif
/* should be called under struct_mutex.. although it can be called
* from atomic context without struct_mutex to acquire an extra
* iova ref if you know one is already held.
@ -369,7 +373,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj,
}
ret = msm_gem_map_vma(aspace, domain, msm_obj->sgt,
get_dmabuf_ptr(obj));
get_dmabuf_ptr(obj), msm_obj->flags);
}
if (!ret)

View file

@ -26,7 +26,7 @@
struct msm_gem_aspace_ops {
int (*map)(struct msm_gem_address_space *, struct msm_gem_vma *,
struct sg_table *sgt, void *priv);
struct sg_table *sgt, void *priv, unsigned int flags);
void (*unmap)(struct msm_gem_address_space *, struct msm_gem_vma *,
struct sg_table *sgt, void *priv);

View file

@ -39,7 +39,7 @@ static void smmu_aspace_unmap_vma(struct msm_gem_address_space *aspace,
static int smmu_aspace_map_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt,
void *priv)
void *priv, unsigned int flags)
{
struct dma_buf *buf = priv;
int ret;
@ -107,13 +107,20 @@ static void iommu_aspace_unmap_vma(struct msm_gem_address_space *aspace,
}
static int iommu_aspace_map_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt,
void *priv)
struct msm_gem_vma *vma, struct sg_table *sgt, void *priv,
unsigned int flags)
{
struct msm_iommu_aspace *local = to_iommu_aspace(aspace);
size_t size = 0;
struct scatterlist *sg;
int ret = 0, i;
int ret, i;
int iommu_flags = IOMMU_READ;
if (!(flags & MSM_BO_GPU_READONLY))
iommu_flags |= IOMMU_WRITE;
if (flags & MSM_BO_PRIVILEGED)
iommu_flags |= IOMMU_PRIV;
if (WARN_ON(drm_mm_node_allocated(&vma->node)))
return 0;
@ -129,8 +136,8 @@ static int iommu_aspace_map_vma(struct msm_gem_address_space *aspace,
vma->iova = vma->node.start << PAGE_SHIFT;
if (aspace->mmu)
ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova,
sgt, IOMMU_READ | IOMMU_WRITE);
ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt,
iommu_flags);
return ret;
}
@ -174,10 +181,10 @@ msm_gem_address_space_new(struct msm_mmu *mmu, const char *name,
int msm_gem_map_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt,
void *priv)
void *priv, unsigned int flags)
{
if (aspace && aspace->ops->map)
return aspace->ops->map(aspace, vma, sgt, priv);
return aspace->ops->map(aspace, vma, sgt, priv, flags);
return -EINVAL;
}

View file

@ -77,6 +77,7 @@ struct drm_msm_param {
#define MSM_BO_SCANOUT 0x00000001 /* scanout capable */
#define MSM_BO_GPU_READONLY 0x00000002
#define MSM_BO_PRIVILEGED 0x00000004
#define MSM_BO_CACHE_MASK 0x000f0000
/* cache modes */
#define MSM_BO_CACHED 0x00010000