diff options
author | Nrithya Kanakasabapathy <nrithya@google.com> | 2021-03-25 05:35:57 +0000 |
---|---|---|
committer | Nrithya Kanakasabapathy <nrithya@google.com> | 2021-03-25 05:38:03 +0000 |
commit | 2be4b1e51a13039aed1f3b9b2544f75d2df2ea6b (patch) | |
tree | 8c1b6f0313cb71643adda9cb642e033b30bff72f | |
parent | d034701c6f09fb30bcaefdd750b60eed70752d7e (diff) | |
download | abrolhos-2be4b1e51a13039aed1f3b9b2544f75d2df2ea6b.tar.gz |
Merge branch 'whitechapel' into android-gs-pixel-5.10
* whitechapel:
edgetpu: free reserved IOVA on error in edgetpu_map_iova_sgt_worker
edgetpu: return EPERM for non-root full CSR mmap
edgetpu: remove ALLOCATE_DEVICE_BUFFER_COMPAT
Signed-off-by: Nrithya Kanakasabapathy <nrithya@google.com>
Change-Id: Ic53bb9eb07be428cafc870deacb110bbeb1b4248
-rw-r--r-- | drivers/edgetpu/edgetpu-core.c | 13 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-device-group.c | 10 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-dmabuf.c | 29 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-fs.c | 34 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-mmu.h | 4 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu.h | 29 |
6 files changed, 40 insertions, 79 deletions
diff --git a/drivers/edgetpu/edgetpu-core.c b/drivers/edgetpu/edgetpu-core.c index e4ae403..9de2a75 100644 --- a/drivers/edgetpu/edgetpu-core.c +++ b/drivers/edgetpu/edgetpu-core.c @@ -38,17 +38,14 @@ static atomic_t single_dev_count = ATOMIC_INIT(-1); -static int edgetpu_mmap_compat(struct edgetpu_client *client, - struct vm_area_struct *vma) +static int edgetpu_mmap_full_csr(struct edgetpu_client *client, + struct vm_area_struct *vma) { int ret; ulong phys_base, vma_size, map_size; - /* TODO(b/156444816): return -EPERM for non-root users */ if (!uid_eq(current_euid(), GLOBAL_ROOT_UID)) - etdev_warn_once( - client->etdev, - "mmap full CSR region without root permission is deprecated"); + return -EPERM; vma_size = vma->vm_end - vma->vm_start; map_size = min(vma_size, client->reg_window.size); phys_base = client->etdev->regs.phys + @@ -126,11 +123,11 @@ int edgetpu_mmap(struct edgetpu_client *client, struct vm_area_struct *vma) /* Mark the VMA's pages as uncacheable. */ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - /* If backward compat map all CSRs */ + /* map all CSRs for debug purpose */ if (!vma->vm_pgoff) { evt = EDGETPU_WAKELOCK_EVENT_FULL_CSR; if (edgetpu_wakelock_inc_event(client->wakelock, evt)) { - ret = edgetpu_mmap_compat(client, vma); + ret = edgetpu_mmap_full_csr(client, vma); if (ret) edgetpu_wakelock_dec_event(client->wakelock, evt); diff --git a/drivers/edgetpu/edgetpu-device-group.c b/drivers/edgetpu/edgetpu-device-group.c index 273feba..2b2f2c8 100644 --- a/drivers/edgetpu/edgetpu-device-group.c +++ b/drivers/edgetpu/edgetpu-device-group.c @@ -865,11 +865,15 @@ static int edgetpu_map_iova_sgt_worker(struct iova_mapping_worker_param *param) const struct edgetpu_mapping *map = &hmap->map; enum edgetpu_context_id ctx_id = edgetpu_group_context_id_locked(group); struct edgetpu_dev *etdev = edgetpu_device_group_nth_etdev(group, i); + int ret; edgetpu_mmu_reserve(etdev, map->alloc_iova, map->alloc_size); - return edgetpu_mmu_map_iova_sgt(etdev, map->device_address, - &hmap->sg_tables[i], map->dir, - ctx_id); + ret = edgetpu_mmu_map_iova_sgt(etdev, map->device_address, + &hmap->sg_tables[i], map->dir, + ctx_id); + if (ret) + edgetpu_mmu_free(etdev, map->alloc_iova, map->alloc_size); + return ret; } /* diff --git a/drivers/edgetpu/edgetpu-dmabuf.c b/drivers/edgetpu/edgetpu-dmabuf.c index 5bf795d..b0e3886 100644 --- a/drivers/edgetpu/edgetpu-dmabuf.c +++ b/drivers/edgetpu/edgetpu-dmabuf.c @@ -103,7 +103,7 @@ static int etdev_add_translations(struct edgetpu_dev *etdev, struct sg_table *sgt = &entry->shrunk_sgt; struct scatterlist *sg; - for (sg = sgt->sgl, i = 0; i < sgt->nents; i++, sg = sg_next(sg)) { + for_each_sg(sgt->sgl, sg, sgt->nents, i) { ret = edgetpu_mmu_add_translation(etdev, tpu_addr + offset, sg_dma_address(sg), sg_dma_len(sg), prot, ctx_id); @@ -111,6 +111,7 @@ static int etdev_add_translations(struct edgetpu_dev *etdev, goto rollback; offset += sg_dma_len(sg); } + edgetpu_mmu_reserve(etdev, tpu_addr, offset); return 0; rollback: @@ -118,6 +119,24 @@ rollback: return ret; } +static void etdev_remove_translations(struct edgetpu_dev *etdev, + tpu_addr_t tpu_addr, + struct dmabuf_map_entry *entry, + enum edgetpu_context_id ctx_id) +{ + uint i; + u64 offset = 0; + struct sg_table *sgt = &entry->shrunk_sgt; + struct scatterlist *sg; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + edgetpu_mmu_remove_translation(etdev, tpu_addr + offset, + sg_dma_len(sg), ctx_id); + offset += sg_dma_len(sg); + } + edgetpu_mmu_free(etdev, tpu_addr, offset); +} + /* * Maps to the first entry in @dmap. * @@ -218,8 +237,8 @@ err_remove: if (!dmap->entries[i].sgt) edgetpu_mmu_free(etdev, tpu_addr, dmap->size); else - edgetpu_mmu_remove_translation(etdev, tpu_addr, - dmap->size, ctx_id); + etdev_remove_translations(etdev, tpu_addr, + &dmap->entries[i], ctx_id); } etdev_unmap_dmabuf(group->etdev, dmap, tpu_addr); @@ -242,8 +261,8 @@ static void group_unmap_dmabuf(struct edgetpu_device_group *group, for (i = 1; i < group->n_clients; i++) { etdev = edgetpu_device_group_nth_etdev(group, i); - edgetpu_mmu_remove_translation(etdev, tpu_addr, dmap->size, - ctx_id); + etdev_remove_translations(etdev, tpu_addr, &dmap->entries[i], + ctx_id); } etdev_unmap_dmabuf(group->etdev, dmap, tpu_addr); } diff --git a/drivers/edgetpu/edgetpu-fs.c b/drivers/edgetpu/edgetpu-fs.c index 9efee4b..14cbbce 100644 --- a/drivers/edgetpu/edgetpu-fs.c +++ b/drivers/edgetpu/edgetpu-fs.c @@ -338,37 +338,6 @@ static int edgetpu_ioctl_unmap_buffer(struct edgetpu_client *client, return ret; } -static int edgetpu_ioctl_allocate_device_buffer_compat( - struct edgetpu_client *leader, - struct edgetpu_device_buffer_ioctl __user *argp) -{ -#ifndef EDGETPU_HAS_DEVICE_DRAM - return -ENOTTY; -#else - struct edgetpu_device_buffer_ioctl ibuf; - struct edgetpu_client *client; - struct edgetpu_device_group *group; - - if (copy_from_user(&ibuf, argp, sizeof(ibuf))) - return -EFAULT; - - LOCK_RETURN_IF_NOT_LEADER(leader, group); - mutex_lock(&group->lock); - - if (!edgetpu_device_group_is_finalized(group) || - ibuf.die_index >= group->n_clients) { - mutex_unlock(&group->lock); - UNLOCK(leader); - return -EINVAL; - } - client = group->members[ibuf.die_index]; - mutex_unlock(&group->lock); - UNLOCK(leader); - - return edgetpu_device_dram_getfd(client, ibuf.size); -#endif /* EDGETPU_HAS_DEVICE_DRAM */ -} - static int edgetpu_ioctl_allocate_device_buffer(struct edgetpu_client *client, u64 size) { @@ -662,9 +631,6 @@ long edgetpu_ioctl(struct file *file, uint cmd, ulong arg) case EDGETPU_SET_PERDIE_EVENTFD: ret = edgetpu_ioctl_set_perdie_eventfd(client->etdev, argp); break; - case EDGETPU_ALLOCATE_DEVICE_BUFFER_COMPAT: - ret = edgetpu_ioctl_allocate_device_buffer_compat(client, argp); - break; case EDGETPU_UNSET_EVENT: ret = edgetpu_ioctl_unset_eventfd(client, arg); break; diff --git a/drivers/edgetpu/edgetpu-mmu.h b/drivers/edgetpu/edgetpu-mmu.h index 0391ff3..8ef2f2c 100644 --- a/drivers/edgetpu/edgetpu-mmu.h +++ b/drivers/edgetpu/edgetpu-mmu.h @@ -202,6 +202,10 @@ void edgetpu_mmu_free(struct edgetpu_dev *etdev, tpu_addr_t tpu_addr, * (as on Hermosa, where the SMMU translates TPU VAs to IOVAs sent to the IOMMU * downstream of the TPU). * + * Note: for chipsets with edgetpu_mmu_alloc() support, @iova passed to this + * function must be either allocated from edgetpu_mmu_alloc() or reserved by + * edgetpu_mmu_reserve(). + * * For chipsets with IOMMU AUX domain support, @context_id can be used to * specify a detached IOMMU domain by value * (EDGETPU_CONTEXT_DOMAIN_TOKEN | @token), where @token is the one returned by diff --git a/drivers/edgetpu/edgetpu.h b/drivers/edgetpu/edgetpu.h index b494224..c382581 100644 --- a/drivers/edgetpu/edgetpu.h +++ b/drivers/edgetpu/edgetpu.h @@ -172,35 +172,6 @@ struct edgetpu_mailbox_attr { #define EDGETPU_SET_PERDIE_EVENTFD \ _IOW(EDGETPU_IOCTL_BASE, 9, struct edgetpu_event_register) -struct edgetpu_device_buffer_ioctl { - /* - * Buffer size to be allocated in bytes. - * - * The size will be aligned with the page size. - */ - __u64 size; - /* - * The buffer will be allocated on the @die_index-th die's device DRAM. - * The index is decided by the order of joining the group, with value - * from zero to (# dies in group) - 1. - */ - __u32 die_index; -}; - -/* - * Deprecated, use EDGETPU_ALLOCATE_DEVICE_BUFFER. - * - * Return a dma-buf FD on success. - * - * EINVAL: If @size is zero. - * EINVAL: If @die_index is greater than or equal to the number of dies in the - * device group. - * EINVAL: If the target device group is not finalized. - * ENODEV: If the on-device DRAM is not supported or failed on initialization. - */ -#define EDGETPU_ALLOCATE_DEVICE_BUFFER_COMPAT \ - _IOR(EDGETPU_IOCTL_BASE, 11, struct edgetpu_device_buffer_ioctl) - /* Unset event by event_id registered with EDGETPU_SET_EVENTFD. */ #define EDGETPU_UNSET_EVENT \ _IOW(EDGETPU_IOCTL_BASE, 14, __u32) |