This Friday hack was driven by wanting to review some virtiofsd changes. However I discovered that while virtiofsd support VHOST_USER_PROTOCOL_F_CONFIG the current virtiofs stubs still assume QEMU controls the config space.
Ahh I thought, but we have vhost-user-base which both supports this and provides for a very minimal boilerplate implementation of the various VirtIO devices. However s390x being a special beast doesn't use mmio or pci transports but has its own special ccw transport. Perhaps I could just follow the existing ccw devices and implement the wrapper. So here we are: ./qemu-system-s390x -serial mon:stdio \ -M s390-ccw-virtio -m 2048M -smp 2 \ -drive file=/home/alex/lsrc/tests/buildroot.git/builds/s390x/images/rootfs.ext4,if=virtio,format=raw -snapshot \ -kernel /home/alex/lsrc/linux.git/builds/s390x/arch/s390/boot/bzImage \ -append "root=/dev/vda console=ttyS0" -display none \ -chardev socket,id=vfs,path=/tmp/virtiofsd.sock \ -device vhost-user-device-ccw,chardev=vfs,virtio-id=26,config_size=44,num_vqs=1 -s -S with: ./target/debug/virtiofsd --shared-dir $HOME \ --socket-path /tmp/virtiofsd.sock --tag home --log-level debug and the kernel gets surprisingly far before oopsing: [ 2.084873] virtio_blk virtio1: 1/0/0 default/read/poll queues [ 2.097845] virtiofs virtio2: discovered new tag: home heh I think GET_CONFIG worked because the tag can only have come from the daemon. [ 2.101920] Segment Routing with IPv6 [ 2.102040] RPL Segment Routing with IPv6 [ 2.102326] In-situ OAM (IOAM) with IPv6 [ 2.103443] NET: Registered PF_PACKET protocol family [ 2.103848] virtio_blk virtio1: [vda] 122880 512-byte logical blocks (62.9 MB/60.0 MiB) [ 2.104918] Key type dns_resolver registered [ 2.106171] virtiofs virtio2: probe with driver virtiofs failed with error -2 Hmm disappointing... [ 2.113538] Unable to handle kernel pointer dereference in virtual kernel address space [ 2.113650] Failing address: 766461000242c000 TEID: 766461000242c803 [ 2.113697] Fault in home space mode while using kernel ASCE. [ 2.113881] AS:0000000001e08007 R3:0000000000000024 [ 2.114679] Oops: 0038 ilc:3 [#1] SMP [ 2.114837] Modules linked in: [ 2.115351] CPU: 1 UID: 0 PID: 30 Comm: kworker/u10:1 Not tainted 6.14.5-ajb #8 [ 2.115629] Hardware name: QEMU 8561 QEMU (KVM/Linux) [ 2.115850] Workqueue: async async_run_entry_fn At which point my attempts to debug the s390 kernel failed because the debug symbols don't seem to match where the kernel lives. Also its Friday and I have a cold beer waiting for me in the fridge. So it seems frustratingly close to being functional but as I'm going to be away for a week I thought it was worth posting as an RFC in case anyone wants to take a closer look. Signed-off-by: Alex Bennée <alex.ben...@linaro.org> --- hw/s390x/vhost-user-device-ccw.c | 75 ++++++++++++++++++++++++++++++++ hw/s390x/meson.build | 18 +++++--- 2 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 hw/s390x/vhost-user-device-ccw.c diff --git a/hw/s390x/vhost-user-device-ccw.c b/hw/s390x/vhost-user-device-ccw.c new file mode 100644 index 0000000000..03881efc02 --- /dev/null +++ b/hw/s390x/vhost-user-device-ccw.c @@ -0,0 +1,75 @@ +/* + * Vhost-user generic device virtio-ccw glue + * + * Copyright (c) 2025 Linaro Ltd. + * Author: Alex Bennée <alex.ben...@linaro.org> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/qdev-properties.h" +#include "hw/virtio/vhost-user-base.h" +#include "virtio-ccw.h" + +struct VHostUserDeviceCCW { + VirtioCcwDevice parent_obj; + + VHostUserBase vub; +}; + +static const Property vhost_user_ccw_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, + VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, + VIRTIO_CCW_MAX_REV), +}; + +#define TYPE_VHOST_USER_DEVICE_CCW "vhost-user-device-ccw" + +OBJECT_DECLARE_SIMPLE_TYPE(VHostUserDeviceCCW, VHOST_USER_DEVICE_CCW) + +static void vhost_user_device_ccw_realize(VirtioCcwDevice *ccw_dev, Error **errp) +{ + VHostUserDeviceCCW *dev = VHOST_USER_DEVICE_CCW(ccw_dev); + DeviceState *vdev = DEVICE(&dev->vub); + + qdev_realize(vdev, BUS(&ccw_dev->bus), errp); +} + +static void vhost_user_device_ccw_instance_init(Object *obj) +{ + VHostUserDeviceCCW *dev = VHOST_USER_DEVICE_CCW(obj); + VirtioCcwDevice *ccw_dev = VIRTIO_CCW_DEVICE(obj); + + ccw_dev->force_revision_1 = true; + virtio_instance_init_common(obj, &dev->vub, sizeof(dev->vub), + TYPE_VHOST_USER_DEVICE); +} + +static void vhost_user_device_ccw_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); + + /* Reason: stop users confusing themselves */ + /* dc->user_creatable = false; */ + + k->realize = vhost_user_device_ccw_realize; + device_class_set_props(dc, vhost_user_ccw_properties); +} + +static const TypeInfo vhost_user_device_ccw = { + .name = TYPE_VHOST_USER_DEVICE_CCW, + .parent = TYPE_VIRTIO_CCW_DEVICE, + .instance_size = sizeof(VHostUserDeviceCCW), + .instance_init = vhost_user_device_ccw_instance_init, + .class_init = vhost_user_device_ccw_class_init, +}; + +static void vhost_user_device_ccw_register(void) +{ + type_register_static(&vhost_user_device_ccw); +} + +type_init(vhost_user_device_ccw_register) diff --git a/hw/s390x/meson.build b/hw/s390x/meson.build index 3bbebfd817..a311ccca8d 100644 --- a/hw/s390x/meson.build +++ b/hw/s390x/meson.build @@ -44,14 +44,22 @@ virtio_ss.add(when: 'CONFIG_VIRTIO_NET', if_true: files('virtio-ccw-net.c')) virtio_ss.add(when: 'CONFIG_VIRTIO_RNG', if_true: files('virtio-ccw-rng.c')) virtio_ss.add(when: 'CONFIG_VIRTIO_SCSI', if_true: files('virtio-ccw-scsi.c')) virtio_ss.add(when: 'CONFIG_VIRTIO_SERIAL', if_true: files('virtio-ccw-serial.c')) +virtio_ss.add(when: 'CONFIG_VIRTIO_MD', if_true: files('virtio-ccw-md.c')) +virtio_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-ccw-mem.c')) if have_virtfs virtio_ss.add(when: 'CONFIG_VIRTIO_9P', if_true: files('virtio-ccw-9p.c')) endif -virtio_ss.add(when: 'CONFIG_VHOST_SCSI', if_true: files('vhost-scsi-ccw.c')) -virtio_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock-ccw.c')) -virtio_ss.add(when: 'CONFIG_VHOST_USER_FS', if_true: files('vhost-user-fs-ccw.c')) -virtio_ss.add(when: 'CONFIG_VIRTIO_MD', if_true: files('virtio-ccw-md.c')) -virtio_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-ccw-mem.c')) + +if have_vhost + virtio_ss.add(when: 'CONFIG_VHOST_SCSI', if_true: files('vhost-scsi-ccw.c')) + virtio_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock-ccw.c')) + + if have_vhost_user + virtio_ss.add(files('vhost-user-device-ccw.c')) + virtio_ss.add(when: 'CONFIG_VHOST_USER_FS', if_true: files('vhost-user-fs-ccw.c')) + endif +endif + s390x_ss.add_all(when: 'CONFIG_VIRTIO_CCW', if_true: virtio_ss) s390x_ss.add(when: 'CONFIG_VIRTIO_MD', if_false: files('virtio-ccw-md-stubs.c')) -- 2.39.5