summaryrefslogtreecommitdiff
path: root/drivers/gpu/msm/kgsl_iommu.c
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2016-05-31 11:24:23 -0600
committerHarshdeep Dhatt <hdhatt@codeaurora.org>2016-11-03 12:06:14 -0600
commite141e85de76ff485d867a272bda582d6ed452ee4 (patch)
treebe53acec552e2a68f500b7cbec005958859a0b7e /drivers/gpu/msm/kgsl_iommu.c
parent5b7da258870763a6fe394b3ed1d96ddba59cce28 (diff)
msm: kgsl: Fix pagetable member of struct kgsl_memdesc
memdesc->pagetable is supposed to help ensure that memory gets unmapped before it is freed, but the pagetable member is being populated at create time not when the buffer gets mapped. This forces the developer to ensure that the same pagetable is used for both the create and map step. Instead, assign the pagetable member when it is first used (to get a GPU address) and put it away when the GPU address is released. Change-Id: Ic0dedbad372fd9029b932dd99633a650049751ed Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Diffstat (limited to 'drivers/gpu/msm/kgsl_iommu.c')
-rw-r--r--drivers/gpu/msm/kgsl_iommu.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 9f35a3197a4c..bc681057250d 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -1403,17 +1403,16 @@ static int _setstate_alloc(struct kgsl_device *device,
{
int ret;
- ret = kgsl_sharedmem_alloc_contig(device, &iommu->setstate, NULL,
- PAGE_SIZE);
- if (ret)
- return ret;
+ ret = kgsl_sharedmem_alloc_contig(device, &iommu->setstate, PAGE_SIZE);
- /* Mark the setstate memory as read only */
- iommu->setstate.flags |= KGSL_MEMFLAGS_GPUREADONLY;
+ if (!ret) {
+ /* Mark the setstate memory as read only */
+ iommu->setstate.flags |= KGSL_MEMFLAGS_GPUREADONLY;
- kgsl_sharedmem_set(device, &iommu->setstate, 0, 0, PAGE_SIZE);
+ kgsl_sharedmem_set(device, &iommu->setstate, 0, 0, PAGE_SIZE);
+ }
- return 0;
+ return ret;
}
static int kgsl_iommu_init(struct kgsl_mmu *mmu)
@@ -1663,7 +1662,7 @@ static int _iommu_map_guard_page(struct kgsl_pagetable *pt,
if (!kgsl_secure_guard_page_memdesc.sgt) {
if (kgsl_allocate_user(KGSL_MMU_DEVICE(pt->mmu),
- &kgsl_secure_guard_page_memdesc, pt,
+ &kgsl_secure_guard_page_memdesc,
sgp_size, KGSL_MEMFLAGS_SECURE)) {
KGSL_CORE_ERR(
"Secure guard page alloc failed\n");
@@ -2364,23 +2363,27 @@ static int kgsl_iommu_get_gpuaddr(struct kgsl_pagetable *pagetable,
}
ret = _insert_gpuaddr(pagetable, addr, size);
- if (ret == 0)
+ if (ret == 0) {
memdesc->gpuaddr = addr;
+ memdesc->pagetable = pagetable;
+ }
out:
spin_unlock(&pagetable->lock);
return ret;
}
-static void kgsl_iommu_put_gpuaddr(struct kgsl_pagetable *pagetable,
- struct kgsl_memdesc *memdesc)
+static void kgsl_iommu_put_gpuaddr(struct kgsl_memdesc *memdesc)
{
- spin_lock(&pagetable->lock);
+ if (memdesc->pagetable == NULL)
+ return;
+
+ spin_lock(&memdesc->pagetable->lock);
- if (_remove_gpuaddr(pagetable, memdesc->gpuaddr))
+ if (_remove_gpuaddr(memdesc->pagetable, memdesc->gpuaddr))
BUG();
- spin_unlock(&pagetable->lock);
+ spin_unlock(&memdesc->pagetable->lock);
}
static int kgsl_iommu_svm_range(struct kgsl_pagetable *pagetable,