From b55462afc720b61348c14c519b05ea9106f2bc3d Mon Sep 17 00:00:00 2001 From: Jeremy Gebben Date: Mon, 12 Nov 2012 16:11:53 -0700 Subject: [PATCH] msm: kgsl: clean up iommu/gpummu protflag handling Make kgsl_memdesc_protflags() return the correct type of flags for the type of mmu being used. Query the memdesc with this function in kgsl_mmu_map(), rather than passing in the protflags. This prevents translation at multiple layers of the code and makes it easier to enforce that the mapping matches the allocation flags. Change-Id: I2a2f4a43026ae903dd134be00e646d258a83f79f Signed-off-by: Jeremy Gebben --- drivers/gpu/msm/adreno.c | 12 ++++-------- drivers/gpu/msm/adreno_ringbuffer.c | 1 + drivers/gpu/msm/kgsl.c | 14 ++++---------- drivers/gpu/msm/kgsl_drm.c | 3 +-- drivers/gpu/msm/kgsl_iommu.c | 13 ++++--------- drivers/gpu/msm/kgsl_mmu.c | 11 +++++------ drivers/gpu/msm/kgsl_mmu.h | 5 ++--- drivers/gpu/msm/kgsl_sharedmem.h | 25 +++++++++++++++++-------- drivers/gpu/msm/z180.c | 10 ++++------ 9 files changed, 42 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index b1a45bf7c62..bf45a637fe4 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -251,23 +251,19 @@ static int adreno_setup_pt(struct kgsl_device *device, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer; - result = kgsl_mmu_map_global(pagetable, &rb->buffer_desc, - GSL_PT_PAGE_RV); + result = kgsl_mmu_map_global(pagetable, &rb->buffer_desc); if (result) goto error; - result = kgsl_mmu_map_global(pagetable, &rb->memptrs_desc, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); + result = kgsl_mmu_map_global(pagetable, &rb->memptrs_desc); if (result) goto unmap_buffer_desc; - result = kgsl_mmu_map_global(pagetable, &device->memstore, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); + result = kgsl_mmu_map_global(pagetable, &device->memstore); if (result) goto unmap_memptrs_desc; - result = kgsl_mmu_map_global(pagetable, &device->mmu.setstate_memory, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); + result = kgsl_mmu_map_global(pagetable, &device->mmu.setstate_memory); if (result) goto unmap_memstore_desc; diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index 5cdf911068e..69b34fa8b2d 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -485,6 +485,7 @@ int adreno_ringbuffer_init(struct kgsl_device *device) */ rb->sizedwords = KGSL_RB_SIZE >> 2; + rb->buffer_desc.flags = KGSL_MEMFLAGS_GPUREADONLY; /* allocate memory for ringbuffer */ status = kgsl_allocate_contiguous(&rb->buffer_desc, (rb->sizedwords << 2)); diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 7ed0b108869..51d0ab5c6d4 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1875,10 +1875,7 @@ static long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv, else if (entry->memdesc.size >= SZ_64K) kgsl_memdesc_set_align(&entry->memdesc, ilog2(SZ_64)); - result = kgsl_mmu_map(private->pagetable, - &entry->memdesc, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); - + result = kgsl_mmu_map(private->pagetable, &entry->memdesc); if (result) goto error_put_file_ptr; @@ -2069,8 +2066,7 @@ kgsl_ioctl_gpumem_alloc(struct kgsl_device_private *dev_priv, if (result) return result; - result = kgsl_mmu_map(private->pagetable, &entry->memdesc, - kgsl_memdesc_protflags(&entry->memdesc)); + result = kgsl_mmu_map(private->pagetable, &entry->memdesc); if (result) goto err; @@ -2108,8 +2104,7 @@ kgsl_ioctl_gpumem_alloc_id(struct kgsl_device_private *dev_priv, goto err; if (!kgsl_memdesc_use_cpu_map(&entry->memdesc)) { - result = kgsl_mmu_map(private->pagetable, &entry->memdesc, - kgsl_memdesc_protflags(&entry->memdesc)); + result = kgsl_mmu_map(private->pagetable, &entry->memdesc); if (result) goto err; } @@ -2723,8 +2718,7 @@ static int kgsl_mmap(struct file *file, struct vm_area_struct *vma) if (kgsl_memdesc_use_cpu_map(&entry->memdesc)) { entry->memdesc.gpuaddr = vma->vm_start; - ret = kgsl_mmu_map(private->pagetable, &entry->memdesc, - kgsl_memdesc_protflags(&entry->memdesc)); + ret = kgsl_mmu_map(private->pagetable, &entry->memdesc); if (ret) { kgsl_mem_entry_put(entry); return ret; diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c index ba88a426bbb..2f3798ae715 100644 --- a/drivers/gpu/msm/kgsl_drm.c +++ b/drivers/gpu/msm/kgsl_drm.c @@ -210,8 +210,7 @@ kgsl_gem_alloc_memory(struct drm_gem_object *obj) return result; } - result = kgsl_mmu_map(priv->pagetable, &priv->memdesc, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); + result = kgsl_mmu_map(priv->pagetable, &priv->memdesc); if (result) { DRM_ERROR( "kgsl_mmu_map failed. result = %d\n", result); diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index df8e1d07675..a225a8ebd2f 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1118,16 +1118,14 @@ static int kgsl_iommu_setup_regs(struct kgsl_mmu *mmu, for (i = 0; i < iommu->unit_count; i++) { status = kgsl_mmu_map_global(pt, - &(iommu->iommu_units[i].reg_map), - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); + &(iommu->iommu_units[i].reg_map)); if (status) goto err; } /* Map Lock variables to GPU pagetable */ if (iommu->sync_lock_initialized) { - status = kgsl_mmu_map_global(pt, &iommu->sync_lock_desc, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); + status = kgsl_mmu_map_global(pt, &iommu->sync_lock_desc); if (status) goto err; } @@ -1499,22 +1497,19 @@ kgsl_iommu_map(void *mmu_specific_pt, unsigned int iommu_virt_addr; struct kgsl_iommu_pt *iommu_pt = mmu_specific_pt; int size = kgsl_sg_size(memdesc->sg, memdesc->sglen); - unsigned int iommu_flags = IOMMU_READ; BUG_ON(NULL == iommu_pt); - if (protflags & GSL_PT_PAGE_WV) - iommu_flags |= IOMMU_WRITE; iommu_virt_addr = memdesc->gpuaddr; ret = iommu_map_range(iommu_pt->domain, iommu_virt_addr, memdesc->sg, - size, iommu_flags); + size, protflags); if (ret) { KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %d, %d) " "failed with err: %d\n", iommu_pt->domain, iommu_virt_addr, memdesc->sg, size, - iommu_flags, ret); + protflags, ret); return ret; } diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index f71cf8c594b..83cf83d33da 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2012, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -580,13 +580,13 @@ void kgsl_mh_start(struct kgsl_device *device) int kgsl_mmu_map(struct kgsl_pagetable *pagetable, - struct kgsl_memdesc *memdesc, - unsigned int protflags) + struct kgsl_memdesc *memdesc) { int ret; struct gen_pool *pool = NULL; int size; int page_align = ilog2(PAGE_SIZE); + unsigned int protflags = kgsl_memdesc_protflags(memdesc); if (kgsl_mmu_type == KGSL_MMU_TYPE_NONE) { if (memdesc->sglen == 1) { @@ -738,7 +738,7 @@ kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, EXPORT_SYMBOL(kgsl_mmu_unmap); int kgsl_mmu_map_global(struct kgsl_pagetable *pagetable, - struct kgsl_memdesc *memdesc, unsigned int protflags) + struct kgsl_memdesc *memdesc) { int result = -EINVAL; unsigned int gpuaddr = 0; @@ -750,11 +750,10 @@ int kgsl_mmu_map_global(struct kgsl_pagetable *pagetable, /* Not all global mappings are needed for all MMU types */ if (!memdesc->size) return 0; - gpuaddr = memdesc->gpuaddr; memdesc->priv |= KGSL_MEMDESC_GLOBAL; - result = kgsl_mmu_map(pagetable, memdesc, protflags); + result = kgsl_mmu_map(pagetable, memdesc); if (result) goto error; diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index 2b33baf5116..0458a1345e0 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -201,10 +201,9 @@ int kgsl_mmu_init(struct kgsl_device *device); int kgsl_mmu_start(struct kgsl_device *device); int kgsl_mmu_close(struct kgsl_device *device); int kgsl_mmu_map(struct kgsl_pagetable *pagetable, - struct kgsl_memdesc *memdesc, - unsigned int protflags); + struct kgsl_memdesc *memdesc); int kgsl_mmu_map_global(struct kgsl_pagetable *pagetable, - struct kgsl_memdesc *memdesc, unsigned int protflags); + struct kgsl_memdesc *memdesc); int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr); diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h index 27b91510ae6..279490f68c6 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.h +++ b/drivers/gpu/msm/kgsl_sharedmem.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2012, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,6 +19,7 @@ #include "kgsl_mmu.h" #include #include +#include #include "kgsl_log.h" @@ -195,15 +196,24 @@ kgsl_memdesc_has_guard_page(const struct kgsl_memdesc *memdesc) /* * kgsl_memdesc_protflags - get mmu protection flags * @memdesc - the memdesc - * Returns a mask of GSL_PT_PAGE* values based on the - * memdesc flags. + * Returns a mask of GSL_PT_PAGE* or IOMMU* values based + * on the memdesc flags. */ static inline unsigned int kgsl_memdesc_protflags(const struct kgsl_memdesc *memdesc) { - unsigned int protflags = GSL_PT_PAGE_RV; - if (!(memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY)) - protflags |= GSL_PT_PAGE_WV; + unsigned int protflags = 0; + enum kgsl_mmutype mmutype = kgsl_mmu_get_mmutype(); + + if (mmutype == KGSL_MMU_TYPE_GPU) { + protflags = GSL_PT_PAGE_RV; + if (!(memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY)) + protflags |= GSL_PT_PAGE_WV; + } else if (mmutype == KGSL_MMU_TYPE_IOMMU) { + protflags = IOMMU_READ; + if (!(memdesc->flags & KGSL_MEMFLAGS_GPUREADONLY)) + protflags |= IOMMU_WRITE; + } return protflags; } @@ -248,8 +258,7 @@ kgsl_allocate(struct kgsl_memdesc *memdesc, ret = kgsl_sharedmem_page_alloc(memdesc, pagetable, size); if (ret) return ret; - ret = kgsl_mmu_map(pagetable, memdesc, - kgsl_memdesc_protflags(memdesc)); + ret = kgsl_mmu_map(pagetable, memdesc); if (ret) kgsl_sharedmem_free(memdesc); return ret; diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c index e578b0e63bb..f0410d64536 100644 --- a/drivers/gpu/msm/z180.c +++ b/drivers/gpu/msm/z180.c @@ -244,20 +244,17 @@ static int z180_setup_pt(struct kgsl_device *device, int result = 0; struct z180_device *z180_dev = Z180_DEVICE(device); - result = kgsl_mmu_map_global(pagetable, &device->mmu.setstate_memory, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); + result = kgsl_mmu_map_global(pagetable, &device->mmu.setstate_memory); if (result) goto error; - result = kgsl_mmu_map_global(pagetable, &device->memstore, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV); + result = kgsl_mmu_map_global(pagetable, &device->memstore); if (result) goto error_unmap_dummy; result = kgsl_mmu_map_global(pagetable, - &z180_dev->ringbuffer.cmdbufdesc, - GSL_PT_PAGE_RV); + &z180_dev->ringbuffer.cmdbufdesc); if (result) goto error_unmap_memstore; /* @@ -498,6 +495,7 @@ static int z180_ringbuffer_init(struct kgsl_device *device) struct z180_device *z180_dev = Z180_DEVICE(device); memset(&z180_dev->ringbuffer, 0, sizeof(struct z180_ringbuffer)); z180_dev->ringbuffer.prevctx = Z180_INVALID_CONTEXT; + z180_dev->ringbuffer.cmdbufdesc.flags = KGSL_MEMFLAGS_GPUREADONLY; return kgsl_allocate_contiguous(&z180_dev->ringbuffer.cmdbufdesc, Z180_RB_SIZE); }