This patch introduces support for vhost-user-spi and vhost-user-spi-pci
devices in QEMU, enabling virtio-based SPI communication via the vhost-user
protocol.
The implementation follows the virtio-spi specification and leverages
the upstream virtio-spi driver in Linux. Relevant references:
- Virtio SPI specification:
https://github.com/oasis-tcs/virtio-spec/tree/master/device-types/spi
- Linux virtio-spi driver:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-virtio.c?h=v6.18-rc3
- vhost-user-spi daemon:
https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-spi
Example usage with rust-vmm vhost-user-spi daemon:
Start the vhost-user-spi daemon:
vhost-device-spi --socket-path=vspi.sock --socket-count=1 \
--device "/dev/spidev0.0"
Launch QEMU with:
qemu-system-aarch64 -m 1G \
-chardev socket,path=/home/root/vspi.sock0,id=vspi \
-device vhost-user-spi-device,chardev=vspi,id=spi \
-object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
-numa node,memdev=mem
Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
---
MAINTAINERS | 6 ++
docs/system/devices/virtio/vhost-user.rst | 3 +
hw/virtio/Kconfig | 5 ++
hw/virtio/meson.build | 3 +
hw/virtio/vhost-user-spi-pci.c | 69 +++++++++++++++++++++++
hw/virtio/vhost-user-spi.c | 65 +++++++++++++++++++++
hw/virtio/virtio.c | 4 +-
include/hw/virtio/vhost-user-spi.h | 25 ++++++++
8 files changed, 179 insertions(+), 1 deletion(-)
create mode 100644 hw/virtio/vhost-user-spi-pci.c
create mode 100644 hw/virtio/vhost-user-spi.c
create mode 100644 include/hw/virtio/vhost-user-spi.h
diff --git a/MAINTAINERS b/MAINTAINERS
index f33f95ceea..9ce2e16140 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2520,6 +2520,12 @@ F: hw/virtio/vhost-user-scmi*
F: include/hw/virtio/vhost-user-scmi.h
F: tests/qtest/libqos/virtio-scmi.*
+vhost-user-spi
+M: Haixu Cui <quic_haixcui@quicinc.com>
+S: Maintained
+F: include/hw/virtio/vhost-user-spi.h
+F: hw/virtio/vhost-user-spi*
+
virtio-crypto
M: Gonglei <arei.gonglei@huawei.com>
S: Supported
diff --git a/docs/system/devices/virtio/vhost-user.rst b/docs/system/devices/virtio/vhost-user.rst
index f556a840e9..2806d81ca2 100644
--- a/docs/system/devices/virtio/vhost-user.rst
+++ b/docs/system/devices/virtio/vhost-user.rst
@@ -58,6 +58,9 @@ platform details for what sort of virtio bus to use.
* - vhost-user-vsock
- Socket based communication
- `vhost-device-vsock <https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-vsock>`_
+ * - vhost-user-spi
+ - Proxy spi devices to host
+ - `vhost-device-spi <https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-spi>`_
The referenced *daemons* are not exhaustive, any conforming backend
implementing the device and using the vhost-user protocol should work.
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index 10f5c53ac0..8895682c61 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -127,6 +127,11 @@ config VHOST_USER_SCMI
default y
depends on VIRTIO && VHOST_USER && ARM
+config VHOST_USER_SPI
+ bool
+ default y
+ depends on VIRTIO && VHOST_USER
+
config VHOST_USER_TEST
bool
default y
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index affd66887d..6675b63ce6 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -28,6 +28,7 @@ if have_vhost
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
+ system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
# PCI Stubs
system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_TEST'],
@@ -42,6 +43,8 @@ if have_vhost
if_true: files('vhost-user-snd-pci.c'))
system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
if_true: files('vhost-user-input-pci.c'))
+ system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
+ if_true: files('vhost-user-spi-pci.c'))
endif
if have_vhost_vdpa
system_virtio_ss.add(files('vhost-vdpa.c'))
diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
new file mode 100644
index 0000000000..095aba5760
--- /dev/null
+++ b/hw/virtio/vhost-user-spi-pci.c
@@ -0,0 +1,69 @@
+/*
+ * Vhost-user spi virtio device PCI glue
+ *
+ * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/vhost-user-spi.h"
+#include "hw/virtio/virtio-pci.h"
+
+struct VHostUserSPIPCI {
+ VirtIOPCIProxy parent_obj;
+ VHostUserSPI vdev;
+};
+
+typedef struct VHostUserSPIPCI VHostUserSPIPCI;
+
+#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
+
+DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
+ TYPE_VHOST_USER_SPI_PCI)
+
+static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+ VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
+ DeviceState *vdev = DEVICE(&dev->vdev);
+
+ vpci_dev->nvectors = 1;
+ qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+}
+
+static void vhost_user_spi_pci_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+ PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+ k->realize = vhost_user_spi_pci_realize;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+ pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+ pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+ pcidev_k->revision = 0x00;
+ pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
+}
+
+static void vhost_user_spi_pci_instance_init(Object *obj)
+{
+ VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
+
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VHOST_USER_SPI);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
+ .base_name = TYPE_VHOST_USER_SPI_PCI,
+ .non_transitional_name = "vhost-user-spi-pci",
+ .instance_size = sizeof(VHostUserSPIPCI),
+ .instance_init = vhost_user_spi_pci_instance_init,
+ .class_init = vhost_user_spi_pci_class_init,
+};
+
+static void vhost_user_spi_pci_register(void)
+{
+ virtio_pci_types_register(&vhost_user_spi_pci_info);
+}
+
+type_init(vhost_user_spi_pci_register);
diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
new file mode 100644
index 0000000000..0d44dec46a
--- /dev/null
+++ b/hw/virtio/vhost-user-spi.c
@@ -0,0 +1,65 @@
+/*
+ * Vhost-user spi virtio device
+ *
+ * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/vhost-user-spi.h"
+#include "qemu/error-report.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_spi.h"
+
+static const Property vspi_properties[] = {
+ DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+};
+
+static void vspi_realize(DeviceState *dev, Error **errp)
+{
+ VHostUserBase *vub = VHOST_USER_BASE(dev);
+ VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
+
+ /* Fixed for SPI */
+ vub->virtio_id = VIRTIO_ID_SPI;
+ vub->num_vqs = 1;
+ vub->vq_size = 4;
+ vub->config_size = sizeof(struct virtio_spi_config);
+
+ vubc->parent_realize(dev, errp);
+}
+
+static const VMStateDescription vu_spi_vmstate = {
+ .name = "vhost-user-spi",
+ .unmigratable = 1,
+};
+
+static void vu_spi_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
+
+ dc->vmsd = &vu_spi_vmstate;
+ device_class_set_props(dc, vspi_properties);
+ device_class_set_parent_realize(dc, vspi_realize,
+ &vubc->parent_realize);
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+}
+
+static const TypeInfo vu_spi_info = {
+ .name = TYPE_VHOST_USER_SPI,
+ .parent = TYPE_VHOST_USER_BASE,
+ .instance_size = sizeof(VHostUserSPI),
+ .class_init = vu_spi_class_init,
+};
+
+static void vu_spi_register_types(void)
+{
+ type_register_static(&vu_spi_info);
+}
+
+type_init(vu_spi_register_types)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 153ee0a0cf..242b95e702 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -48,6 +48,7 @@
#include "standard-headers/linux/virtio_iommu.h"
#include "standard-headers/linux/virtio_mem.h"
#include "standard-headers/linux/virtio_vsock.h"
+#include "standard-headers/linux/virtio_spi.h"
/*
* Maximum size of virtio device config space
@@ -196,7 +197,8 @@ const char *virtio_device_names[] = {
[VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
[VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
[VIRTIO_ID_BT] = "virtio-bluetooth",
- [VIRTIO_ID_GPIO] = "virtio-gpio"
+ [VIRTIO_ID_GPIO] = "virtio-gpio",
+ [VIRTIO_ID_SPI] = "virtio-spi"
};
static const char *virtio_id_to_name(uint16_t device_id)
diff --git a/include/hw/virtio/vhost-user-spi.h b/include/hw/virtio/vhost-user-spi.h
new file mode 100644
index 0000000000..a1a65820cd
--- /dev/null
+++ b/include/hw/virtio/vhost-user-spi.h
@@ -0,0 +1,25 @@
+/*
+ * Vhost-user spi virtio device
+ *
+ * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_SPI_H
+#define QEMU_VHOST_USER_SPI_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
+
+#define TYPE_VHOST_USER_SPI "vhost-user-spi-device"
+
+OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSPI, VHOST_USER_SPI)
+
+struct VHostUserSPI {
+ VHostUserBase parent_obj;
+};
+
+#endif /* QEMU_VHOST_USER_SPI_H */
--
2.34.1
On Thu, Oct 30, 2025 at 10:34 AM Haixu Cui <quic_haixcui@quicinc.com> wrote:
>
> This patch introduces support for vhost-user-spi and vhost-user-spi-pci
> devices in QEMU, enabling virtio-based SPI communication via the vhost-user
> protocol.
>
> The implementation follows the virtio-spi specification and leverages
> the upstream virtio-spi driver in Linux. Relevant references:
>
> - Virtio SPI specification:
> https://github.com/oasis-tcs/virtio-spec/tree/master/device-types/spi
> - Linux virtio-spi driver:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-virtio.c?h=v6.18-rc3
> - vhost-user-spi daemon:
> https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-spi
>
> Example usage with rust-vmm vhost-user-spi daemon:
>
> Start the vhost-user-spi daemon:
> vhost-device-spi --socket-path=vspi.sock --socket-count=1 \
> --device "/dev/spidev0.0"
>
> Launch QEMU with:
> qemu-system-aarch64 -m 1G \
> -chardev socket,path=/home/root/vspi.sock0,id=vspi \
> -device vhost-user-spi-device,chardev=vspi,id=spi \
> -object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
> -numa node,memdev=mem
>
> Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
> ---
> MAINTAINERS | 6 ++
> docs/system/devices/virtio/vhost-user.rst | 3 +
> hw/virtio/Kconfig | 5 ++
> hw/virtio/meson.build | 3 +
> hw/virtio/vhost-user-spi-pci.c | 69 +++++++++++++++++++++++
> hw/virtio/vhost-user-spi.c | 65 +++++++++++++++++++++
> hw/virtio/virtio.c | 4 +-
> include/hw/virtio/vhost-user-spi.h | 25 ++++++++
> 8 files changed, 179 insertions(+), 1 deletion(-)
> create mode 100644 hw/virtio/vhost-user-spi-pci.c
> create mode 100644 hw/virtio/vhost-user-spi.c
> create mode 100644 include/hw/virtio/vhost-user-spi.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f33f95ceea..9ce2e16140 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2520,6 +2520,12 @@ F: hw/virtio/vhost-user-scmi*
> F: include/hw/virtio/vhost-user-scmi.h
> F: tests/qtest/libqos/virtio-scmi.*
>
> +vhost-user-spi
> +M: Haixu Cui <quic_haixcui@quicinc.com>
> +S: Maintained
> +F: include/hw/virtio/vhost-user-spi.h
> +F: hw/virtio/vhost-user-spi*
> +
> virtio-crypto
> M: Gonglei <arei.gonglei@huawei.com>
> S: Supported
> diff --git a/docs/system/devices/virtio/vhost-user.rst b/docs/system/devices/virtio/vhost-user.rst
> index f556a840e9..2806d81ca2 100644
> --- a/docs/system/devices/virtio/vhost-user.rst
> +++ b/docs/system/devices/virtio/vhost-user.rst
> @@ -58,6 +58,9 @@ platform details for what sort of virtio bus to use.
> * - vhost-user-vsock
> - Socket based communication
> - `vhost-device-vsock <https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-vsock>`_
> + * - vhost-user-spi
> + - Proxy spi devices to host
> + - `vhost-device-spi <https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-spi>`_
>
> The referenced *daemons* are not exhaustive, any conforming backend
> implementing the device and using the vhost-user protocol should work.
> diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
> index 10f5c53ac0..8895682c61 100644
> --- a/hw/virtio/Kconfig
> +++ b/hw/virtio/Kconfig
> @@ -127,6 +127,11 @@ config VHOST_USER_SCMI
> default y
> depends on VIRTIO && VHOST_USER && ARM
>
> +config VHOST_USER_SPI
> + bool
> + default y
> + depends on VIRTIO && VHOST_USER
> +
> config VHOST_USER_TEST
> bool
> default y
> diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
> index affd66887d..6675b63ce6 100644
> --- a/hw/virtio/meson.build
> +++ b/hw/virtio/meson.build
> @@ -28,6 +28,7 @@ if have_vhost
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
> system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
> + system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
>
> # PCI Stubs
> system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_TEST'],
> @@ -42,6 +43,8 @@ if have_vhost
> if_true: files('vhost-user-snd-pci.c'))
> system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
> if_true: files('vhost-user-input-pci.c'))
> + system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
> + if_true: files('vhost-user-spi-pci.c'))
> endif
> if have_vhost_vdpa
> system_virtio_ss.add(files('vhost-vdpa.c'))
> diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
> new file mode 100644
> index 0000000000..095aba5760
> --- /dev/null
> +++ b/hw/virtio/vhost-user-spi-pci.c
> @@ -0,0 +1,69 @@
> +/*
> + * Vhost-user spi virtio device PCI glue
> + *
> + * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/vhost-user-spi.h"
> +#include "hw/virtio/virtio-pci.h"
> +
> +struct VHostUserSPIPCI {
> + VirtIOPCIProxy parent_obj;
> + VHostUserSPI vdev;
> +};
> +
> +typedef struct VHostUserSPIPCI VHostUserSPIPCI;
> +
> +#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
> +
> +DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
> + TYPE_VHOST_USER_SPI_PCI)
> +
> +static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
> +{
> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
> + DeviceState *vdev = DEVICE(&dev->vdev);
> +
> + vpci_dev->nvectors = 1;
> + qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
> +}
> +
> +static void vhost_user_spi_pci_class_init(ObjectClass *klass, const void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
> + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
> + k->realize = vhost_user_spi_pci_realize;
> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
> + pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
> + pcidev_k->revision = 0x00;
> + pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
> +}
> +
> +static void vhost_user_spi_pci_instance_init(Object *obj)
> +{
> + VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
> +
> + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
> + TYPE_VHOST_USER_SPI);
> +}
> +
> +static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
> + .base_name = TYPE_VHOST_USER_SPI_PCI,
> + .non_transitional_name = "vhost-user-spi-pci",
> + .instance_size = sizeof(VHostUserSPIPCI),
> + .instance_init = vhost_user_spi_pci_instance_init,
> + .class_init = vhost_user_spi_pci_class_init,
> +};
> +
> +static void vhost_user_spi_pci_register(void)
> +{
> + virtio_pci_types_register(&vhost_user_spi_pci_info);
> +}
> +
> +type_init(vhost_user_spi_pci_register);
> diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
> new file mode 100644
> index 0000000000..0d44dec46a
> --- /dev/null
> +++ b/hw/virtio/vhost-user-spi.c
> @@ -0,0 +1,65 @@
> +/*
> + * Vhost-user spi virtio device
> + *
> + * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/virtio/virtio-bus.h"
> +#include "hw/virtio/vhost-user-spi.h"
> +#include "qemu/error-report.h"
> +#include "standard-headers/linux/virtio_ids.h"
> +#include "standard-headers/linux/virtio_spi.h"
> +
> +static const Property vspi_properties[] = {
> + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
> +};
> +
> +static void vspi_realize(DeviceState *dev, Error **errp)
> +{
> + VHostUserBase *vub = VHOST_USER_BASE(dev);
> + VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
> +
> + /* Fixed for SPI */
> + vub->virtio_id = VIRTIO_ID_SPI;
> + vub->num_vqs = 1;
> + vub->vq_size = 4;
> + vub->config_size = sizeof(struct virtio_spi_config);
> +
> + vubc->parent_realize(dev, errp);
> +}
> +
> +static const VMStateDescription vu_spi_vmstate = {
> + .name = "vhost-user-spi",
> + .unmigratable = 1,
> +};
> +
> +static void vu_spi_class_init(ObjectClass *klass, const void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
> +
> + dc->vmsd = &vu_spi_vmstate;
> + device_class_set_props(dc, vspi_properties);
> + device_class_set_parent_realize(dc, vspi_realize,
> + &vubc->parent_realize);
> + set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> +}
> +
> +static const TypeInfo vu_spi_info = {
> + .name = TYPE_VHOST_USER_SPI,
> + .parent = TYPE_VHOST_USER_BASE,
> + .instance_size = sizeof(VHostUserSPI),
> + .class_init = vu_spi_class_init,
> +};
> +
> +static void vu_spi_register_types(void)
> +{
> + type_register_static(&vu_spi_info);
> +}
> +
> +type_init(vu_spi_register_types)
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 153ee0a0cf..242b95e702 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -48,6 +48,7 @@
> #include "standard-headers/linux/virtio_iommu.h"
> #include "standard-headers/linux/virtio_mem.h"
> #include "standard-headers/linux/virtio_vsock.h"
> +#include "standard-headers/linux/virtio_spi.h"
>
> /*
> * Maximum size of virtio device config space
> @@ -196,7 +197,8 @@ const char *virtio_device_names[] = {
> [VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
> [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
> [VIRTIO_ID_BT] = "virtio-bluetooth",
> - [VIRTIO_ID_GPIO] = "virtio-gpio"
> + [VIRTIO_ID_GPIO] = "virtio-gpio",
> + [VIRTIO_ID_SPI] = "virtio-spi"
> };
>
> static const char *virtio_id_to_name(uint16_t device_id)
> diff --git a/include/hw/virtio/vhost-user-spi.h b/include/hw/virtio/vhost-user-spi.h
> new file mode 100644
> index 0000000000..a1a65820cd
> --- /dev/null
> +++ b/include/hw/virtio/vhost-user-spi.h
> @@ -0,0 +1,25 @@
> +/*
> + * Vhost-user spi virtio device
> + *
> + * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef QEMU_VHOST_USER_SPI_H
> +#define QEMU_VHOST_USER_SPI_H
> +
> +#include "hw/virtio/virtio.h"
> +#include "hw/virtio/vhost.h"
> +#include "hw/virtio/vhost-user.h"
> +#include "hw/virtio/vhost-user-base.h"
> +
> +#define TYPE_VHOST_USER_SPI "vhost-user-spi-device"
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSPI, VHOST_USER_SPI)
> +
> +struct VHostUserSPI {
> + VHostUserBase parent_obj;
> +};
> +
> +#endif /* QEMU_VHOST_USER_SPI_H */
> --
> 2.34.1
>
I unfortunately cannot test it since the rust-vmm daemon requires a
host SPI device, but LGTM
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > I unfortunately cannot test it since the rust-vmm daemon requires a > host SPI device, but LGTM > > Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Thanks Manos for reviewing and providing the feedback. I really appreciate your time and effort. To QEMU community: I would like to kindly ask if anyone else has additional comments or suggestions regarding this patch. If there are no further concerns, could you please advise whether it is ready to be merged? Best Regards Haixu Cui
© 2016 - 2026 Red Hat, Inc.