From: Viresh Kumar <viresh.kumar@linaro.org>
To: linux-kernel@vger.kernel.org,
"Michael S. Tsirkin" <mst@redhat.com>,
"Jason Wang" <jasowang@redhat.com>,
"Xuan Zhuo" <xuanzhuo@linux.alibaba.com>,
"Eugenio Pérez" <eperezma@redhat.com>,
"Viresh Kumar" <viresh.kumar@linaro.org>
Cc: "Arnd Bergmann" <arnd@kernel.org>,
"Vincent Guittot" <vincent.guittot@linaro.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Bill Mills" <bill.mills@linaro.org>,
"Rob Herring" <robh@kernel.org>,
"Saravana Kannan" <saravanak@google.com>,
devicetree@vger.kernel.org, virtualization@lists.linux.dev,
"Sudeep Holla" <sudeep.holla@arm.com>,
"Bertrand Marquis" <bertrand.marquis@arm.com>,
"Edgar E . Iglesias" <edgar.iglesias@amd.com>,
"Arnaud Pouliquen" <arnaud.pouliquen@foss.st.com>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>
Subject: [RFC PATCH 4/6] virtio-msg: Add optional userspace interface for message I/O
Date: Wed, 30 Jul 2025 14:59:33 +0530 [thread overview]
Message-ID: <97ae7b7bea8a22108aaebdfd9330de93ecc91333.1753865268.git.viresh.kumar@linaro.org> (raw)
In-Reply-To: <cover.1753865268.git.viresh.kumar@linaro.org>
Add support for an optional userspace interface to the virtio-msg
transport via a per-bus miscdevice. When enabled by a bus
implementation, this interface allows userspace to send and receive
virtio messages through a character device node.
A separate device node is created for each bus that registers for
userspace access, e.g., /dev/virtio-msg-N. This enables backend-side
components or test tools to interact with the transport layer directly
from userspace.
Bus implementations that do not require userspace interaction can omit
this interface entirely.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/virtio/Kconfig | 8 ++
drivers/virtio/Makefile | 4 +-
drivers/virtio/virtio_msg_internal.h | 32 ++++++
drivers/virtio/virtio_msg_user.c | 140 +++++++++++++++++++++++++++
4 files changed, 183 insertions(+), 1 deletion(-)
create mode 100644 drivers/virtio/virtio_msg_user.c
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 690ac98850b6..a86025c9e008 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -178,6 +178,14 @@ config VIRTIO_MSG
This enables support for Virtio message transport. This option is
selected by any driver which implements the virtio message bus.
+config VIRTIO_MSG_USER
+ tristate "Userspace interface for virtio message transport"
+ depends on VIRTIO_MSG
+ help
+ This enables userspace interface for Virtio message transport. This
+ can be used to read / write messages over virtio-msg transport from
+ userspace.
+
config VIRTIO_DMA_SHARED_BUFFER
tristate
depends on DMA_SHARED_BUFFER
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 3eff8ca72446..5b664c5f5f25 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -4,7 +4,9 @@ obj-$(CONFIG_VIRTIO_ANCHOR) += virtio_anchor.o
obj-$(CONFIG_VIRTIO_PCI_LIB) += virtio_pci_modern_dev.o
obj-$(CONFIG_VIRTIO_PCI_LIB_LEGACY) += virtio_pci_legacy_dev.o
obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
-obj-$(CONFIG_VIRTIO_MSG) += virtio_msg.o
+virtio_msg_transport-y := virtio_msg.o
+virtio_msg_transport-$(CONFIG_VIRTIO_MSG_USER) += virtio_msg_user.o
+obj-$(CONFIG_VIRTIO_MSG) += virtio_msg_transport.o
obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
diff --git a/drivers/virtio/virtio_msg_internal.h b/drivers/virtio/virtio_msg_internal.h
index b7c2cb44b67b..0d13d73507eb 100644
--- a/drivers/virtio/virtio_msg_internal.h
+++ b/drivers/virtio/virtio_msg_internal.h
@@ -9,6 +9,8 @@
#ifndef _DRIVERS_VIRTIO_MSG_INTERNAL_H
#define _DRIVERS_VIRTIO_MSG_INTERNAL_H
+#include <linux/completion.h>
+#include <linux/miscdevice.h>
#include <linux/virtio.h>
#include <uapi/linux/virtio_msg.h>
@@ -53,4 +55,34 @@ void virtio_msg_unregister(struct virtio_msg_device *vmdev);
void virtio_msg_prepare(struct virtio_msg *vmsg, u8 msg_id, u16 payload_size);
int virtio_msg_event(struct virtio_msg_device *vmdev, struct virtio_msg *vmsg);
+/* Virtio msg userspace interface */
+struct virtio_msg_user_device;
+
+struct virtio_msg_user_ops {
+ int (*handle)(struct virtio_msg_user_device *vmudev, struct virtio_msg *vmsg);
+};
+
+/* Host side device using virtio message */
+struct virtio_msg_user_device {
+ struct virtio_msg_user_ops *ops;
+ struct miscdevice misc;
+ struct completion r_completion;
+ struct completion w_completion;
+ struct virtio_msg *vmsg;
+ struct device *parent;
+ char name[15];
+};
+
+#if IS_REACHABLE(CONFIG_VIRTIO_MSG_USER)
+int virtio_msg_user_register(struct virtio_msg_user_device *vmudev);
+void virtio_msg_user_unregister(struct virtio_msg_user_device *vmudev);
+#else
+static inline int virtio_msg_user_register(struct virtio_msg_user_device *vmudev)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void virtio_msg_user_unregister(struct virtio_msg_user_device *vmudev) {}
+#endif /* CONFIG_VIRTIO_MSG_USER */
+
#endif /* _DRIVERS_VIRTIO_MSG_INTERNAL_H */
diff --git a/drivers/virtio/virtio_msg_user.c b/drivers/virtio/virtio_msg_user.c
new file mode 100644
index 000000000000..cf7286b3a311
--- /dev/null
+++ b/drivers/virtio/virtio_msg_user.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Virtio message transport user API.
+ *
+ * Copyright (C) 2025 Google LLC and Linaro.
+ * Viresh Kumar <viresh.kumar@linaro.org>
+ */
+
+#define pr_fmt(fmt) "virtio-msg: " fmt
+
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "virtio_msg_internal.h"
+
+#define to_virtio_msg_user_device(_misc) \
+ container_of(_misc, struct virtio_msg_user_device, misc)
+
+static ssize_t vmsg_miscdev_read(struct file *file, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct miscdevice *misc = file->private_data;
+ struct virtio_msg_user_device *vmudev = to_virtio_msg_user_device(misc);
+ struct device *dev = vmudev->parent;
+ int ret;
+
+ if (count < VIRTIO_MSG_MIN_SIZE) {
+ dev_err(dev, "Trying to read message of incorrect size: %zu\n",
+ count);
+ return 0;
+ }
+
+ /* Wait for the message */
+ ret = wait_for_completion_interruptible(&vmudev->r_completion);
+ if (ret < 0) {
+ dev_err(dev, "Interrupted while waiting for response: %d\n", ret);
+ return 0;
+ }
+
+ WARN_ON(!vmudev->vmsg);
+
+ /* The "vmsg" pointer is filled by the bus driver before waking up */
+ if (copy_to_user(buf, vmudev->vmsg, count) != 0)
+ return 0;
+
+ vmudev->vmsg = NULL;
+
+ return count;
+}
+
+static ssize_t vmsg_miscdev_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct miscdevice *misc = file->private_data;
+ struct virtio_msg_user_device *vmudev = to_virtio_msg_user_device(misc);
+ struct virtio_msg *vmsg __free(kfree) = NULL;
+
+ if (count < VIRTIO_MSG_MIN_SIZE) {
+ dev_err(vmudev->parent, "Trying to write message of incorrect size: %zu\n",
+ count);
+ return 0;
+ }
+
+ vmsg = kzalloc(count, GFP_KERNEL);
+ if (!vmsg)
+ return 0;
+
+ if (copy_from_user(vmsg, buf, count) != 0)
+ return 0;
+
+ vmudev->ops->handle(vmudev, vmsg);
+
+ /* Wake up the handler only for responses */
+ if (vmsg->type & VIRTIO_MSG_TYPE_RESPONSE)
+ complete(&vmudev->w_completion);
+
+ return count;
+}
+
+static const struct file_operations vmsg_miscdev_fops = {
+ .owner = THIS_MODULE,
+ .read = vmsg_miscdev_read,
+ .write = vmsg_miscdev_write,
+};
+
+/**
+ * virtio_msg_user_register - Register a user-space accessible virtio message device
+ * @vmudev: Pointer to the virtio message user device
+ *
+ * Initializes and registers a user-accessible virtio message device as a `misc`
+ * character device. Upon successful registration, the device appears in
+ * userspace as `/dev/virtio-msg-N` where `N` is a unique identifier assigned at
+ * runtime.
+ *
+ * The resulting device node allows user-space interaction with the virtio
+ * message transport.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int virtio_msg_user_register(struct virtio_msg_user_device *vmudev)
+{
+ static u8 vmsg_user_device_count;
+ int ret;
+
+ if (!vmudev || !vmudev->ops)
+ return -EINVAL;
+
+ init_completion(&vmudev->r_completion);
+ init_completion(&vmudev->w_completion);
+
+ vmudev->misc.parent = vmudev->parent;
+ vmudev->misc.minor = MISC_DYNAMIC_MINOR;
+ vmudev->misc.fops = &vmsg_miscdev_fops;
+ vmudev->misc.name = vmudev->name;
+ sprintf(vmudev->name, "virtio-msg-%d", vmsg_user_device_count);
+
+ ret = misc_register(&vmudev->misc);
+ if (ret)
+ return ret;
+
+ vmsg_user_device_count++;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtio_msg_user_register);
+
+/**
+ * virtio_msg_user_unregister - Unregister a user-space virtio message device
+ * @vmudev: Pointer to the virtio message user device
+ *
+ * Unregisters a previously registered virtio message device from the misc
+ * subsystem. This removes its user-space interface (e.g., /dev/virtio-msg-N).
+ */
+void virtio_msg_user_unregister(struct virtio_msg_user_device *vmudev)
+{
+ misc_deregister(&vmudev->misc);
+}
+EXPORT_SYMBOL_GPL(virtio_msg_user_unregister);
--
2.31.1.272.g89b43f80a514
next prev parent reply other threads:[~2025-07-30 9:30 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-30 9:29 [RFC PATCH 0/6] virtio: Add support for Virtio message transport Viresh Kumar
2025-07-30 9:29 ` [RFC PATCH 1/6] of: reserved-memory: Add reserved_mem_device_init() Viresh Kumar
2025-07-30 9:29 ` [RFC PATCH 2/6] of: reserved-memory: Add of_reserved_mem_lookup_by_name Viresh Kumar
2025-07-30 9:46 ` Krzysztof Kozlowski
2025-07-30 10:57 ` Viresh Kumar
2025-07-30 11:24 ` Krzysztof Kozlowski
2025-08-01 6:02 ` Viresh Kumar
2025-07-30 9:29 ` [RFC PATCH 3/6] virtio: Add support for virtio-msg transport Viresh Kumar
2025-07-30 9:29 ` Viresh Kumar [this message]
2025-07-30 9:29 ` [RFC PATCH 5/6] virtio-msg: Add support for FF-A (Firmware Framework for Arm) bus Viresh Kumar
2025-07-30 9:29 ` [RFC PATCH 6/6] virtio-msg: Add support for loopback bus Viresh Kumar
2025-07-30 9:49 ` Krzysztof Kozlowski
2025-07-30 13:39 ` [RFC PATCH 0/6] virtio: Add support for Virtio message transport Rob Herring
2025-08-12 9:49 ` Viresh Kumar
2025-08-12 13:28 ` Rob Herring
2025-08-13 6:28 ` Viresh Kumar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=97ae7b7bea8a22108aaebdfd9330de93ecc91333.1753865268.git.viresh.kumar@linaro.org \
--to=viresh.kumar@linaro.org \
--cc=alex.bennee@linaro.org \
--cc=arnaud.pouliquen@foss.st.com \
--cc=arnd@kernel.org \
--cc=bertrand.marquis@arm.com \
--cc=bill.mills@linaro.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=edgar.iglesias@amd.com \
--cc=eperezma@redhat.com \
--cc=jasowang@redhat.com \
--cc=krzk+dt@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mst@redhat.com \
--cc=robh@kernel.org \
--cc=saravanak@google.com \
--cc=sudeep.holla@arm.com \
--cc=vincent.guittot@linaro.org \
--cc=virtualization@lists.linux.dev \
--cc=xuanzhuo@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®