Implement RPMSG_CREATE_EPT_FD_IOCTL, new uAPI for rpmsg ctrl, which
shares most of operations of RPMSG_CREATE_EPT_IOCTL except that it
returns fd representing eptdev to userspace directly.
Possible calling procedures for userspace are:
- fd = open("/dev/rpmsg_ctrlX")
- ioctl(fd, RPMSG_CREATE_EPT_FD_IOCTL, &info);
- fd_ep = info.fd
- operations on fd_ep(write, read, poll ioctl)
- ioctl(fd_ep, RPMSG_DESTROY_EPT_IOCTL)
- close(fd_ep)
- close(fd)
Signed-off-by: Dawei Li <dawei.li@linux.dev>
---
drivers/rpmsg/rpmsg_ctrl.c | 38 ++++++++++++++++++++++++++++++--------
include/uapi/linux/rpmsg.h | 24 ++++++++++++++++++++++++
2 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/drivers/rpmsg/rpmsg_ctrl.c b/drivers/rpmsg/rpmsg_ctrl.c
index 28f57945ccd9..9f2f118ceb7b 100644
--- a/drivers/rpmsg/rpmsg_ctrl.c
+++ b/drivers/rpmsg/rpmsg_ctrl.c
@@ -75,19 +75,32 @@ static long rpmsg_ctrldev_ioctl(struct file *fp, unsigned int cmd,
unsigned long arg)
{
struct rpmsg_ctrldev *ctrldev = fp->private_data;
+ struct rpmsg_endpoint_fd_info ept_fd_info;
void __user *argp = (void __user *)arg;
struct rpmsg_endpoint_info eptinfo;
struct rpmsg_channel_info chinfo;
struct rpmsg_device *rpdev;
int ret = 0;
-
- if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
- return -EFAULT;
-
- memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
- chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
- chinfo.src = eptinfo.src;
- chinfo.dst = eptinfo.dst;
+ int fd = -1;
+
+ if (cmd == RPMSG_CREATE_EPT_IOCTL || cmd == RPMSG_CREATE_DEV_IOCTL ||
+ cmd == RPMSG_RELEASE_DEV_IOCTL) {
+ if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
+ return -EFAULT;
+
+ memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
+ chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
+ chinfo.src = eptinfo.src;
+ chinfo.dst = eptinfo.dst;
+ } else if (cmd == RPMSG_CREATE_EPT_FD_IOCTL) {
+ if (copy_from_user(&ept_fd_info, argp, sizeof(ept_fd_info)))
+ return -EFAULT;
+
+ memcpy(chinfo.name, ept_fd_info.name, RPMSG_NAME_SIZE);
+ chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
+ chinfo.src = ept_fd_info.src;
+ chinfo.dst = ept_fd_info.dst;
+ }
mutex_lock(&ctrldev->ctrl_lock);
switch (cmd) {
@@ -110,6 +123,15 @@ static long rpmsg_ctrldev_ioctl(struct file *fp, unsigned int cmd,
chinfo.name, ret);
break;
+ case RPMSG_CREATE_EPT_FD_IOCTL:
+ ret = rpmsg_anonymous_eptdev_create(ctrldev->rpdev, &ctrldev->dev, chinfo,
+ ept_fd_info.flags, &fd);
+ if (!ret) {
+ ept_fd_info.fd = fd;
+ ret = copy_to_user(argp, &ept_fd_info, sizeof(ept_fd_info));
+ }
+ break;
+
default:
ret = -EINVAL;
}
diff --git a/include/uapi/linux/rpmsg.h b/include/uapi/linux/rpmsg.h
index f0c8da2b185b..e7057bd23577 100644
--- a/include/uapi/linux/rpmsg.h
+++ b/include/uapi/linux/rpmsg.h
@@ -53,4 +53,28 @@ struct rpmsg_endpoint_info {
*/
#define RPMSG_SET_INCOMING_FLOWCONTROL _IOR(0xb5, 0x6, int)
+/**
+ * struct rpmsg_endpoint_fd_info - endpoint & fd info representation
+ * @name: name of service
+ * @src: local address. To set to RPMSG_ADDR_ANY if not used.
+ * @dst: destination address. To set to RPMSG_ADDR_ANY if not used.
+ * @flags: file flags of endpoint device, valid flags:
+ * O_RDONLY/O_WRONLY/O_RDWR
+ * O_NONBLOCK
+ * O_CLOEXEC
+ * @fd: fd returned from driver
+ */
+struct rpmsg_endpoint_fd_info {
+ char name[32];
+ __u32 src;
+ __u32 dst;
+ __u32 flags;
+ __s32 fd;
+};
+
+/**
+ * Instantiate a new rmpsg endpoint which is represented by fd
+ */
+#define RPMSG_CREATE_EPT_FD_IOCTL _IOWR(0xb5, 0x7, struct rpmsg_endpoint_fd_info)
+
#endif
--
2.25.1
Hi Dawei,
On 19/05/25 20:38, Dawei Li wrote:
> Implement RPMSG_CREATE_EPT_FD_IOCTL, new uAPI for rpmsg ctrl, which
> shares most of operations of RPMSG_CREATE_EPT_IOCTL except that it
> returns fd representing eptdev to userspace directly.
>
> Possible calling procedures for userspace are:
> - fd = open("/dev/rpmsg_ctrlX")
> - ioctl(fd, RPMSG_CREATE_EPT_FD_IOCTL, &info);
> - fd_ep = info.fd
We are returning a new fd to userspace from inside an IOCTL itself. Is this a
standard way of doing things in Kernel space? (see below related comment)
> - operations on fd_ep(write, read, poll ioctl)
> - ioctl(fd_ep, RPMSG_DESTROY_EPT_IOCTL)
> - close(fd_ep)
Can we rely on the userspace to close() the fd_ep? (if not done, could be a
memory leak..).. Opposed to fd, which we can rely on the userspace to
close() since they initiated the open() call. I am just trying to understand if
this is a standard way of doing things...
> - close(fd)
>
> Signed-off-by: Dawei Li <dawei.li@linux.dev>
> ---
> drivers/rpmsg/rpmsg_ctrl.c | 38 ++++++++++++++++++++++++++++++--------
> include/uapi/linux/rpmsg.h | 24 ++++++++++++++++++++++++
> 2 files changed, 54 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/rpmsg/rpmsg_ctrl.c b/drivers/rpmsg/rpmsg_ctrl.c
> index 28f57945ccd9..9f2f118ceb7b 100644
> --- a/drivers/rpmsg/rpmsg_ctrl.c
> +++ b/drivers/rpmsg/rpmsg_ctrl.c
> @@ -75,19 +75,32 @@ static long rpmsg_ctrldev_ioctl(struct file *fp, unsigned int cmd,
> unsigned long arg)
> {
> struct rpmsg_ctrldev *ctrldev = fp->private_data;
> + struct rpmsg_endpoint_fd_info ept_fd_info;
> void __user *argp = (void __user *)arg;
> struct rpmsg_endpoint_info eptinfo;
> struct rpmsg_channel_info chinfo;
> struct rpmsg_device *rpdev;
> int ret = 0;
> -
> - if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
> - return -EFAULT;
> -
> - memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
> - chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
> - chinfo.src = eptinfo.src;
> - chinfo.dst = eptinfo.dst;
> + int fd = -1;
> +
> + if (cmd == RPMSG_CREATE_EPT_IOCTL || cmd == RPMSG_CREATE_DEV_IOCTL ||
> + cmd == RPMSG_RELEASE_DEV_IOCTL) {
> + if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
> + return -EFAULT;
> +
> + memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
> + chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
> + chinfo.src = eptinfo.src;
> + chinfo.dst = eptinfo.dst;
> + } else if (cmd == RPMSG_CREATE_EPT_FD_IOCTL) {
Maybe we can put this 'else if condition' in the first 'if' and treat other
conditions under 'else', as 'RPMSG_CREATE_EPT_FD_IOCTL' is the only
ioctl with a different struct type.
Thanks,
Beleswar
> + if (copy_from_user(&ept_fd_info, argp, sizeof(ept_fd_info)))
> + return -EFAULT;
> +
> + memcpy(chinfo.name, ept_fd_info.name, RPMSG_NAME_SIZE);
> + chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
> + chinfo.src = ept_fd_info.src;
> + chinfo.dst = ept_fd_info.dst;
> + }
>
> mutex_lock(&ctrldev->ctrl_lock);
> switch (cmd) {
> @@ -110,6 +123,15 @@ static long rpmsg_ctrldev_ioctl(struct file *fp, unsigned int cmd,
> chinfo.name, ret);
> break;
>
> + case RPMSG_CREATE_EPT_FD_IOCTL:
> + ret = rpmsg_anonymous_eptdev_create(ctrldev->rpdev, &ctrldev->dev, chinfo,
> + ept_fd_info.flags, &fd);
> + if (!ret) {
> + ept_fd_info.fd = fd;
> + ret = copy_to_user(argp, &ept_fd_info, sizeof(ept_fd_info));
> + }
> + break;
> +
> default:
> ret = -EINVAL;
> }
> diff --git a/include/uapi/linux/rpmsg.h b/include/uapi/linux/rpmsg.h
> index f0c8da2b185b..e7057bd23577 100644
> --- a/include/uapi/linux/rpmsg.h
> +++ b/include/uapi/linux/rpmsg.h
> @@ -53,4 +53,28 @@ struct rpmsg_endpoint_info {
> */
> #define RPMSG_SET_INCOMING_FLOWCONTROL _IOR(0xb5, 0x6, int)
>
> +/**
> + * struct rpmsg_endpoint_fd_info - endpoint & fd info representation
> + * @name: name of service
> + * @src: local address. To set to RPMSG_ADDR_ANY if not used.
> + * @dst: destination address. To set to RPMSG_ADDR_ANY if not used.
> + * @flags: file flags of endpoint device, valid flags:
> + * O_RDONLY/O_WRONLY/O_RDWR
> + * O_NONBLOCK
> + * O_CLOEXEC
> + * @fd: fd returned from driver
> + */
> +struct rpmsg_endpoint_fd_info {
> + char name[32];
> + __u32 src;
> + __u32 dst;
> + __u32 flags;
> + __s32 fd;
> +};
> +
> +/**
> + * Instantiate a new rmpsg endpoint which is represented by fd
> + */
> +#define RPMSG_CREATE_EPT_FD_IOCTL _IOWR(0xb5, 0x7, struct rpmsg_endpoint_fd_info)
> +
> #endif
HI Beleswar,
Thanks for reviewing.
On Fri, May 30, 2025 at 03:15:28PM +0530, Beleswar Prasad Padhi wrote:
> Hi Dawei,
>
> On 19/05/25 20:38, Dawei Li wrote:
> > Implement RPMSG_CREATE_EPT_FD_IOCTL, new uAPI for rpmsg ctrl, which
> > shares most of operations of RPMSG_CREATE_EPT_IOCTL except that it
> > returns fd representing eptdev to userspace directly.
> >
> > Possible calling procedures for userspace are:
> > - fd = open("/dev/rpmsg_ctrlX")
> > - ioctl(fd, RPMSG_CREATE_EPT_FD_IOCTL, &info);
> > - fd_ep = info.fd
>
>
> We are returning a new fd to userspace from inside an IOCTL itself. Is this a
> standard way of doing things in Kernel space? (see below related comment)
Yes, anon_get_{fd,file} are used extensively in kernel for returning a new
fd to userspace which is associated with an unique data structure in kernel
space, in different ways:
- via ioctl(), some examples are:
- KVM ioctl(s)
- KVM_CREATE_VCPU -> kvm_vm_ioctl_create_vcpu
- KVM_GET_STATS_FD -> kvm_vcpu_ioctl_get_stats_fd
- KVM_CREATE_DEVICE -> kvm_ioctl_create_device
- KVM_CREATE_VM -> kvm_dev_ioctl_create_vm
- DMA buf/fence/sync ioctls
- DMA_BUF_IOCTL_EXPORT_SYNC_FILE -> dma_buf_export_sync_file
- SW_SYNC_IOC_CREATE_FENCE -> sw_sync_ioctl_create_fence
- Couples of driver implement DMA buf by using anon file _implicitly_:
- UDMABUF_CREATE -> udmabuf_ioctl_create
- DMA_HEAP_IOCTL_ALLOC -> dma_heap_ioctl_allocate
- gpiolib ioctls:
- GPIO_GET_LINEHANDLE_IOCTL -> linehandle_create
- GPIO_V2_GET_LINE_IOCTL
- IOMMUFD ioctls:
- VFIO Ioctls:
- ....
- via other specific syscalls:
- epoll_create1
- bpf
- perf_event_open
- inotify_init
- ...
>
> > - operations on fd_ep(write, read, poll ioctl)
> > - ioctl(fd_ep, RPMSG_DESTROY_EPT_IOCTL)
> > - close(fd_ep)
>
>
> Can we rely on the userspace to close() the fd_ep? (if not done, could be a
> memory leak..).. Opposed to fd, which we can rely on the userspace to
> close() since they initiated the open() call. I am just trying to understand if
> this is a standard way of doing things...
Good question.
When userland gets a fd from kernel, it's userland's duty to manage and release
the resource when it's done with it, because kernel never knows when the fd and
its resourcen are not needed by userland except process is on exiting. The fact
remains true no matter how fd is generated from kernel:
- open()
- ioctl()
- Other syscalls(epoll_create1, e.g, as listed above)
As a result, kernel & driver provide fops->release() to achieve resource
release when fd is not needed for userland, some callers of it maybe:
- Userland call close() explicitly
- Kernel does the dirty job when user process exits(if some fds are
still opened):
- Userland call exit() explicitly.
- User process was killed by some signals.
Maybe some comments/docs are needed in uAPI?
>
> > - close(fd)
> >
[snip]
> > +
> > + if (cmd == RPMSG_CREATE_EPT_IOCTL || cmd == RPMSG_CREATE_DEV_IOCTL ||
> > + cmd == RPMSG_RELEASE_DEV_IOCTL) {
> > + if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
> > + return -EFAULT;
> > +
> > + memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
> > + chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
> > + chinfo.src = eptinfo.src;
> > + chinfo.dst = eptinfo.dst;
> > + } else if (cmd == RPMSG_CREATE_EPT_FD_IOCTL) {
>
>
> Maybe we can put this 'else if condition' in the first 'if' and treat other
> conditions under 'else', as 'RPMSG_CREATE_EPT_FD_IOCTL' is the only
> ioctl with a different struct type.
Good point! I will try to address it in next respin.
>
> Thanks,
> Beleswar
>
> > + if (copy_from_user(&ept_fd_info, argp, sizeof(ept_fd_info)))
> > + return -EFAULT;
> > +
> > + memcpy(chinfo.name, ept_fd_info.name, RPMSG_NAME_SIZE);
> > + chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
> > + chinfo.src = ept_fd_info.src;
> > + chinfo.dst = ept_fd_info.dst;
> > + }
> >
[snip]
Thanks,
Dawei
Hi Dawei,
On 30/05/25 18:20, Dawei Li wrote:
> HI Beleswar,
>
> Thanks for reviewing.
>
> On Fri, May 30, 2025 at 03:15:28PM +0530, Beleswar Prasad Padhi wrote:
>> Hi Dawei,
>>
>> On 19/05/25 20:38, Dawei Li wrote:
>>> Implement RPMSG_CREATE_EPT_FD_IOCTL, new uAPI for rpmsg ctrl, which
>>> shares most of operations of RPMSG_CREATE_EPT_IOCTL except that it
>>> returns fd representing eptdev to userspace directly.
>>>
>>> Possible calling procedures for userspace are:
>>> - fd = open("/dev/rpmsg_ctrlX")
>>> - ioctl(fd, RPMSG_CREATE_EPT_FD_IOCTL, &info);
>>> - fd_ep = info.fd
>>
>> We are returning a new fd to userspace from inside an IOCTL itself. Is this a
>> standard way of doing things in Kernel space? (see below related comment)
> Yes, anon_get_{fd,file} are used extensively in kernel for returning a new
> fd to userspace which is associated with an unique data structure in kernel
> space, in different ways:
>
> - via ioctl(), some examples are:
>
> - KVM ioctl(s)
> - KVM_CREATE_VCPU -> kvm_vm_ioctl_create_vcpu
> - KVM_GET_STATS_FD -> kvm_vcpu_ioctl_get_stats_fd
> - KVM_CREATE_DEVICE -> kvm_ioctl_create_device
> - KVM_CREATE_VM -> kvm_dev_ioctl_create_vm
>
> - DMA buf/fence/sync ioctls
> - DMA_BUF_IOCTL_EXPORT_SYNC_FILE -> dma_buf_export_sync_file
> - SW_SYNC_IOC_CREATE_FENCE -> sw_sync_ioctl_create_fence
> - Couples of driver implement DMA buf by using anon file _implicitly_:
> - UDMABUF_CREATE -> udmabuf_ioctl_create
> - DMA_HEAP_IOCTL_ALLOC -> dma_heap_ioctl_allocate
>
> - gpiolib ioctls:
> - GPIO_GET_LINEHANDLE_IOCTL -> linehandle_create
> - GPIO_V2_GET_LINE_IOCTL
>
> - IOMMUFD ioctls:
>
> - VFIO Ioctls:
>
> - ....
>
>
> - via other specific syscalls:
> - epoll_create1
> - bpf
> - perf_event_open
> - inotify_init
> - ...
Thank you for the extensive list of examples!
>
>>> - operations on fd_ep(write, read, poll ioctl)
>>> - ioctl(fd_ep, RPMSG_DESTROY_EPT_IOCTL)
>>> - close(fd_ep)
>>
>> Can we rely on the userspace to close() the fd_ep? (if not done, could be a
>> memory leak..).. Opposed to fd, which we can rely on the userspace to
>> close() since they initiated the open() call. I am just trying to understand if
>> this is a standard way of doing things...
> Good question.
>
> When userland gets a fd from kernel, it's userland's duty to manage and release
> the resource when it's done with it, because kernel never knows when the fd and
> its resourcen are not needed by userland except process is on exiting. The fact
> remains true no matter how fd is generated from kernel:
> - open()
> - ioctl()
> - Other syscalls(epoll_create1, e.g, as listed above)
>
> As a result, kernel & driver provide fops->release() to achieve resource
> release when fd is not needed for userland, some callers of it maybe:
> - Userland call close() explicitly
> - Kernel does the dirty job when user process exits(if some fds are
> still opened):
> - Userland call exit() explicitly.
> - User process was killed by some signals.
>
> Maybe some comments/docs are needed in uAPI?
Perhaps yes. It makes sense to me now. Thanks for addressing my queries!
>
>>> - close(fd)
>>>
> [snip]
>
>>> +
>>> + if (cmd == RPMSG_CREATE_EPT_IOCTL || cmd == RPMSG_CREATE_DEV_IOCTL ||
>>> + cmd == RPMSG_RELEASE_DEV_IOCTL) {
>>> + if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
>>> + return -EFAULT;
>>> +
>>> + memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
>>> + chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
>>> + chinfo.src = eptinfo.src;
>>> + chinfo.dst = eptinfo.dst;
>>> + } else if (cmd == RPMSG_CREATE_EPT_FD_IOCTL) {
>>
>> Maybe we can put this 'else if condition' in the first 'if' and treat other
>> conditions under 'else', as 'RPMSG_CREATE_EPT_FD_IOCTL' is the only
>> ioctl with a different struct type.
> Good point! I will try to address it in next respin.
Thanks,
Beleswar
>
>> Thanks,
>> Beleswar
>>
>>> + if (copy_from_user(&ept_fd_info, argp, sizeof(ept_fd_info)))
>>> + return -EFAULT;
>>> +
>>> + memcpy(chinfo.name, ept_fd_info.name, RPMSG_NAME_SIZE);
>>> + chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
>>> + chinfo.src = ept_fd_info.src;
>>> + chinfo.dst = ept_fd_info.dst;
>>> + }
>>>
> [snip]
>
> Thanks,
>
> Dawei
Hi Dawei,
kernel test robot noticed the following build warnings:
url: https://github.com/intel-lab-lkp/linux/commits/Dawei-Li/rpmsg-char-Reuse-eptdev-logic-for-anonymous-device/20250519-231006
base: 92a09c47464d040866cf2b4cd052bc60555185fb
patch link: https://lore.kernel.org/r/20250519150823.62350-4-dawei.li%40linux.dev
patch subject: [PATCH v3 3/3] rpmsg: ctrl: Introduce RPMSG_CREATE_EPT_FD_IOCTL uAPI
config: powerpc64-randconfig-r072-20250521 (https://download.01.org/0day-ci/archive/20250521/202505211038.sqqVX8kO-lkp@intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202505211038.sqqVX8kO-lkp@intel.com/
smatch warnings:
drivers/rpmsg/rpmsg_ctrl.c:140 rpmsg_ctrldev_ioctl() warn: maybe return -EFAULT instead of the bytes remaining?
vim +140 drivers/rpmsg/rpmsg_ctrl.c
617d32938d1be0 Arnaud Pouliquen 2022-01-24 74 static long rpmsg_ctrldev_ioctl(struct file *fp, unsigned int cmd,
617d32938d1be0 Arnaud Pouliquen 2022-01-24 75 unsigned long arg)
617d32938d1be0 Arnaud Pouliquen 2022-01-24 76 {
617d32938d1be0 Arnaud Pouliquen 2022-01-24 77 struct rpmsg_ctrldev *ctrldev = fp->private_data;
74317ea5240801 Dawei Li 2025-05-19 78 struct rpmsg_endpoint_fd_info ept_fd_info;
617d32938d1be0 Arnaud Pouliquen 2022-01-24 79 void __user *argp = (void __user *)arg;
617d32938d1be0 Arnaud Pouliquen 2022-01-24 80 struct rpmsg_endpoint_info eptinfo;
617d32938d1be0 Arnaud Pouliquen 2022-01-24 81 struct rpmsg_channel_info chinfo;
8109517b394e6d Arnaud Pouliquen 2022-01-24 82 struct rpmsg_device *rpdev;
8109517b394e6d Arnaud Pouliquen 2022-01-24 83 int ret = 0;
74317ea5240801 Dawei Li 2025-05-19 84 int fd = -1;
617d32938d1be0 Arnaud Pouliquen 2022-01-24 85
74317ea5240801 Dawei Li 2025-05-19 86 if (cmd == RPMSG_CREATE_EPT_IOCTL || cmd == RPMSG_CREATE_DEV_IOCTL ||
74317ea5240801 Dawei Li 2025-05-19 87 cmd == RPMSG_RELEASE_DEV_IOCTL) {
617d32938d1be0 Arnaud Pouliquen 2022-01-24 88 if (copy_from_user(&eptinfo, argp, sizeof(eptinfo)))
617d32938d1be0 Arnaud Pouliquen 2022-01-24 89 return -EFAULT;
617d32938d1be0 Arnaud Pouliquen 2022-01-24 90
617d32938d1be0 Arnaud Pouliquen 2022-01-24 91 memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE);
617d32938d1be0 Arnaud Pouliquen 2022-01-24 92 chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
617d32938d1be0 Arnaud Pouliquen 2022-01-24 93 chinfo.src = eptinfo.src;
617d32938d1be0 Arnaud Pouliquen 2022-01-24 94 chinfo.dst = eptinfo.dst;
74317ea5240801 Dawei Li 2025-05-19 95 } else if (cmd == RPMSG_CREATE_EPT_FD_IOCTL) {
74317ea5240801 Dawei Li 2025-05-19 96 if (copy_from_user(&ept_fd_info, argp, sizeof(ept_fd_info)))
74317ea5240801 Dawei Li 2025-05-19 97 return -EFAULT;
74317ea5240801 Dawei Li 2025-05-19 98
74317ea5240801 Dawei Li 2025-05-19 99 memcpy(chinfo.name, ept_fd_info.name, RPMSG_NAME_SIZE);
74317ea5240801 Dawei Li 2025-05-19 100 chinfo.name[RPMSG_NAME_SIZE - 1] = '\0';
74317ea5240801 Dawei Li 2025-05-19 101 chinfo.src = ept_fd_info.src;
74317ea5240801 Dawei Li 2025-05-19 102 chinfo.dst = ept_fd_info.dst;
74317ea5240801 Dawei Li 2025-05-19 103 }
617d32938d1be0 Arnaud Pouliquen 2022-01-24 104
8109517b394e6d Arnaud Pouliquen 2022-01-24 105 mutex_lock(&ctrldev->ctrl_lock);
8109517b394e6d Arnaud Pouliquen 2022-01-24 106 switch (cmd) {
8109517b394e6d Arnaud Pouliquen 2022-01-24 107 case RPMSG_CREATE_EPT_IOCTL:
8109517b394e6d Arnaud Pouliquen 2022-01-24 108 ret = rpmsg_chrdev_eptdev_create(ctrldev->rpdev, &ctrldev->dev, chinfo);
8109517b394e6d Arnaud Pouliquen 2022-01-24 109 break;
8109517b394e6d Arnaud Pouliquen 2022-01-24 110
8109517b394e6d Arnaud Pouliquen 2022-01-24 111 case RPMSG_CREATE_DEV_IOCTL:
8109517b394e6d Arnaud Pouliquen 2022-01-24 112 rpdev = rpmsg_create_channel(ctrldev->rpdev, &chinfo);
8109517b394e6d Arnaud Pouliquen 2022-01-24 113 if (!rpdev) {
8109517b394e6d Arnaud Pouliquen 2022-01-24 114 dev_err(&ctrldev->dev, "failed to create %s channel\n", chinfo.name);
8109517b394e6d Arnaud Pouliquen 2022-01-24 115 ret = -ENXIO;
8109517b394e6d Arnaud Pouliquen 2022-01-24 116 }
8109517b394e6d Arnaud Pouliquen 2022-01-24 117 break;
8109517b394e6d Arnaud Pouliquen 2022-01-24 118
8109517b394e6d Arnaud Pouliquen 2022-01-24 119 case RPMSG_RELEASE_DEV_IOCTL:
8109517b394e6d Arnaud Pouliquen 2022-01-24 120 ret = rpmsg_release_channel(ctrldev->rpdev, &chinfo);
8109517b394e6d Arnaud Pouliquen 2022-01-24 121 if (ret)
8109517b394e6d Arnaud Pouliquen 2022-01-24 122 dev_err(&ctrldev->dev, "failed to release %s channel (%d)\n",
8109517b394e6d Arnaud Pouliquen 2022-01-24 123 chinfo.name, ret);
8109517b394e6d Arnaud Pouliquen 2022-01-24 124 break;
8109517b394e6d Arnaud Pouliquen 2022-01-24 125
74317ea5240801 Dawei Li 2025-05-19 126 case RPMSG_CREATE_EPT_FD_IOCTL:
74317ea5240801 Dawei Li 2025-05-19 127 ret = rpmsg_anonymous_eptdev_create(ctrldev->rpdev, &ctrldev->dev, chinfo,
74317ea5240801 Dawei Li 2025-05-19 128 ept_fd_info.flags, &fd);
74317ea5240801 Dawei Li 2025-05-19 129 if (!ret) {
You should flip this around. if (ret)
break;
74317ea5240801 Dawei Li 2025-05-19 130 ept_fd_info.fd = fd;
74317ea5240801 Dawei Li 2025-05-19 131 ret = copy_to_user(argp, &ept_fd_info, sizeof(ept_fd_info));
This should be:
if (copy_to_user(argp, &ept_fd_info, sizeof(ept_fd_info)))
ret = -EFAULT;
74317ea5240801 Dawei Li 2025-05-19 132 }
74317ea5240801 Dawei Li 2025-05-19 133 break;
74317ea5240801 Dawei Li 2025-05-19 134
8109517b394e6d Arnaud Pouliquen 2022-01-24 135 default:
8109517b394e6d Arnaud Pouliquen 2022-01-24 136 ret = -EINVAL;
8109517b394e6d Arnaud Pouliquen 2022-01-24 137 }
8109517b394e6d Arnaud Pouliquen 2022-01-24 138 mutex_unlock(&ctrldev->ctrl_lock);
8109517b394e6d Arnaud Pouliquen 2022-01-24 139
8109517b394e6d Arnaud Pouliquen 2022-01-24 @140 return ret;
617d32938d1be0 Arnaud Pouliquen 2022-01-24 141 };
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2025 Red Hat, Inc.