From: Timos Ampelikiotis <[email protected]> Add vhost-user-console support enabling console device emulation via the vhost-user protocol. This allows console handling to be performed by separate userspace processes such as the rust-vmm vhost-device-console daemon.
The device is based on vhost-user-base: set the console virtio id, four queues, the console config layout, and add a PCI wrapper. Migration is disabled for now. Tested with rust-vmm vhost-device-console: - https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-console Signed-off-by: Timos Ampelikiotis <[email protected]> --- Invocation of rust-vmm device: RUST_LOG=trace cargo run --bin vhost-device-console \ --socket-path /tmp/console.sock \ --console-path <PATH_TO_CONSOLE_FILE> Invocation of QEMU: qemu-system-x86_64 \ -m 4096 \ -numa node,memdev=mem \ -object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \ -chardev socket,id=char1,path=/tmp/console.sock \ -device vhost-user-console-pci,chardev=char1,id=console \ ... Acknowledgements: - This device was developed in the context of AGL (Automotive Grade Linux) SDV-EG (Software Defined Vehicles - Expert Group). - The development was based on the vhost-user-snd QEMU device introduced by the following repository: https://github.com/epilys/qemu-virtio-snd/tree/vhost-sound --- hw/virtio/Kconfig | 5 ++ hw/virtio/meson.build | 2 + hw/virtio/vhost-user-console-pci.c | 72 ++++++++++++++++++++++++++ hw/virtio/vhost-user-console.c | 65 +++++++++++++++++++++++ include/hw/virtio/vhost-user-console.h | 24 +++++++++ 5 files changed, 168 insertions(+) create mode 100644 hw/virtio/vhost-user-console-pci.c create mode 100644 hw/virtio/vhost-user-console.c create mode 100644 include/hw/virtio/vhost-user-console.h diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig index 10f5c53ac0..9c9dd8d7e3 100644 --- a/hw/virtio/Kconfig +++ b/hw/virtio/Kconfig @@ -112,6 +112,11 @@ config VHOST_USER_GPIO default y depends on VIRTIO && VHOST_USER +config VHOST_USER_CONSOLE + bool + default y + depends on VIRTIO && VHOST_USER + config VHOST_VDPA_DEV bool default y diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build index affd66887d..232178e217 100644 --- a/hw/virtio/meson.build +++ b/hw/virtio/meson.build @@ -61,6 +61,7 @@ system_virtio_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem.c')) system_virtio_ss.add(when: 'CONFIG_VIRTIO_NSM', if_true: files('virtio-nsm.c')) system_virtio_ss.add(when: 'CONFIG_VIRTIO_NSM', if_true: [files('cbor-helpers.c'), libcbor]) system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SCMI', if_true: files('vhost-user-scmi.c')) +system_virtio_ss.add(when: 'CONFIG_VHOST_USER_CONSOLE', if_true: files('vhost-user-console.c')) virtio_pci_ss = ss.source_set() virtio_pci_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock-pci.c')) @@ -82,6 +83,7 @@ virtio_pci_ss.add(when: 'CONFIG_VIRTIO_SCSI', if_true: files('virtio-scsi-pci.c' virtio_pci_ss.add(when: 'CONFIG_VIRTIO_BLK', if_true: files('virtio-blk-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VIRTIO_NET', if_true: files('virtio-net-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VIRTIO_SERIAL', if_true: files('virtio-serial-pci.c')) +virtio_pci_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_CONSOLE'], if_true: files('vhost-user-console-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VIRTIO_PMEM', if_true: files('virtio-pmem-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VIRTIO_IOMMU', if_true: files('virtio-iommu-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem-pci.c')) diff --git a/hw/virtio/vhost-user-console-pci.c b/hw/virtio/vhost-user-console-pci.c new file mode 100644 index 0000000000..6c856a3424 --- /dev/null +++ b/hw/virtio/vhost-user-console-pci.c @@ -0,0 +1,72 @@ +/* + * Vhost-user console virtio device PCI glue + * + * Copyright (c) 2024-2025 Timos Ampelikiotis <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/qdev-properties.h" +#include "hw/virtio/vhost-user-console.h" +#include "hw/virtio/virtio-pci.h" + +struct VHostUserConsolePCI { + VirtIOPCIProxy parent_obj; + VHostUserConsole vdev; +}; + +typedef struct VHostUserConsolePCI VHostUserConsolePCI; + +#define TYPE_VHOST_USER_CONSOLE_PCI "vhost-user-console-pci-base" + +DECLARE_INSTANCE_CHECKER(VHostUserConsolePCI, VHOST_USER_CONSOLE_PCI, + TYPE_VHOST_USER_CONSOLE_PCI) + +static void vhost_user_console_pci_realize(VirtIOPCIProxy *vpci_dev, + Error **errp) +{ + VHostUserConsolePCI *dev = VHOST_USER_CONSOLE_PCI(vpci_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + vpci_dev->nvectors = 1; + + qdev_realize(vdev, BUS(&vpci_dev->bus), errp); +} + +static void vhost_user_console_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_console_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_console_pci_instance_init(Object *obj) +{ + VHostUserConsolePCI *dev = VHOST_USER_CONSOLE_PCI(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VHOST_USER_CONSOLE); +} + +static const VirtioPCIDeviceTypeInfo vhost_user_console_pci_info = { + .base_name = TYPE_VHOST_USER_CONSOLE_PCI, + .non_transitional_name = "vhost-user-console-pci", + .instance_size = sizeof(VHostUserConsolePCI), + .instance_init = vhost_user_console_pci_instance_init, + .class_init = vhost_user_console_pci_class_init, +}; + +static void vhost_user_console_pci_register(void) +{ + virtio_pci_types_register(&vhost_user_console_pci_info); +} + +type_init(vhost_user_console_pci_register); diff --git a/hw/virtio/vhost-user-console.c b/hw/virtio/vhost-user-console.c new file mode 100644 index 0000000000..d1eba5bc34 --- /dev/null +++ b/hw/virtio/vhost-user-console.c @@ -0,0 +1,65 @@ +/* + * Vhost-user console virtio device + * + * Copyright (c) 2024-2025 Timos Ampelikiotis <[email protected]> + * + * Simple wrapper of the generic vhost-user-device. + * + * 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-console.h" +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_console.h" + +static const VMStateDescription vu_console_vmstate = { + .name = "vhost-user-console", + .unmigratable = 1, +}; + +static const Property vconsole_properties[] = { + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev), +}; + +static void vu_console_base_realize(DeviceState *dev, Error **errp) +{ + VHostUserBase *vub = VHOST_USER_BASE(dev); + VHostUserBaseClass *vubs = VHOST_USER_BASE_GET_CLASS(dev); + + vub->virtio_id = VIRTIO_ID_CONSOLE; + vub->num_vqs = 4; + vub->config_size = sizeof(struct virtio_console_config); + + vubs->parent_realize(dev, errp); +} + +static void vu_console_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass); + + dc->vmsd = &vu_console_vmstate; + device_class_set_props(dc, vconsole_properties); + device_class_set_parent_realize(dc, vu_console_base_realize, + &vubc->parent_realize); + + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + +static const TypeInfo vu_console_info = { + .name = TYPE_VHOST_USER_CONSOLE, + .parent = TYPE_VHOST_USER_BASE, + .instance_size = sizeof(VHostUserConsole), + .class_init = vu_console_class_init, +}; + +static void vu_console_register_types(void) +{ + type_register_static(&vu_console_info); +} + +type_init(vu_console_register_types) diff --git a/include/hw/virtio/vhost-user-console.h b/include/hw/virtio/vhost-user-console.h new file mode 100644 index 0000000000..261d62b756 --- /dev/null +++ b/include/hw/virtio/vhost-user-console.h @@ -0,0 +1,24 @@ +/* + * Vhost-user console virtio device + * + * Copyright (c) 2024-2025 Timos Ampelikiotis <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef QEMU_VHOST_USER_CONSOLE_H +#define QEMU_VHOST_USER_CONSOLE_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_CONSOLE "vhost-user-console" +OBJECT_DECLARE_SIMPLE_TYPE(VHostUserConsole, VHOST_USER_CONSOLE) + +struct VHostUserConsole { + VHostUserBase parent; +}; + +#endif /* QEMU_VHOST_USER_CONSOLE_H */ -- 2.43.0
