summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNrithya Kanakasabapathy <nrithya@google.com>2021-03-25 05:35:57 +0000
committerNrithya Kanakasabapathy <nrithya@google.com>2021-03-25 05:38:03 +0000
commit2be4b1e51a13039aed1f3b9b2544f75d2df2ea6b (patch)
tree8c1b6f0313cb71643adda9cb642e033b30bff72f
parentd034701c6f09fb30bcaefdd750b60eed70752d7e (diff)
downloadabrolhos-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.c13
-rw-r--r--drivers/edgetpu/edgetpu-device-group.c10
-rw-r--r--drivers/edgetpu/edgetpu-dmabuf.c29
-rw-r--r--drivers/edgetpu/edgetpu-fs.c34
-rw-r--r--drivers/edgetpu/edgetpu-mmu.h4
-rw-r--r--drivers/edgetpu/edgetpu.h29
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)