[PATCH RFC v2 04/11] remoteproc: report VIRTIO_F_VERSION_1 for non-rproc-specific vdevs

Francesco Valla francesco at valla.it
Sun Nov 1 15:26:41 PST 2026


There is currently no way to report the VIRTIO_F_VERSION_1 using the
resource table alone, as the per-vdev feature array is limited to 32
bits.

Considering that the VIRTIO 1.0 specification is now ~10 years old,
always report the VIRTIO_F_VERSION_1 feature for virtio devices that
are not specific for remoteproc usage. These latter, which as of today
are rpmsg and rproc-serial, are excluded to avoid impacting the existing
usecases, since VIRTIO_F_VERSION_1 changes the semantics of the
communication (e.g., the configuration space is assumed to be
little-endian rather than follow the device's endianness).

While at it, replace BUG_ON() with WARN_ON() and return an appropriate
error in case of features that would overflow the 32 bits limit.

Signed-off-by: Francesco Valla <francesco at valla.it>
---
 drivers/remoteproc/remoteproc_virtio.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index c56d3330adfe..f1b362158a9c 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -16,6 +16,7 @@
 #include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 #include <linux/remoteproc.h>
+#include <linux/rsc_table.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
 #include <linux/virtio_ids.h>
@@ -27,6 +28,11 @@
 
 #include "remoteproc_internal.h"
 
+static bool rproc_virtio_rsc_vdev_rproc_specific(struct fw_rsc_vdev *rsc)
+{
+	return (rsc->id == VIRTIO_ID_RPMSG || rsc->id == VIRTIO_ID_RPROC_SERIAL);
+}
+
 static int copy_dma_range_map(struct device *to, struct device *from)
 {
 	const struct bus_dma_region *map = from->dma_range_map, *new_map, *r;
@@ -268,8 +274,17 @@ static void rproc_virtio_synchronize_cbs(struct virtio_device *vdev)
 static u64 rproc_virtio_get_features(struct virtio_device *vdev)
 {
 	struct fw_rsc_vdev *rsc = vdev_to_rsc(vdev);
+	u64 features = (u64)rsc->dfeatures;
 
-	return rsc->dfeatures;
+	/*
+	 * All non-remoteproc-specific virtio devices are assumed to be
+	 * compliant with virtio specifications 1.x; there is no other method
+	 * to transmit this capability from the remote processor to the host.
+	 */
+	if (!rproc_virtio_rsc_vdev_rproc_specific(rsc))
+		features |= (1ULL << VIRTIO_F_VERSION_1);
+
+	return features;
 }
 
 static void rproc_transport_features(struct virtio_device *vdev)
@@ -285,6 +300,7 @@ static void rproc_transport_features(struct virtio_device *vdev)
 static int rproc_virtio_finalize_features(struct virtio_device *vdev)
 {
 	struct fw_rsc_vdev *rsc = vdev_to_rsc(vdev);
+	u64 features;
 
 	/* Give virtio_ring a chance to accept features */
 	vring_transport_features(vdev);
@@ -292,8 +308,14 @@ static int rproc_virtio_finalize_features(struct virtio_device *vdev)
 	/* Give virtio_rproc a chance to accept features. */
 	rproc_transport_features(vdev);
 
-	/* Make sure we don't have any features > 32 bits! */
-	BUG_ON((u32)vdev->features != vdev->features);
+	/* Make sure we don't have any features > 32 bits except the expected ones. */
+	features = vdev->features;
+
+	if (!rproc_virtio_rsc_vdev_rproc_specific(rsc))
+		features &= ~(1ULL << VIRTIO_F_VERSION_1);
+
+	if (WARN_ON((u32)vdev->features != features))
+		return -EINVAL;
 
 	/*
 	 * Remember the finalized features of our vdev, and provide it

-- 
2.56.0




More information about the linux-arm-kernel mailing list