rust-vmm / vhost-device

'vhost-user' device backends workspace
Apache License 2.0
69 stars 47 forks source link

Problem with interrupt support for vhost-device-gpio and QEMU 8.1.1 #613

Open wzab opened 9 months ago

wzab commented 9 months ago

I tried to test connecting simulated GPIO peripherals to QEMU using vhost-device-gpio. I have successfully built the vhost-device-gpio (with cargo build --features "mock_gpio") and tried to connect it to the Linux running on a qemu-aarch64-virt machine, built with Buildroot version 2023.11.1.

Of course, I had to add CONFIG_GPIO_VIRTIO=m in the Linux kernel configuration.

In the virtual machine, I have loaded the driver with modprobe gpio-virtio. Then, I could access the simulated GPIO controlling the direction and values. However, when I tried to test interrupt functionality with gpiomon 0 0, I got an error:

# gpiomon 0 0
gpiomon: error waiting for events: No such device

After some investigations, I have found the cause. The feature VIRTIO_GPIO_F_IRQ was not set for the created virtio gpio device. Further investigation required compiling QEMU with debugging symbols and running it under gdb.

With that, I could find that the problem is caused by the fact that this flag is not set in the host_features in virtio-pci.c source in QEMU. As a quick workaround, I have modified the function virtio_pci_pre_plugged, adding the lacking feature here:

static void virtio_pci_pre_plugged(DeviceState *d, Error **errp)
{
    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

    if (virtio_pci_modern(proxy)) {
        virtio_add_feature(&vdev->host_features, 0); /* VIRTIO_GPIO_F_IRQ - added by WZab as a quick&dirty workaround */ 
        virtio_add_feature(&vdev->host_features, VIRTIO_F_VERSION_1);
    }

    virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE);
}

With such a modified QEMU, I was able to activate emulation of IRQs with vhost-device-gpio. That is a QEMU problem, but it is highly specific to vhost-device-gpio. Therefore, I've described it here.

wzab commented 9 months ago

With the above modification, the Linux kernel displays a complaint:

gpio gpiochip0: (virtio2): not an immutable chip, please consider fixing it!
stefano-garzarella commented 9 months ago

@wzab thanks for opening this issue. @vireshk can you take a look? Thanks!

vireshk commented 9 months ago

@wzab I never tested it with PCI but MMIO and it worked. Please send a fix to QEMU mailing list for this. Thanks.

vireshk commented 9 months ago

With the above modification, the Linux kernel displays a complaint:

gpio gpiochip0: (virtio2): not an immutable chip, please consider fixing it!

Yeah, the irq chip needs some minor changes. If you are okay, then please send a fix for that. I can review it for you.

Something like this:

f56914393537 gpio: zynq: fix zynqmp_gpio not an immutable chip warning

wzab commented 9 months ago

@wzab I never tested it with PCI but MMIO and it worked. Please send a fix to QEMU mailing list for this. Thanks.

I have created the related issue in QEMU repository: https://gitlab.com/qemu-project/qemu/-/issues/2167