diff options
author | Jordan Crouse <jcrouse@codeaurora.org> | 2016-05-31 11:24:23 -0600 |
---|---|---|
committer | Harshdeep Dhatt <hdhatt@codeaurora.org> | 2016-11-03 12:06:14 -0600 |
commit | e141e85de76ff485d867a272bda582d6ed452ee4 (patch) | |
tree | be53acec552e2a68f500b7cbec005958859a0b7e /drivers/gpu/msm/kgsl_iommu.c | |
parent | 5b7da258870763a6fe394b3ed1d96ddba59cce28 (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.c | 33 |
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, |