Loading drivers/gpu/msm/adreno_a5xx.c +2 −2 Original line number Diff line number Diff line /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2017, 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 Loading Loading @@ -250,7 +250,7 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev) return ret; ret = kgsl_allocate_user(&adreno_dev->dev, &crit_pkts_refbuf0, NULL, PAGE_SIZE, KGSL_MEMFLAGS_SECURE); PAGE_SIZE, KGSL_MEMFLAGS_SECURE); if (ret) return ret; Loading drivers/gpu/msm/kgsl.c +7 −26 Original line number Diff line number Diff line /* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2008-2017, 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 Loading Loading @@ -370,24 +370,6 @@ kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, return kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc); } /** * kgsl_mem_entry_untrack_gpuaddr() - Untrack memory that is previously tracked * process - Pointer to process private to which memory belongs * entry - Memory entry to untrack * * Function just does the opposite of kgsl_mem_entry_track_gpuaddr. Needs to be * called with processes spin lock held */ static void kgsl_mem_entry_untrack_gpuaddr(struct kgsl_process_private *process, struct kgsl_mem_entry *entry) { struct kgsl_pagetable *pagetable = entry->memdesc.pagetable; if (entry->memdesc.gpuaddr) kgsl_mmu_put_gpuaddr(pagetable, &entry->memdesc); } /* Commit the entry to the process so it can be accessed by other operations */ static void kgsl_mem_entry_commit_process(struct kgsl_mem_entry *entry) { Loading Loading @@ -436,7 +418,7 @@ kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry, if (id < 0) { ret = id; kgsl_mem_entry_untrack_gpuaddr(process, entry); kgsl_mmu_put_gpuaddr(&entry->memdesc); goto err_put_proc_priv; } Loading Loading @@ -472,6 +454,7 @@ err_put_proc_priv: static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry) { unsigned int type; if (entry == NULL) return; Loading @@ -488,9 +471,7 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry) entry->priv->stats[type].cur -= entry->memdesc.size; spin_unlock(&entry->priv->mem_lock); kgsl_mmu_unmap(entry->memdesc.pagetable, &entry->memdesc); kgsl_mem_entry_untrack_gpuaddr(entry->priv, entry); kgsl_mmu_put_gpuaddr(&entry->memdesc); kgsl_process_private_put(entry->priv); Loading Loading @@ -3021,7 +3002,7 @@ static struct kgsl_mem_entry *gpumem_alloc_entry( entry->memdesc.priv |= KGSL_MEMDESC_SECURE; ret = kgsl_allocate_user(dev_priv->device, &entry->memdesc, private->pagetable, size, flags); size, flags); if (ret != 0) goto err; Loading Loading @@ -3442,11 +3423,11 @@ static unsigned long _gpu_set_svm_region(struct kgsl_process_private *private, return ret; entry->memdesc.gpuaddr = (uint64_t) addr; entry->memdesc.pagetable = private->pagetable; ret = kgsl_mmu_map(private->pagetable, &entry->memdesc); if (ret) { kgsl_mmu_put_gpuaddr(private->pagetable, &entry->memdesc); kgsl_mmu_put_gpuaddr(&entry->memdesc); return ret; } Loading drivers/gpu/msm/kgsl_iommu.c +19 −16 Original line number Diff line number Diff line /* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2017, 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 Loading Loading @@ -1402,17 +1402,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); 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); } return 0; return ret; } static int kgsl_iommu_init(struct kgsl_mmu *mmu) Loading Loading @@ -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"); Loading Loading @@ -2264,23 +2263,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, Loading drivers/gpu/msm/kgsl_mmu.c +23 −6 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2017, 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 Loading Loading @@ -419,17 +419,29 @@ EXPORT_SYMBOL(kgsl_mmu_map); * @pagetable: Pagetable to release the memory from * @memdesc: Memory descriptor containing the GPU address to free */ void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc) void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc) { struct kgsl_pagetable *pagetable = memdesc->pagetable; int unmap_fail = 0; if (memdesc->size == 0 || memdesc->gpuaddr == 0) return; if (PT_OP_VALID(pagetable, put_gpuaddr)) pagetable->pt_ops->put_gpuaddr(pagetable, memdesc); if (!kgsl_memdesc_is_global(memdesc)) unmap_fail = kgsl_mmu_unmap(pagetable, memdesc); /* * Do not free the gpuaddr/size if unmap fails. Because if we * try to map this range in future, the iommu driver will throw * a BUG_ON() because it feels we are overwriting a mapping. */ if (PT_OP_VALID(pagetable, put_gpuaddr) && (unmap_fail == 0)) pagetable->pt_ops->put_gpuaddr(memdesc); if (!kgsl_memdesc_is_global(memdesc)) memdesc->gpuaddr = 0; memdesc->pagetable = NULL; } EXPORT_SYMBOL(kgsl_mmu_put_gpuaddr); Loading Loading @@ -580,7 +592,12 @@ static int nommu_get_gpuaddr(struct kgsl_pagetable *pagetable, memdesc->gpuaddr = (uint64_t) sg_phys(memdesc->sgt->sgl); return memdesc->gpuaddr != 0 ? 0 : -ENOMEM; if (memdesc->gpuaddr) { memdesc->pagetable = pagetable; return 0; } return -ENOMEM; } static struct kgsl_mmu_pt_ops nommu_pt_ops = { Loading drivers/gpu/msm/kgsl_mmu.h +3 −4 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2017, 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 Loading Loading @@ -92,7 +92,7 @@ struct kgsl_mmu_pt_ops { u64 (*get_ttbr0)(struct kgsl_pagetable *); u32 (*get_contextidr)(struct kgsl_pagetable *); int (*get_gpuaddr)(struct kgsl_pagetable *, struct kgsl_memdesc *); void (*put_gpuaddr)(struct kgsl_pagetable *, struct kgsl_memdesc *); void (*put_gpuaddr)(struct kgsl_memdesc *); uint64_t (*find_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t, uint64_t, uint64_t); int (*set_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t); Loading Loading @@ -180,8 +180,7 @@ int kgsl_mmu_map(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc); unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr); unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, u64 ttbr0, uint64_t addr); Loading Loading
drivers/gpu/msm/adreno_a5xx.c +2 −2 Original line number Diff line number Diff line /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2017, 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 Loading Loading @@ -250,7 +250,7 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev) return ret; ret = kgsl_allocate_user(&adreno_dev->dev, &crit_pkts_refbuf0, NULL, PAGE_SIZE, KGSL_MEMFLAGS_SECURE); PAGE_SIZE, KGSL_MEMFLAGS_SECURE); if (ret) return ret; Loading
drivers/gpu/msm/kgsl.c +7 −26 Original line number Diff line number Diff line /* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2008-2017, 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 Loading Loading @@ -370,24 +370,6 @@ kgsl_mem_entry_track_gpuaddr(struct kgsl_process_private *process, return kgsl_mmu_get_gpuaddr(pagetable, &entry->memdesc); } /** * kgsl_mem_entry_untrack_gpuaddr() - Untrack memory that is previously tracked * process - Pointer to process private to which memory belongs * entry - Memory entry to untrack * * Function just does the opposite of kgsl_mem_entry_track_gpuaddr. Needs to be * called with processes spin lock held */ static void kgsl_mem_entry_untrack_gpuaddr(struct kgsl_process_private *process, struct kgsl_mem_entry *entry) { struct kgsl_pagetable *pagetable = entry->memdesc.pagetable; if (entry->memdesc.gpuaddr) kgsl_mmu_put_gpuaddr(pagetable, &entry->memdesc); } /* Commit the entry to the process so it can be accessed by other operations */ static void kgsl_mem_entry_commit_process(struct kgsl_mem_entry *entry) { Loading Loading @@ -436,7 +418,7 @@ kgsl_mem_entry_attach_process(struct kgsl_mem_entry *entry, if (id < 0) { ret = id; kgsl_mem_entry_untrack_gpuaddr(process, entry); kgsl_mmu_put_gpuaddr(&entry->memdesc); goto err_put_proc_priv; } Loading Loading @@ -472,6 +454,7 @@ err_put_proc_priv: static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry) { unsigned int type; if (entry == NULL) return; Loading @@ -488,9 +471,7 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry) entry->priv->stats[type].cur -= entry->memdesc.size; spin_unlock(&entry->priv->mem_lock); kgsl_mmu_unmap(entry->memdesc.pagetable, &entry->memdesc); kgsl_mem_entry_untrack_gpuaddr(entry->priv, entry); kgsl_mmu_put_gpuaddr(&entry->memdesc); kgsl_process_private_put(entry->priv); Loading Loading @@ -3021,7 +3002,7 @@ static struct kgsl_mem_entry *gpumem_alloc_entry( entry->memdesc.priv |= KGSL_MEMDESC_SECURE; ret = kgsl_allocate_user(dev_priv->device, &entry->memdesc, private->pagetable, size, flags); size, flags); if (ret != 0) goto err; Loading Loading @@ -3442,11 +3423,11 @@ static unsigned long _gpu_set_svm_region(struct kgsl_process_private *private, return ret; entry->memdesc.gpuaddr = (uint64_t) addr; entry->memdesc.pagetable = private->pagetable; ret = kgsl_mmu_map(private->pagetable, &entry->memdesc); if (ret) { kgsl_mmu_put_gpuaddr(private->pagetable, &entry->memdesc); kgsl_mmu_put_gpuaddr(&entry->memdesc); return ret; } Loading
drivers/gpu/msm/kgsl_iommu.c +19 −16 Original line number Diff line number Diff line /* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2017, 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 Loading Loading @@ -1402,17 +1402,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); 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); } return 0; return ret; } static int kgsl_iommu_init(struct kgsl_mmu *mmu) Loading Loading @@ -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"); Loading Loading @@ -2264,23 +2263,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, Loading
drivers/gpu/msm/kgsl_mmu.c +23 −6 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2017, 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 Loading Loading @@ -419,17 +419,29 @@ EXPORT_SYMBOL(kgsl_mmu_map); * @pagetable: Pagetable to release the memory from * @memdesc: Memory descriptor containing the GPU address to free */ void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc) void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc) { struct kgsl_pagetable *pagetable = memdesc->pagetable; int unmap_fail = 0; if (memdesc->size == 0 || memdesc->gpuaddr == 0) return; if (PT_OP_VALID(pagetable, put_gpuaddr)) pagetable->pt_ops->put_gpuaddr(pagetable, memdesc); if (!kgsl_memdesc_is_global(memdesc)) unmap_fail = kgsl_mmu_unmap(pagetable, memdesc); /* * Do not free the gpuaddr/size if unmap fails. Because if we * try to map this range in future, the iommu driver will throw * a BUG_ON() because it feels we are overwriting a mapping. */ if (PT_OP_VALID(pagetable, put_gpuaddr) && (unmap_fail == 0)) pagetable->pt_ops->put_gpuaddr(memdesc); if (!kgsl_memdesc_is_global(memdesc)) memdesc->gpuaddr = 0; memdesc->pagetable = NULL; } EXPORT_SYMBOL(kgsl_mmu_put_gpuaddr); Loading Loading @@ -580,7 +592,12 @@ static int nommu_get_gpuaddr(struct kgsl_pagetable *pagetable, memdesc->gpuaddr = (uint64_t) sg_phys(memdesc->sgt->sgl); return memdesc->gpuaddr != 0 ? 0 : -ENOMEM; if (memdesc->gpuaddr) { memdesc->pagetable = pagetable; return 0; } return -ENOMEM; } static struct kgsl_mmu_pt_ops nommu_pt_ops = { Loading
drivers/gpu/msm/kgsl_mmu.h +3 −4 Original line number Diff line number Diff line /* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2002,2007-2017, 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 Loading Loading @@ -92,7 +92,7 @@ struct kgsl_mmu_pt_ops { u64 (*get_ttbr0)(struct kgsl_pagetable *); u32 (*get_contextidr)(struct kgsl_pagetable *); int (*get_gpuaddr)(struct kgsl_pagetable *, struct kgsl_memdesc *); void (*put_gpuaddr)(struct kgsl_pagetable *, struct kgsl_memdesc *); void (*put_gpuaddr)(struct kgsl_memdesc *); uint64_t (*find_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t, uint64_t, uint64_t); int (*set_svm_region)(struct kgsl_pagetable *, uint64_t, uint64_t); Loading Loading @@ -180,8 +180,7 @@ int kgsl_mmu_map(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc); void kgsl_mmu_put_gpuaddr(struct kgsl_memdesc *memdesc); unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr); unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu, u64 ttbr0, uint64_t addr); Loading