Message ID | 20210714122954.71931-1-guangming.cao@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | dma-buf: support users to change dma_buf.name | expand |
Am 14.07.21 um 14:29 schrieb guangming.cao@mediatek.com: > From: Guangming Cao <Guangming.Cao@mediatek.com> > > User space user can call DMA_BUF_SET_NAME to set dma_buf.name, > also add a kernel api for users to do same thing at kernel side. Well if you want to add a kernel API to set the name you also need to provide an user for this. Christian. > > Signed-off-by: Guangming Cao <Guangming.Cao@mediatek.com> > --- > drivers/dma-buf/dma-buf.c | 28 ++++++++++++++++++++++------ > include/linux/dma-buf.h | 1 + > 2 files changed, 23 insertions(+), 6 deletions(-) > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > index 511fe0d217a0..949af232c644 100644 > --- a/drivers/dma-buf/dma-buf.c > +++ b/drivers/dma-buf/dma-buf.c > @@ -331,20 +331,20 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) > * purpose between different devices. > * > * @dmabuf: [in] dmabuf buffer that will be renamed. > - * @buf: [in] A piece of userspace memory that contains the name of > + * @buf: [in] A piece of memory that contains the name of > * the dma-buf. > * > * Returns 0 on success. If the dma-buf buffer is already attached to > * devices, return -EBUSY. > * > */ > -static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf) > +long dma_buf_set_name(struct dma_buf *dmabuf, const char *buf) > { > - char *name = strndup_user(buf, DMA_BUF_NAME_LEN); > + char *name = kstrndup(buf, DMA_BUF_NAME_LEN, GFP_KERNEL); > long ret = 0; > > - if (IS_ERR(name)) > - return PTR_ERR(name); > + if (!name) > + return -ENOMEM; > > dma_resv_lock(dmabuf->resv, NULL); > if (!list_empty(&dmabuf->attachments)) { > @@ -361,6 +361,22 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf) > dma_resv_unlock(dmabuf->resv); > return ret; > } > +EXPORT_SYMBOL_GPL(dma_buf_set_name); > + > +static long > +dma_buf_set_name_user(struct dma_buf *dmabuf, const char __user *buf) > +{ > + char *name = strndup_user(buf, DMA_BUF_NAME_LEN); > + long ret = 0; > + > + if (IS_ERR(name)) > + return PTR_ERR(name); > + > + ret = dma_buf_set_name(dmabuf, name); > + kfree(name); > + > + return ret; > +} > > static long dma_buf_ioctl(struct file *file, > unsigned int cmd, unsigned long arg) > @@ -403,7 +419,7 @@ static long dma_buf_ioctl(struct file *file, > > case DMA_BUF_SET_NAME_A: > case DMA_BUF_SET_NAME_B: > - return dma_buf_set_name(dmabuf, (const char __user *)arg); > + return dma_buf_set_name_user(dmabuf, (const char __user *)arg); > > default: > return -ENOTTY; > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > index efdc56b9d95f..e6612ab59a59 100644 > --- a/include/linux/dma-buf.h > +++ b/include/linux/dma-buf.h > @@ -507,4 +507,5 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, > unsigned long); > int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map); > void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map); > +long dma_buf_set_name(struct dma_buf *dmabuf, const char *name); > #endif /* __DMA_BUF_H__ */
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 511fe0d217a0..949af232c644 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -331,20 +331,20 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) * purpose between different devices. * * @dmabuf: [in] dmabuf buffer that will be renamed. - * @buf: [in] A piece of userspace memory that contains the name of + * @buf: [in] A piece of memory that contains the name of * the dma-buf. * * Returns 0 on success. If the dma-buf buffer is already attached to * devices, return -EBUSY. * */ -static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf) +long dma_buf_set_name(struct dma_buf *dmabuf, const char *buf) { - char *name = strndup_user(buf, DMA_BUF_NAME_LEN); + char *name = kstrndup(buf, DMA_BUF_NAME_LEN, GFP_KERNEL); long ret = 0; - if (IS_ERR(name)) - return PTR_ERR(name); + if (!name) + return -ENOMEM; dma_resv_lock(dmabuf->resv, NULL); if (!list_empty(&dmabuf->attachments)) { @@ -361,6 +361,22 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf) dma_resv_unlock(dmabuf->resv); return ret; } +EXPORT_SYMBOL_GPL(dma_buf_set_name); + +static long +dma_buf_set_name_user(struct dma_buf *dmabuf, const char __user *buf) +{ + char *name = strndup_user(buf, DMA_BUF_NAME_LEN); + long ret = 0; + + if (IS_ERR(name)) + return PTR_ERR(name); + + ret = dma_buf_set_name(dmabuf, name); + kfree(name); + + return ret; +} static long dma_buf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -403,7 +419,7 @@ static long dma_buf_ioctl(struct file *file, case DMA_BUF_SET_NAME_A: case DMA_BUF_SET_NAME_B: - return dma_buf_set_name(dmabuf, (const char __user *)arg); + return dma_buf_set_name_user(dmabuf, (const char __user *)arg); default: return -ENOTTY; diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index efdc56b9d95f..e6612ab59a59 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -507,4 +507,5 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map); void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map); +long dma_buf_set_name(struct dma_buf *dmabuf, const char *name); #endif /* __DMA_BUF_H__ */