summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-05-11 11:48:35 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-05-11 11:48:34 -0700
commita55a52a8a225c5601a0075fd640a6499e393eae8 (patch)
treec5c84967760edbae6259b955cd52ec4ddc6e56d9
parentc4a48b7ed2e4287ffd953a152564e2554bc3a26b (diff)
parentc0cdf127058b1d5264466f494b1fa14e42c76a30 (diff)
Merge "drm/msm: Allocate secure buffer objects"
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c27
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c15
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c19
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h2
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c53
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h2
-rw-r--r--drivers/gpu/drm/msm/msm_gem_prime.c12
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c57
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c75
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h3
-rw-r--r--drivers/staging/android/ion/ion.c22
-rw-r--r--drivers/staging/android/ion/ion.h17
-rw-r--r--include/uapi/drm/msm_drm.h2
13 files changed, 251 insertions, 55 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index de2ee1ffb735..dbd4fb8b2212 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -15,6 +15,9 @@
#include "msm_iommu.h"
#include "a5xx_gpu.h"
+#define SECURE_VA_START 0xc0000000
+#define SECURE_VA_SIZE SZ_256M
+
static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -133,6 +136,12 @@ static int a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
OUT_RING(ring, 0x02);
+ /* Turn on secure mode if the submission is secure */
+ if (submit->secure) {
+ OUT_PKT7(ring, CP_SET_SECURE_MODE, 1);
+ OUT_RING(ring, 1);
+ }
+
/* Record the always on counter before command execution */
if (submit->profile_buf_iova) {
uint64_t gpuaddr = submit->profile_buf_iova +
@@ -212,6 +221,11 @@ static int a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
OUT_RING(ring, upper_32_bits(rbmemptr(adreno_gpu, ring->id, fence)));
OUT_RING(ring, submit->fence);
+ if (submit->secure) {
+ OUT_PKT7(ring, CP_SET_SECURE_MODE, 1);
+ OUT_RING(ring, 0);
+ }
+
/* Yield the floor on command completion */
OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4);
/*
@@ -762,14 +776,10 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
ADRENO_PROTECT_RW(0x10000, 0x8000));
gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_CNTL, 0);
- /*
- * Disable the trusted memory range - we don't actually supported secure
- * memory rendering at this point in time and we don't want to block off
- * part of the virtual memory space.
- */
+
gpu_write64(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO,
- REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x00000000);
- gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000);
+ REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, SECURE_VA_START);
+ gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, SECURE_VA_SIZE);
/* Put the GPU into 64 bit by default */
gpu_write(gpu, REG_A5XX_CP_ADDR_MODE_CNTL, 0x1);
@@ -1405,6 +1415,9 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
a5xx_config.va_start = 0x800000000;
a5xx_config.va_end = 0x8ffffffff;
+ a5xx_config.secure_va_start = SECURE_VA_START;
+ a5xx_config.secure_va_end = SECURE_VA_START + SECURE_VA_SIZE - 1;
+
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, &a5xx_config);
if (ret) {
a5xx_destroy(&(a5xx_gpu->base.base));
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 9952fa8dcda5..0929dc1ce78e 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -563,6 +563,15 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
return ret;
}
+ if (gpu->secure_aspace) {
+ mmu = gpu->secure_aspace->mmu;
+ if (mmu) {
+ ret = mmu->funcs->attach(mmu, NULL, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
mutex_lock(&drm->struct_mutex);
adreno_gpu->memptrs_bo = msm_gem_new(drm, sizeof(*adreno_gpu->memptrs),
MSM_BO_UNCACHED);
@@ -608,6 +617,12 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu)
aspace->mmu->funcs->detach(aspace->mmu);
msm_gem_address_space_put(aspace);
}
+
+ if (gpu->base.secure_aspace) {
+ aspace = gpu->base.secure_aspace;
+ aspace->mmu->funcs->detach(aspace->mmu);
+ msm_gem_address_space_put(aspace);
+ }
}
static void adreno_snapshot_os(struct msm_gpu *gpu,
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 7d378f7ebaa4..22addb797db3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1208,23 +1208,34 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
if (args->flags & ~MSM_INFO_FLAGS)
return -EINVAL;
- if (!ctx || !ctx->aspace)
- return -EINVAL;
-
obj = drm_gem_object_lookup(dev, file, args->handle);
if (!obj)
return -ENOENT;
if (args->flags & MSM_INFO_IOVA) {
+ struct msm_gem_address_space *aspace = NULL;
+ struct msm_drm_private *priv = dev->dev_private;
+ struct msm_gem_object *msm_obj = to_msm_bo(obj);
uint64_t iova;
- ret = msm_gem_get_iova(obj, ctx->aspace, &iova);
+ if (msm_obj->flags & MSM_BO_SECURE && priv->gpu)
+ aspace = priv->gpu->secure_aspace;
+ else if (ctx)
+ aspace = ctx->aspace;
+
+ if (!aspace) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = msm_gem_get_iova(obj, aspace, &iova);
if (!ret)
args->offset = iova;
} else {
args->offset = msm_gem_mmap_offset(obj);
}
+out:
drm_gem_object_unreference_unlocked(obj);
return ret;
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index bd75a1ba1f8b..94f429cb83a7 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -469,7 +469,7 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
struct drm_gem_object *msm_gem_new(struct drm_device *dev,
uint32_t size, uint32_t flags);
struct drm_gem_object *msm_gem_import(struct drm_device *dev,
- uint32_t size, struct sg_table *sgt);
+ uint32_t size, struct sg_table *sgt, u32 flags);
void msm_gem_sync(struct drm_gem_object *obj, u32 op);
int msm_framebuffer_prepare(struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index d35d03c2935d..4674c5423cbd 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -18,12 +18,31 @@
#include <linux/spinlock.h>
#include <linux/shmem_fs.h>
#include <linux/dma-buf.h>
+#include <soc/qcom/secure_buffer.h>
#include "msm_drv.h"
#include "msm_gem.h"
#include "msm_gpu.h"
#include "msm_mmu.h"
+static int protect_pages(struct msm_gem_object *msm_obj)
+{
+ int perm = PERM_READ | PERM_WRITE;
+ int src = VMID_HLOS;
+ int dst = VMID_CP_PIXEL;
+
+ return hyp_assign_table(msm_obj->sgt, &src, 1, &dst, &perm, 1);
+}
+
+static int unprotect_pages(struct msm_gem_object *msm_obj)
+{
+ int perm = PERM_READ | PERM_WRITE | PERM_EXEC;
+ int src = VMID_CP_PIXEL;
+ int dst = VMID_HLOS;
+
+ return hyp_assign_table(msm_obj->sgt, &src, 1, &dst, &perm, 1);
+}
+
static void *get_dmabuf_ptr(struct drm_gem_object *obj)
{
return (obj && obj->import_attach) ? obj->import_attach->dmabuf : NULL;
@@ -109,6 +128,20 @@ static struct page **get_pages(struct drm_gem_object *obj)
if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl,
msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+
+ /* Secure the pages if we need to */
+ if (use_pages(obj) && msm_obj->flags & MSM_BO_SECURE) {
+ int ret = protect_pages(msm_obj);
+
+ if (ret)
+ return ERR_PTR(ret);
+
+ /*
+ * Set a flag to indicate the pages are locked by us and
+ * need to be unlocked when the pages get freed
+ */
+ msm_obj->flags |= MSM_BO_LOCKED;
+ }
}
return msm_obj->pages;
@@ -119,12 +152,17 @@ static void put_pages(struct drm_gem_object *obj)
struct msm_gem_object *msm_obj = to_msm_bo(obj);
if (msm_obj->pages) {
+ if (msm_obj->flags & MSM_BO_LOCKED) {
+ unprotect_pages(msm_obj);
+ msm_obj->flags &= ~MSM_BO_LOCKED;
+ }
+
sg_free_table(msm_obj->sgt);
kfree(msm_obj->sgt);
- if (use_pages(obj))
+ if (use_pages(obj)) {
drm_gem_put_pages(obj, msm_obj->pages, true, false);
- else {
+ } else {
drm_mm_remove_node(msm_obj->vram_node);
drm_free_large(msm_obj->pages);
}
@@ -153,6 +191,12 @@ int msm_gem_mmap_obj(struct drm_gem_object *obj,
{
struct msm_gem_object *msm_obj = to_msm_bo(obj);
+ /* We can't mmap secure objects */
+ if (msm_obj->flags & MSM_BO_SECURE) {
+ drm_gem_vm_close(vma);
+ return -EACCES;
+ }
+
vma->vm_flags &= ~VM_PFNMAP;
vma->vm_flags |= VM_MIXEDMAP;
@@ -756,7 +800,7 @@ fail:
}
struct drm_gem_object *msm_gem_import(struct drm_device *dev,
- uint32_t size, struct sg_table *sgt)
+ uint32_t size, struct sg_table *sgt, u32 flags)
{
struct msm_gem_object *msm_obj;
struct drm_gem_object *obj;
@@ -789,6 +833,9 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev,
goto fail;
}
+ /* OR the passed in flags */
+ msm_obj->flags |= flags;
+
ret = drm_prime_sg_to_page_addr_arrays(sgt, msm_obj->pages, NULL, npages);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 0b19d11bc666..d5204221d902 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -24,6 +24,7 @@
/* Additional internal-use only BO flags: */
#define MSM_BO_STOLEN 0x10000000 /* try to use stolen/splash memory */
+#define MSM_BO_LOCKED 0x20000000 /* Pages have been securely locked */
struct msm_gem_address_space {
const char *name;
@@ -118,6 +119,7 @@ struct msm_gem_submit {
bool valid;
uint64_t profile_buf_iova;
void *profile_buf_vaddr;
+ bool secure;
unsigned int nr_cmds;
unsigned int nr_bos;
struct {
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c
index 121975b07cd4..678018804f3a 100644
--- a/drivers/gpu/drm/msm/msm_gem_prime.c
+++ b/drivers/gpu/drm/msm/msm_gem_prime.c
@@ -19,6 +19,7 @@
#include "msm_gem.h"
#include <linux/dma-buf.h>
+#include <linux/ion.h>
struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
{
@@ -55,7 +56,16 @@ int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach, struct sg_table *sg)
{
- return msm_gem_import(dev, attach->dmabuf->size, sg);
+ u32 flags = 0;
+
+ /*
+ * Check to see if this is a secure buffer by way of Ion and set the
+ * appropriate flag if so.
+ */
+ if (ion_dma_buf_is_secure(attach->dmabuf))
+ flags |= MSM_BO_SECURE;
+
+ return msm_gem_import(dev, attach->dmabuf->size, sg, flags);
}
int msm_gem_prime_pin(struct drm_gem_object *obj)
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 8e0f15c416fd..ea7b4441fe99 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -50,6 +50,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
submit->profile_buf_vaddr = NULL;
submit->profile_buf_iova = 0;
+ submit->secure = false;
INIT_LIST_HEAD(&submit->bo_list);
ww_acquire_init(&submit->ticket, &reservation_ww_class);
@@ -66,7 +67,8 @@ copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
return -EFAULT;
}
-static int submit_lookup_objects(struct msm_gem_submit *submit,
+static int submit_lookup_objects(struct msm_gpu *gpu,
+ struct msm_gem_submit *submit,
struct drm_msm_gem_submit *args, struct drm_file *file)
{
unsigned i;
@@ -119,6 +121,20 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
msm_obj = to_msm_bo(obj);
+ /*
+ * If the buffer is marked as secure make sure that we can
+ * handle secure buffers and then mark the submission as secure
+ */
+ if (msm_obj->flags & MSM_BO_SECURE) {
+ if (!gpu->secure_aspace) {
+ DRM_ERROR("Cannot handle secure buffers\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ submit->secure = true;
+ }
+
if (!list_empty(&msm_obj->submit_entry)) {
DRM_ERROR("handle %u at index %u already on submit list\n",
submit_bo.handle, i);
@@ -143,12 +159,17 @@ out:
return ret;
}
-static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i)
+static void submit_unlock_unpin_bo(struct msm_gpu *gpu,
+ struct msm_gem_submit *submit, int i)
{
struct msm_gem_object *msm_obj = submit->bos[i].obj;
+ struct msm_gem_address_space *aspace;
+
+ aspace = (msm_obj->flags & MSM_BO_SECURE) ?
+ gpu->secure_aspace : submit->aspace;
if (submit->bos[i].flags & BO_PINNED)
- msm_gem_put_iova(&msm_obj->base, submit->aspace);
+ msm_gem_put_iova(&msm_obj->base, aspace);
if (submit->bos[i].flags & BO_LOCKED)
ww_mutex_unlock(&msm_obj->resv->lock);
@@ -160,7 +181,8 @@ static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i)
}
/* This is where we make sure all the bo's are reserved and pin'd: */
-static int submit_validate_objects(struct msm_gem_submit *submit)
+static int submit_validate_objects(struct msm_gpu *gpu,
+ struct msm_gem_submit *submit)
{
int contended, slow_locked = -1, i, ret = 0;
@@ -169,8 +191,12 @@ retry:
for (i = 0; i < submit->nr_bos; i++) {
struct msm_gem_object *msm_obj = submit->bos[i].obj;
+ struct msm_gem_address_space *aspace;
uint64_t iova;
+ aspace = (msm_obj->flags & MSM_BO_SECURE) ?
+ gpu->secure_aspace : submit->aspace;
+
if (slow_locked == i)
slow_locked = -1;
@@ -186,8 +212,7 @@ retry:
/* if locking succeeded, pin bo: */
- ret = msm_gem_get_iova_locked(&msm_obj->base,
- submit->aspace, &iova);
+ ret = msm_gem_get_iova_locked(&msm_obj->base, aspace, &iova);
/* this would break the logic in the fail path.. there is no
* reason for this to happen, but just to be on the safe side
@@ -215,10 +240,10 @@ retry:
fail:
for (; i >= 0; i--)
- submit_unlock_unpin_bo(submit, i);
+ submit_unlock_unpin_bo(gpu, submit, i);
if (slow_locked > 0)
- submit_unlock_unpin_bo(submit, slow_locked);
+ submit_unlock_unpin_bo(gpu, submit, slow_locked);
if (ret == -EDEADLK) {
struct msm_gem_object *msm_obj = submit->bos[contended].obj;
@@ -267,6 +292,11 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
return -EINVAL;
}
+ if (obj->flags & MSM_BO_SECURE) {
+ DRM_ERROR("cannot do relocs on a secure buffer\n");
+ return -EINVAL;
+ }
+
/* For now, just map the entire thing. Eventually we probably
* to do it page-by-page, w/ kmap() if not vmap()d..
*/
@@ -327,13 +357,14 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
return 0;
}
-static void submit_cleanup(struct msm_gem_submit *submit, bool fail)
+static void submit_cleanup(struct msm_gpu *gpu, struct msm_gem_submit *submit,
+ bool fail)
{
unsigned i;
for (i = 0; i < submit->nr_bos; i++) {
struct msm_gem_object *msm_obj = submit->bos[i].obj;
- submit_unlock_unpin_bo(submit, i);
+ submit_unlock_unpin_bo(gpu, submit, i);
list_del_init(&msm_obj->submit_entry);
drm_gem_object_unreference(&msm_obj->base);
}
@@ -373,11 +404,11 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
goto out;
}
- ret = submit_lookup_objects(submit, args, file);
+ ret = submit_lookup_objects(gpu, submit, args, file);
if (ret)
goto out;
- ret = submit_validate_objects(submit);
+ ret = submit_validate_objects(gpu, submit);
if (ret)
goto out;
@@ -460,7 +491,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
out:
if (submit)
- submit_cleanup(submit, !!ret);
+ submit_cleanup(gpu, submit, !!ret);
mutex_unlock(&dev->struct_mutex);
return ret;
}
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 2f01db8b08c3..47fa02e8d1fc 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -572,12 +572,16 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
WARN_ON(is_active(msm_obj) && (msm_obj->gpu != gpu));
if (!is_active(msm_obj)) {
+ struct msm_gem_address_space *aspace;
uint64_t iova;
+ aspace = (msm_obj->flags & MSM_BO_SECURE) ?
+ gpu->secure_aspace : submit->aspace;
+
/* ring takes a reference to the bo and iova: */
drm_gem_object_reference(&msm_obj->base);
msm_gem_get_iova_locked(&msm_obj->base,
- submit->aspace, &iova);
+ aspace, &iova);
}
if (submit->bos[i].flags & MSM_SUBMIT_BO_READ)
@@ -757,11 +761,49 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)
return 0;
}
+static struct msm_gem_address_space *
+msm_gpu_create_address_space(struct msm_gpu *gpu, struct device *dev,
+ int type, u64 start, u64 end, const char *name)
+{
+ struct msm_gem_address_space *aspace;
+ struct iommu_domain *iommu;
+
+ /*
+ * If start == end then assume we don't want an address space; this is
+ * mainly for targets to opt out of secure
+ */
+ if (start == end)
+ return NULL;
+
+ iommu = iommu_domain_alloc(&platform_bus_type);
+ if (!iommu) {
+ dev_info(gpu->dev->dev,
+ "%s: no IOMMU, fallback to VRAM carveout!\n",
+ gpu->name);
+ return NULL;
+ }
+
+ iommu->geometry.aperture_start = start;
+ iommu->geometry.aperture_end = end;
+
+ dev_info(gpu->dev->dev, "%s: using IOMMU '%s'\n", gpu->name, name);
+
+ aspace = msm_gem_address_space_create(dev, iommu, type, name);
+ if (IS_ERR(aspace)) {
+ dev_err(gpu->dev->dev, "%s: failed to init IOMMU '%s': %ld\n",
+ gpu->name, name, PTR_ERR(aspace));
+
+ iommu_domain_free(iommu);
+ aspace = NULL;
+ }
+
+ return aspace;
+}
+
int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
const char *name, struct msm_gpu_config *config)
{
- struct iommu_domain *iommu;
int i, ret, nr_rings;
if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs)))
@@ -831,30 +873,13 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
if (IS_ERR(gpu->gpu_cx))
gpu->gpu_cx = NULL;
- /* Setup IOMMU.. eventually we will (I think) do this once per context
- * and have separate page tables per context. For now, to keep things
- * simple and to get something working, just use a single address space:
- */
- iommu = iommu_domain_alloc(&platform_bus_type);
- if (iommu) {
- /* TODO 32b vs 64b address space.. */
- iommu->geometry.aperture_start = config->va_start;
- iommu->geometry.aperture_end = config->va_end;
-
- dev_info(drm->dev, "%s: using IOMMU\n", name);
- gpu->aspace = msm_gem_address_space_create(&pdev->dev,
- iommu, MSM_IOMMU_DOMAIN_USER, "gpu");
- if (IS_ERR(gpu->aspace)) {
- ret = PTR_ERR(gpu->aspace);
- dev_err(drm->dev, "failed to init iommu: %d\n", ret);
- gpu->aspace = NULL;
- iommu_domain_free(iommu);
- goto fail;
- }
+ gpu->aspace = msm_gpu_create_address_space(gpu, &pdev->dev,
+ MSM_IOMMU_DOMAIN_USER, config->va_start, config->va_end,
+ "gpu");
- } else {
- dev_info(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name);
- }
+ gpu->secure_aspace = msm_gpu_create_address_space(gpu, &pdev->dev,
+ MSM_IOMMU_DOMAIN_SECURE, config->secure_va_start,
+ config->secure_va_end, "gpu_secure");
nr_rings = config->nr_rings;
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 29e2e59b580b..d273ea30151e 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -38,6 +38,8 @@ struct msm_gpu_config {
int nr_rings;
uint64_t va_start;
uint64_t va_end;
+ uint64_t secure_va_start;
+ uint64_t secure_va_end;
};
/* So far, with hardware that I've seen to date, we can have:
@@ -114,6 +116,7 @@ struct msm_gpu {
int irq;
struct msm_gem_address_space *aspace;
+ struct msm_gem_address_space *secure_aspace;
/* Power Control: */
struct regulator *gpu_reg, *gpu_cx;
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index bfb7dd2d920d..49ed6de1a95e 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -1473,6 +1473,28 @@ int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle)
}
EXPORT_SYMBOL(ion_share_dma_buf_fd);
+bool ion_dma_buf_is_secure(struct dma_buf *dmabuf)
+{
+ struct ion_buffer *buffer;
+ enum ion_heap_type type;
+
+ /* Return false if we didn't create the buffer */
+ if (!dmabuf || dmabuf->ops != &dma_buf_ops)
+ return false;
+
+ buffer = dmabuf->priv;
+
+ if (!buffer || !buffer->heap)
+ return false;
+
+ type = buffer->heap->type;
+
+ return (type == (enum ion_heap_type)ION_HEAP_TYPE_SECURE_DMA ||
+ type == (enum ion_heap_type)ION_HEAP_TYPE_SYSTEM_SECURE) ?
+ true : false;
+}
+EXPORT_SYMBOL(ion_dma_buf_is_secure);
+
struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd)
{
struct dma_buf *dmabuf;
diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h
index 5f99ea16617a..73902ebafca6 100644
--- a/drivers/staging/android/ion/ion.h
+++ b/drivers/staging/android/ion/ion.h
@@ -2,7 +2,7 @@
* drivers/staging/android/ion/ion.h
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014,2017 The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -209,6 +209,16 @@ int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle);
*/
struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd);
+/**
+ * ion_dma_buf_is_secure() - Returns true if the dma buf is secure
+ * dmabuf
+ * @dmabuf: pointer to a dma-buf
+ *
+ * Given a dma-buf pointer, return true if ion created it and it is from
+ * a secure heap.
+ */
+bool ion_dma_buf_is_secure(struct dma_buf *dmabuf);
+
#else
static inline void ion_reserve(struct ion_platform_data *data)
{
@@ -272,5 +282,10 @@ static inline int ion_handle_get_flags(struct ion_client *client,
return -ENODEV;
}
+bool ion_dma_buf_is_secure(struct dma_buf *dmabuf)
+{
+ return false;
+}
+
#endif /* CONFIG_ION */
#endif /* _LINUX_ION_H */
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index db65513ad656..07e6e00a89f6 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -78,6 +78,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_SECURE 0x00000008 /* Allocate and map as secure */
#define MSM_BO_CACHE_MASK 0x000f0000
/* cache modes */
#define MSM_BO_CACHED 0x00010000
@@ -86,6 +87,7 @@ struct drm_msm_param {
#define MSM_BO_FLAGS (MSM_BO_SCANOUT | \
MSM_BO_GPU_READONLY | \
+ MSM_BO_SECURE | \
MSM_BO_CACHED | \
MSM_BO_WC | \
MSM_BO_UNCACHED)