From nobody Sun Dec 14 21:49:39 2025 Received: from out-179.mta1.migadu.com (out-179.mta1.migadu.com [95.215.58.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A75F31DE8AF for ; Wed, 15 Oct 2025 15:18:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760541538; cv=none; b=MWYxu9n19NImkL3w+50xqqENOPwMin8snsvguTqPIXEULUl2PbBuEsljfqIl9rdXLwpvpI0GlFJgnZxFm0Iiuu/iSU7je+/styPJVUQ9Ys38APsqPmsyTq0Rg/EMotZ33SavM9lUM4g9bhrJcXMe1+nt22HWKohNxtaA0tBhL+c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760541538; c=relaxed/simple; bh=DlyQcWUqmoBEjGqsD6SDjZ8Iydua2QTKihAMWrnvlk0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=I9Moqgyh2yftFLAIjgBxVslgU+QTGsgQWNJAIiDXahIERlFSYrff/hcviR5Bm9b2JU9RU5TviXRq9UQND6geN295sUlskEtUr4rS0BebJZd6QwEyeRAii670QIKLCv9TtyURrUvimus52sD2uYw80fzJ9rOAxlTDGykR/ivKzBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=FFzzh2ap; arc=none smtp.client-ip=95.215.58.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="FFzzh2ap" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1760541533; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nyViFsVshW4RvH6wpA3CONDC16GQKDJiDzwgrJuApCk=; b=FFzzh2apewnKPs9W7AmStTSk31uasd29GYRLGjET8VmEEaEHzqo7CsZJvtikgyrQgs9Y0O XU5Y6bnouiwVW1TDyOOTH0j9xaysUBxi9gu5+NwTZV9o0y8IZfhTxHybl2pzb5il1TjvI/ owMZo3ftfRXG9/WeTFbViEa5y7EY344= From: Dawei Li To: andersson@kernel.org, mathieu.poirier@linaro.org Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, dawei.li@linux.dev, set_pte_at@outlook.com Subject: [PATCH v5 1/3] rpmsg: char: Reuse eptdev logic for anonymous device Date: Wed, 15 Oct 2025 23:17:16 +0800 Message-Id: <20251015151718.3927-2-dawei.li@linux.dev> In-Reply-To: <20251015151718.3927-1-dawei.li@linux.dev> References: <20251015151718.3927-1-dawei.li@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Current uAPI implementation for rpmsg ctrl & char device manipulation is abstracted in procedures below: - fd =3D open("/dev/rpmsg_ctrlX") - ioctl(fd, RPMSG_CREATE_EPT_IOCTL, &info); /dev/rpmsgY devnode is generated. - fd_ep =3D open("/dev/rpmsgY", O_RDWR) - operations on fd_ep(write, read, poll ioctl) - ioctl(fd_ep, RPMSG_DESTROY_EPT_IOCTL) - close(fd_ep) - close(fd) This /dev/rpmsgY abstraction is less favorable for: - Performance issue: It's time consuming for some operations are involved: - Device node creation. Depends on specific config, especially CONFIG_DEVTMPFS, the overall overhead is based on coordination between DEVTMPFS and userspace tools such as udev and mdev. - Extra kernel-userspace switch cost. - Other major costs brought by heavy-weight logic like device_add(). - /dev/rpmsgY node can be opened only once. It doesn't make much sense that a dynamically created device node can be opened only once. - For some container application such as docker, a client can't access host's device node unless specified explicitly. But in case of /dev/rpmsgY, which is generated dynamically and whose existence is unknown for clients in advance, this uAPI based on device node doesn't fit well. An anonymous inode based approach is introduced to address the issues above. Rather than generating device node and opening it, rpmsg code just creates an anonymous inode representing eptdev and return the fd to userspace. The legacy abstraction based on struct device and struct cdev is honored: - Avoid legacy uAPI break(RPMSG_CREATE_EPT_IOCTL) - Reuse existing logic: - dev_err() and friends. - Life cycle management of struct device. Signed-off-by: Dawei Li --- drivers/rpmsg/rpmsg_char.c | 80 ++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c index 96fcdd2d7093..85154a422e9d 100644 --- a/drivers/rpmsg/rpmsg_char.c +++ b/drivers/rpmsg/rpmsg_char.c @@ -91,7 +91,8 @@ int rpmsg_chrdev_eptdev_destroy(struct device *dev, void = *data) /* wake up any blocked readers */ wake_up_interruptible(&eptdev->readq); =20 - cdev_device_del(&eptdev->cdev, &eptdev->dev); + if (eptdev->dev.devt) + cdev_device_del(&eptdev->cdev, &eptdev->dev); put_device(&eptdev->dev); =20 return 0; @@ -132,21 +133,17 @@ static int rpmsg_ept_flow_cb(struct rpmsg_device *rpd= ev, void *priv, bool enable return 0; } =20 -static int rpmsg_eptdev_open(struct inode *inode, struct file *filp) +static int __rpmsg_eptdev_open(struct rpmsg_eptdev *eptdev) { - struct rpmsg_eptdev *eptdev =3D cdev_to_eptdev(inode->i_cdev); struct rpmsg_endpoint *ept; struct rpmsg_device *rpdev =3D eptdev->rpdev; struct device *dev =3D &eptdev->dev; =20 - mutex_lock(&eptdev->ept_lock); if (eptdev->ept) { - mutex_unlock(&eptdev->ept_lock); return -EBUSY; } =20 if (!eptdev->rpdev) { - mutex_unlock(&eptdev->ept_lock); return -ENETRESET; } =20 @@ -164,21 +161,32 @@ static int rpmsg_eptdev_open(struct inode *inode, str= uct file *filp) if (!ept) { dev_err(dev, "failed to open %s\n", eptdev->chinfo.name); put_device(dev); - mutex_unlock(&eptdev->ept_lock); return -EINVAL; } =20 ept->flow_cb =3D rpmsg_ept_flow_cb; eptdev->ept =3D ept; - filp->private_data =3D eptdev; - mutex_unlock(&eptdev->ept_lock); =20 return 0; } =20 -static int rpmsg_eptdev_release(struct inode *inode, struct file *filp) +static int rpmsg_eptdev_open(struct inode *inode, struct file *filp) { struct rpmsg_eptdev *eptdev =3D cdev_to_eptdev(inode->i_cdev); + int ret; + + mutex_lock(&eptdev->ept_lock); + ret =3D __rpmsg_eptdev_open(eptdev); + if (!ret) + filp->private_data =3D eptdev; + mutex_unlock(&eptdev->ept_lock); + + return ret; +} + +static int rpmsg_eptdev_release(struct inode *inode, struct file *filp) +{ + struct rpmsg_eptdev *eptdev =3D filp->private_data; struct device *dev =3D &eptdev->dev; =20 /* Close the endpoint, if it's not already destroyed by the parent */ @@ -400,12 +408,13 @@ static void rpmsg_eptdev_release_device(struct device= *dev) struct rpmsg_eptdev *eptdev =3D dev_to_eptdev(dev); =20 ida_free(&rpmsg_ept_ida, dev->id); - ida_free(&rpmsg_minor_ida, MINOR(eptdev->dev.devt)); + if (eptdev->dev.devt) + ida_free(&rpmsg_minor_ida, MINOR(eptdev->dev.devt)); kfree(eptdev); } =20 -static struct rpmsg_eptdev *rpmsg_chrdev_eptdev_alloc(struct rpmsg_device = *rpdev, - struct device *parent) +static struct rpmsg_eptdev *rpmsg_eptdev_alloc(struct rpmsg_device *rpdev, + struct device *parent, bool cdev) { struct rpmsg_eptdev *eptdev; struct device *dev; @@ -428,33 +437,50 @@ static struct rpmsg_eptdev *rpmsg_chrdev_eptdev_alloc= (struct rpmsg_device *rpdev dev->groups =3D rpmsg_eptdev_groups; dev_set_drvdata(dev, eptdev); =20 - cdev_init(&eptdev->cdev, &rpmsg_eptdev_fops); - eptdev->cdev.owner =3D THIS_MODULE; + if (cdev) { + cdev_init(&eptdev->cdev, &rpmsg_eptdev_fops); + eptdev->cdev.owner =3D THIS_MODULE; + } =20 return eptdev; } =20 -static int rpmsg_chrdev_eptdev_add(struct rpmsg_eptdev *eptdev, struct rpm= sg_channel_info chinfo) +static struct rpmsg_eptdev *rpmsg_chrdev_eptdev_alloc(struct rpmsg_device = *rpdev, + struct device *parent) +{ + return rpmsg_eptdev_alloc(rpdev, parent, true); +} + +static int rpmsg_eptdev_add(struct rpmsg_eptdev *eptdev, + struct rpmsg_channel_info chinfo, bool cdev) { struct device *dev =3D &eptdev->dev; int ret; =20 eptdev->chinfo =3D chinfo; =20 - ret =3D ida_alloc_max(&rpmsg_minor_ida, RPMSG_DEV_MAX - 1, GFP_KERNEL); - if (ret < 0) - goto free_eptdev; - dev->devt =3D MKDEV(MAJOR(rpmsg_major), ret); + if (cdev) { + ret =3D ida_alloc_max(&rpmsg_minor_ida, RPMSG_DEV_MAX - 1, GFP_KERNEL); + if (ret < 0) + goto free_eptdev; =20 + dev->devt =3D MKDEV(MAJOR(rpmsg_major), ret); + } + + /* Anonymous inode device still need device name for dev_err() and friend= s */ ret =3D ida_alloc(&rpmsg_ept_ida, GFP_KERNEL); if (ret < 0) goto free_minor_ida; dev->id =3D ret; dev_set_name(dev, "rpmsg%d", ret); =20 - ret =3D cdev_device_add(&eptdev->cdev, &eptdev->dev); - if (ret) - goto free_ept_ida; + ret =3D 0; + + if (cdev) { + ret =3D cdev_device_add(&eptdev->cdev, &eptdev->dev); + if (ret) + goto free_ept_ida; + } =20 /* We can now rely on the release function for cleanup */ dev->release =3D rpmsg_eptdev_release_device; @@ -464,7 +490,8 @@ static int rpmsg_chrdev_eptdev_add(struct rpmsg_eptdev = *eptdev, struct rpmsg_cha free_ept_ida: ida_free(&rpmsg_ept_ida, dev->id); free_minor_ida: - ida_free(&rpmsg_minor_ida, MINOR(dev->devt)); + if (cdev) + ida_free(&rpmsg_minor_ida, MINOR(dev->devt)); free_eptdev: put_device(dev); kfree(eptdev); @@ -472,6 +499,11 @@ static int rpmsg_chrdev_eptdev_add(struct rpmsg_eptdev= *eptdev, struct rpmsg_cha return ret; } =20 +static int rpmsg_chrdev_eptdev_add(struct rpmsg_eptdev *eptdev, struct rpm= sg_channel_info chinfo) +{ + return rpmsg_eptdev_add(eptdev, chinfo, true); +} + int rpmsg_chrdev_eptdev_create(struct rpmsg_device *rpdev, struct device *= parent, struct rpmsg_channel_info chinfo) { --=20 2.25.1 From nobody Sun Dec 14 21:49:39 2025 Received: from out-174.mta0.migadu.com (out-174.mta0.migadu.com [91.218.175.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85B962FCC16 for ; Wed, 15 Oct 2025 15:19:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760541561; cv=none; b=lMUSpLjXbwfCZVqhj6PvsrFjROSJIURTUxNe3PwgxWketLAyl0TyqEdPpIfOqdMhKVNs8I0C7LtMreFAlo3u6Bbi2W9sowmauH03adjit31cCnNRnqouNDshLmKGBm1x2+X0dUi34mSuv7Y+/xdJO5DkodChj42HZJ6Z8L2Ok3g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760541561; c=relaxed/simple; bh=pscgKDfCia+syY3l6wEPcO0AE3fzka4Z4JqRlh3DALw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jF9VfuQb4/ydM7AB6fZ9Dqh24Z8X1tLuzt4G6HbE7uIYRkkobSYpsOpmvWQlRBALHyA+pU/qV1XAUxn3QzNmGFL5/OoGP6GwrZekX2v3kgFZ+5GOC6NlHgI4SpmOm2I3F8dB2dw+I+U38HCWGOqScv8jWVl6q7PtxtM2wxaMKb4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=irKBQwEC; arc=none smtp.client-ip=91.218.175.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="irKBQwEC" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1760541547; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EkxSFdBzl73HGr1Q2yVRL9dvH+HdlU7w2ZgBc5WvZlA=; b=irKBQwECLz+WuW3cLITnf9FssMNx5L1m9UcTADex5qzCYpJ+nRZ8CFv1jhQB1nRVYxcBn0 fUo2c1/FwWfdXN2HBQYf2WcYUgeUEhc0BS6QHlcDaeVXJy5E+Jo6HMajEtrP66HxUU6VcX etM13fcc5b3QRZDWHCqT1yu6maQb2n0= From: Dawei Li To: andersson@kernel.org, mathieu.poirier@linaro.org Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, dawei.li@linux.dev, set_pte_at@outlook.com Subject: [PATCH v5 2/3] rpmsg: char: Implement eptdev based on anonymous inode Date: Wed, 15 Oct 2025 23:17:17 +0800 Message-Id: <20251015151718.3927-3-dawei.li@linux.dev> In-Reply-To: <20251015151718.3927-1-dawei.li@linux.dev> References: <20251015151718.3927-1-dawei.li@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Introduce new eptdev abstraction based on anonymous inode. The new API is exactly same with legacy one except: - It's anonymous and devnode/path free. - Its fops->open() is empty. Signed-off-by: Dawei Li --- drivers/rpmsg/rpmsg_char.c | 49 ++++++++++++++++++++++++++++++++++++++ drivers/rpmsg/rpmsg_char.h | 23 ++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c index 85154a422e9d..34b35ea74aab 100644 --- a/drivers/rpmsg/rpmsg_char.c +++ b/drivers/rpmsg/rpmsg_char.c @@ -13,6 +13,7 @@ =20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 +#include #include #include #include @@ -517,6 +518,54 @@ int rpmsg_chrdev_eptdev_create(struct rpmsg_device *rp= dev, struct device *parent } EXPORT_SYMBOL(rpmsg_chrdev_eptdev_create); =20 +static const struct file_operations rpmsg_anonymous_eptdev_fops =3D { + .owner =3D THIS_MODULE, + .release =3D rpmsg_eptdev_release, + .read_iter =3D rpmsg_eptdev_read_iter, + .write_iter =3D rpmsg_eptdev_write_iter, + .poll =3D rpmsg_eptdev_poll, + .unlocked_ioctl =3D rpmsg_eptdev_ioctl, + .compat_ioctl =3D compat_ptr_ioctl, +}; + +int rpmsg_anonymous_eptdev_create(struct rpmsg_device *rpdev, struct devic= e *parent, + struct rpmsg_channel_info chinfo, unsigned int flags, + int *pfd) +{ + struct rpmsg_eptdev *eptdev; + int ret, fd; + + /* Anonymous inode only supports these file flags */ + if (flags & ~(O_ACCMODE | O_NONBLOCK | O_CLOEXEC)) + return -EINVAL; + + eptdev =3D rpmsg_eptdev_alloc(rpdev, parent, false); + if (IS_ERR(eptdev)) + return PTR_ERR(eptdev); + + ret =3D rpmsg_eptdev_add(eptdev, chinfo, false); + if (ret) { + dev_err(&eptdev->dev, "failed to add %s\n", eptdev->chinfo.name); + return ret; + } + + fd =3D anon_inode_getfd("rpmsg-eptdev", &rpmsg_anonymous_eptdev_fops, ept= dev, flags); + if (fd < 0) { + put_device(&eptdev->dev); + return fd; + } + + mutex_lock(&eptdev->ept_lock); + ret =3D __rpmsg_eptdev_open(eptdev); + mutex_unlock(&eptdev->ept_lock); + + if (!ret) + *pfd =3D fd; + + return ret; +} +EXPORT_SYMBOL(rpmsg_anonymous_eptdev_create); + static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev) { struct rpmsg_channel_info chinfo; diff --git a/drivers/rpmsg/rpmsg_char.h b/drivers/rpmsg/rpmsg_char.h index 117d9cbc52f0..70ce2c511f13 100644 --- a/drivers/rpmsg/rpmsg_char.h +++ b/drivers/rpmsg/rpmsg_char.h @@ -19,6 +19,22 @@ int rpmsg_chrdev_eptdev_create(struct rpmsg_device *rpdev, struct device *= parent, struct rpmsg_channel_info chinfo); =20 +/** + * rpmsg_anonymous_eptdev_create() - register anonymous device and its ass= ociated + * fd based on an endpoint + * @rpdev: prepared rpdev to be used for creating endpoints + * @parent: parent device + * @chinfo: associated endpoint channel information. + * @flag: file flag + * @pfd: fd in represent of endpoint device + * + * This function create a new rpmsg endpoint device and its associated fd = to instantiate a new + * endpoint based on chinfo information. + */ +int rpmsg_anonymous_eptdev_create(struct rpmsg_device *rpdev, struct devic= e *parent, + struct rpmsg_channel_info chinfo, unsigned int flags, + int *pfd); + /** * rpmsg_chrdev_eptdev_destroy() - destroy created char device endpoint. * @data: private data associated to the endpoint device @@ -36,6 +52,13 @@ static inline int rpmsg_chrdev_eptdev_create(struct rpms= g_device *rpdev, struct return -ENXIO; } =20 +static inline int rpmsg_anonymous_eptdev_create(struct rpmsg_device *rpdev= , struct device *parent, + struct rpmsg_channel_info chinfo, + unsigned int flags, int *pfd) +{ + return -ENXIO; +} + static inline int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *da= ta) { return -ENXIO; --=20 2.25.1 From nobody Sun Dec 14 21:49:39 2025 Received: from out-170.mta1.migadu.com (out-170.mta1.migadu.com [95.215.58.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C80BC2FB985 for ; Wed, 15 Oct 2025 15:19:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760541559; cv=none; b=gyuYOjA6CzKRndFrivAWn90fwpLVE0yny8PFZcu0gBwGwaHzrRwhKpqtvHNbGvjCneZYDPlpOZ4Boe5eOF3OeAWyR6vAcBh+GS//nR/isDO6g3qBouCwTLdSyRNQtvn5E0halw+RlRUNxRvK3Po+Nl7N1O3CbhsIT7oGr9uej7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760541559; c=relaxed/simple; bh=a9xKhDk+BGtJ4JiaTrGo1b0mvMJxDoS0zpI5Gu5pD4Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=u3E/Yj+h2fD1f2CU1/dMDNUts100TpiRjXPeA/r6lmLrplBi1kB8De+H8p0vzt4K+3xUZqMmyWiol/oOYaI+BkRX+5roIR+fVdZJdf+FpJ2I6QjBjmhFSxgBnKgJ+KC/xvv45g+9Swwk1DL7NKkz5nCK3BWpRGZE4o01ECEJryw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=udULT81v; arc=none smtp.client-ip=95.215.58.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="udULT81v" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1760541553; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FSAoHN+I0q5gvwL07/+w9FpvcidtI68SZ5LkGFNNr6w=; b=udULT81vHIEVtIBF5XvtutmVrlGPzNupoyXCUuAEkSjJ5KIHh+zFjEWykswdr5yVjG9eAv S2y3mltUcBCzV9/DoUrxNsqRQtreuXr4DGXKGSwGIkjWff9qBg0OHS/MKV/rZEW9VL59DF c2ZDhOOd2eIZ1QLTvCqFHicpK3drHjk= From: Dawei Li To: andersson@kernel.org, mathieu.poirier@linaro.org Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, dawei.li@linux.dev, set_pte_at@outlook.com Subject: [PATCH v5 3/3] rpmsg: ctrl: Introduce RPMSG_CREATE_EPT_FD_IOCTL uAPI Date: Wed, 15 Oct 2025 23:17:18 +0800 Message-Id: <20251015151718.3927-4-dawei.li@linux.dev> In-Reply-To: <20251015151718.3927-1-dawei.li@linux.dev> References: <20251015151718.3927-1-dawei.li@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" 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 =3D open("/dev/rpmsg_ctrlX") - ioctl(fd, RPMSG_CREATE_EPT_FD_IOCTL, &info); - fd_ep =3D 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 --- drivers/rpmsg/rpmsg_ctrl.c | 35 ++++++++++++++++++++++++++++------- include/uapi/linux/rpmsg.h | 27 ++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/drivers/rpmsg/rpmsg_ctrl.c b/drivers/rpmsg/rpmsg_ctrl.c index 28f57945ccd9..efb207506e5c 100644 --- a/drivers/rpmsg/rpmsg_ctrl.c +++ b/drivers/rpmsg/rpmsg_ctrl.c @@ -75,19 +75,30 @@ static long rpmsg_ctrldev_ioctl(struct file *fp, unsign= ed int cmd, unsigned long arg) { struct rpmsg_ctrldev *ctrldev =3D fp->private_data; + struct rpmsg_endpoint_fd_info ept_fd_info; void __user *argp =3D (void __user *)arg; struct rpmsg_endpoint_info eptinfo; struct rpmsg_channel_info chinfo; struct rpmsg_device *rpdev; int ret =3D 0; =20 - if (copy_from_user(&eptinfo, argp, sizeof(eptinfo))) - return -EFAULT; - - memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE); - chinfo.name[RPMSG_NAME_SIZE - 1] =3D '\0'; - chinfo.src =3D eptinfo.src; - chinfo.dst =3D eptinfo.dst; + if (cmd =3D=3D 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] =3D '\0'; + chinfo.src =3D ept_fd_info.src; + chinfo.dst =3D ept_fd_info.dst; + } else { + if (copy_from_user(&eptinfo, argp, sizeof(eptinfo))) + return -EFAULT; + + memcpy(chinfo.name, eptinfo.name, RPMSG_NAME_SIZE); + chinfo.name[RPMSG_NAME_SIZE - 1] =3D '\0'; + chinfo.src =3D eptinfo.src; + chinfo.dst =3D eptinfo.dst; + } =20 mutex_lock(&ctrldev->ctrl_lock); switch (cmd) { @@ -110,6 +121,16 @@ static long rpmsg_ctrldev_ioctl(struct file *fp, unsig= ned int cmd, chinfo.name, ret); break; =20 + case RPMSG_CREATE_EPT_FD_IOCTL: + ret =3D rpmsg_anonymous_eptdev_create(ctrldev->rpdev, &ctrldev->dev, chi= nfo, + ept_fd_info.flags, &ept_fd_info.fd); + if (ret) + break; + + if (copy_to_user(argp, &ept_fd_info, sizeof(ept_fd_info))) + ret =3D -EFAULT; + break; + default: ret =3D -EINVAL; } diff --git a/include/uapi/linux/rpmsg.h b/include/uapi/linux/rpmsg.h index f0c8da2b185b..02befb298f71 100644 --- a/include/uapi/linux/rpmsg.h +++ b/include/uapi/linux/rpmsg.h @@ -29,7 +29,8 @@ struct rpmsg_endpoint_info { #define RPMSG_CREATE_EPT_IOCTL _IOW(0xb5, 0x1, struct rpmsg_endpoint_info) =20 /** - * Destroy a rpmsg char device endpoint created by the RPMSG_CREATE_EPT_IO= CTL. + * Destroy a rpmsg char device endpoint created by the RPMSG_CREATE_EPT_IO= CTL + * or RPMSG_CREATE_EPT_FD_IOCTL. */ #define RPMSG_DESTROY_EPT_IOCTL _IO(0xb5, 0x2) =20 @@ -53,4 +54,28 @@ struct rpmsg_endpoint_info { */ #define RPMSG_SET_INCOMING_FLOWCONTROL _IOR(0xb5, 0x6, int) =20 +/** + * 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_f= d_info) + #endif --=20 2.25.1