From: Timos Ampelikiotis <[email protected]> Add vhost-user-can device, which has been tested with latest vhost-device-can (see https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-can) and the virtio-can driver v6 (see https://lore.kernel.org/all/aQJRnX7OpFRY%2F1+H@fedora/).
Signed-off-by: Timos Ampelikiotis <[email protected]> Signed-off-by: Matias Ezequiel Vara Larsen <[email protected]> Tested-by: Matias Ezequiel Vara Larsen <[email protected]> --- hw/net/Kconfig | 5 +++ hw/net/can/meson.build | 3 ++ hw/net/can/vhost-user-can-pci.c | 69 +++++++++++++++++++++++++++++++++ hw/net/can/vhost-user-can.c | 65 +++++++++++++++++++++++++++++++ include/hw/net/vhost-user-can.h | 26 +++++++++++++ 5 files changed, 168 insertions(+) create mode 100644 hw/net/can/vhost-user-can-pci.c create mode 100644 hw/net/can/vhost-user-can.c create mode 100644 include/hw/net/vhost-user-can.h diff --git a/hw/net/Kconfig b/hw/net/Kconfig index 2b513d6895..c6fe5b4376 100644 --- a/hw/net/Kconfig +++ b/hw/net/Kconfig @@ -160,3 +160,8 @@ config CAN_CTUCANFD_PCI default y if PCI_DEVICES depends on PCI && CAN_CTUCANFD select CAN_BUS + +config VHOST_USER_CAN + bool + default y + depends on VIRTIO && VHOST_USER diff --git a/hw/net/can/meson.build b/hw/net/can/meson.build index 7382344628..1796a89820 100644 --- a/hw/net/can/meson.build +++ b/hw/net/can/meson.build @@ -4,5 +4,8 @@ system_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_pcm3680_pci.c')) system_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_mioe3680_pci.c')) system_ss.add(when: 'CONFIG_CAN_CTUCANFD', if_true: files('ctucan_core.c')) system_ss.add(when: 'CONFIG_CAN_CTUCANFD_PCI', if_true: files('ctucan_pci.c')) +system_ss.add(when: 'CONFIG_VHOST_USER_CAN', if_true: files('vhost-user-can.c')) +system_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_CAN'], + if_true: files('vhost-user-can-pci.c')) system_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-can.c')) system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-canfd.c')) diff --git a/hw/net/can/vhost-user-can-pci.c b/hw/net/can/vhost-user-can-pci.c new file mode 100644 index 0000000000..e525d28ab1 --- /dev/null +++ b/hw/net/can/vhost-user-can-pci.c @@ -0,0 +1,69 @@ +/* + * Vhost-user CAN virtio device PCI glue + * + * Copyright (c) 2024 Timos Ampelikiotis <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/net/vhost-user-can.h" +#include "hw/virtio/virtio-pci.h" + +struct VHostUserCanPCI { + VirtIOPCIProxy parent_obj; + VHostUserCan vdev; +}; + +typedef struct VHostUserCanPCI VHostUserCanPCI; + +#define TYPE_VHOST_USER_CAN_PCI "vhost-user-can-pci-base" + +DECLARE_INSTANCE_CHECKER(VHostUserCanPCI, VHOST_USER_CAN_PCI, + TYPE_VHOST_USER_CAN_PCI) + +static void vhost_user_can_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) +{ + VHostUserCanPCI *dev = VHOST_USER_CAN_PCI(vpci_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + vpci_dev->nvectors = 1; + + qdev_realize(vdev, BUS(&vpci_dev->bus), errp); +} + +static void vhost_user_can_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_can_pci_realize; + set_bit(DEVICE_CATEGORY_NETWORK, 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_SERIAL_CANBUS; +} + +static void vhost_user_can_pci_instance_init(Object *obj) +{ + VHostUserCanPCI *dev = VHOST_USER_CAN_PCI(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VHOST_USER_CAN); +} + +static const VirtioPCIDeviceTypeInfo vhost_user_can_pci_info = { + .base_name = TYPE_VHOST_USER_CAN_PCI, + .non_transitional_name = "vhost-user-can-pci", + .instance_size = sizeof(VHostUserCanPCI), + .instance_init = vhost_user_can_pci_instance_init, + .class_init = vhost_user_can_pci_class_init, +}; + +static void vhost_user_can_pci_register(void) +{ + virtio_pci_types_register(&vhost_user_can_pci_info); +} + +type_init(vhost_user_can_pci_register); diff --git a/hw/net/can/vhost-user-can.c b/hw/net/can/vhost-user-can.c new file mode 100644 index 0000000000..acab1f64ee --- /dev/null +++ b/hw/net/can/vhost-user-can.c @@ -0,0 +1,65 @@ +/* + * Vhost-user CAN virtio device + * + * Copyright (c) 2024 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/net/vhost-user-can.h" +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_can.h" + +static const VMStateDescription vu_can_vmstate = { + .name = "vhost-user-can", + .unmigratable = 1, +}; + +static const Property vcan_properties[] = { + DEFINE_PROP_CHR("chardev", VHostUserBase, chardev), +}; + +static void vu_can_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_CAN; + vub->num_vqs = 3; + vub->config_size = sizeof(struct virtio_can_config); + + vubs->parent_realize(dev, errp); +} + +static void vu_can_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass); + + dc->vmsd = &vu_can_vmstate; + device_class_set_props(dc, vcan_properties); + device_class_set_parent_realize(dc, vu_can_base_realize, + &vubc->parent_realize); + + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); +} + +static const TypeInfo vu_can_info = { + .name = TYPE_VHOST_USER_CAN, + .parent = TYPE_VHOST_USER_BASE, + .instance_size = sizeof(VHostUserCan), + .class_init = vu_can_class_init, +}; + +static void vu_can_register_types(void) +{ + type_register_static(&vu_can_info); +} + +type_init(vu_can_register_types) diff --git a/include/hw/net/vhost-user-can.h b/include/hw/net/vhost-user-can.h new file mode 100644 index 0000000000..38bc261ce7 --- /dev/null +++ b/include/hw/net/vhost-user-can.h @@ -0,0 +1,26 @@ +/* + * Vhost-user Can virtio device + * + * Copyright (c) 2024 Timos Ampelikiotis <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef QEMU_VHOST_USER_CAN_H +#define QEMU_VHOST_USER_CAN_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_CAN "vhost-user-can" +OBJECT_DECLARE_SIMPLE_TYPE(VHostUserCan, VHOST_USER_CAN) + +struct VHostUserCan { + /*< private >*/ + VHostUserBase parent; + /*< public >*/ +}; + +#endif /* QEMU_VHOST_USER_CAN_H */ -- 2.42.0
