diff options
author | Ge Bian <bian@google.com> | 2021-07-15 13:09:03 -0700 |
---|---|---|
committer | Ge Bian <bian@google.com> | 2021-07-16 00:45:31 -0700 |
commit | b768cd230e08fe2628f9855e2a21dfa47222e2ad (patch) | |
tree | 972a007ab6c44d30c848c25e2b59edb8b0f2accd /lwis_device_slc.c | |
parent | 87f5606036547cce6f571997cf73f388ab3c398a (diff) | |
download | lwis-b768cd230e08fe2628f9855e2a21dfa47222e2ad.tar.gz |
LWIS: Free SLC partition only if the fd matches.
Bug: 186183144
Test: build, boot, manual test, CTS pass.
Change-Id: Ib9847b1746889e1b31674f36c376b41966fd5ee0
Signed-off-by: Ge Bian <bian@google.com>
Diffstat (limited to 'lwis_device_slc.c')
-rw-r--r-- | lwis_device_slc.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/lwis_device_slc.c b/lwis_device_slc.c index d5f542d..f1b58fe 100644 --- a/lwis_device_slc.c +++ b/lwis_device_slc.c @@ -103,6 +103,7 @@ static int lwis_slc_enable(struct lwis_device *lwis_dev) for (i = 0; i < slc_dev->num_pt; i++) { slc_dev->pt[i].id = i; slc_dev->pt[i].size_kb = pt_size_kb[i]; + slc_dev->pt[i].fd = -1; slc_dev->pt[i].partition_id = PT_PTID_INVALID; slc_dev->pt[i].partition_handle = slc_dev->partition_handle; } @@ -132,6 +133,7 @@ static int lwis_slc_disable(struct lwis_device *lwis_dev) "Closing partition id %d at device shutdown", slc_dev->pt[i].id); pt_client_disable(slc_dev->partition_handle, slc_dev->pt[i].id); slc_dev->pt[i].partition_id = PT_PTID_INVALID; + slc_dev->pt[i].fd = -1; } } pt_client_unregister(slc_dev->partition_handle); @@ -142,6 +144,7 @@ int lwis_slc_buffer_alloc(struct lwis_device *lwis_dev, struct lwis_alloc_buffer { struct lwis_slc_device *slc_dev = (struct lwis_slc_device *)lwis_dev; int i = 0, fd_or_err = -1; + ptid_t partition_id = PT_PTID_INVALID; if (!lwis_dev) { pr_err("LWIS device cannot be NULL\n"); @@ -166,9 +169,9 @@ int lwis_slc_buffer_alloc(struct lwis_device *lwis_dev, struct lwis_alloc_buffer for (i = 0; i < slc_dev->num_pt; i++) { if (slc_dev->pt[i].partition_id == PT_PTID_INVALID && slc_dev->pt[i].size_kb >= SIZE_TO_KB(alloc_info->size)) { - slc_dev->pt[i].partition_id = + partition_id = pt_client_enable(slc_dev->partition_handle, slc_dev->pt[i].id); - if (slc_dev->pt[i].partition_id != PT_PTID_INVALID) { + if (partition_id != PT_PTID_INVALID) { fd_or_err = anon_inode_getfd("slc_pt_file", &pt_file_ops, &slc_dev->pt[i], O_CLOEXEC); if (fd_or_err < 0) { @@ -176,11 +179,12 @@ int lwis_slc_buffer_alloc(struct lwis_device *lwis_dev, struct lwis_alloc_buffer "Failed to create a new file instance for the partition\n"); return fd_or_err; } + slc_dev->pt[i].fd = fd_or_err; + slc_dev->pt[i].partition_id = partition_id; alloc_info->dma_fd = fd_or_err; alloc_info->partition_id = slc_dev->pt[i].partition_id; return 0; } else { - slc_dev->pt[i].partition_id = PT_PTID_INVALID; dev_err(lwis_dev->dev, "Failed to enable partition id %d\n", slc_dev->pt[i].id); return -EPROTO; @@ -213,9 +217,17 @@ int lwis_slc_buffer_free(struct lwis_device *lwis_dev, int fd) return -EBADF; } slc_pt = fp->private_data; + + if (slc_pt->fd != fd) { + dev_warn(lwis_dev->dev, "Stale SLC buffer free for fd %d with ptid %d\n", fd, + slc_pt->partition_id); + return -EINVAL; + } + if (slc_pt->partition_id != PT_PTID_INVALID && slc_pt->partition_handle) { pt_client_disable(slc_pt->partition_handle, slc_pt->id); slc_pt->partition_id = PT_PTID_INVALID; + slc_pt->fd = -1; } fput(fp); |