[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