At the moment the IRQ line for a virtio-mmio device is assigned in the generic device__register() routine in devices.c, by calling back into virtio-mmio.c. This does not only sound slightly convoluted, but also breaks when we try to register an MMIO device that is not a virtio-mmio device. In this case container_of will return a bogus pointer (as it assumes a struct virtio_mmio), and the IRQ allocation routine will corrupt some data in the device_header (for instance the first byte of the "data" pointer). Simply assign the IRQ directly in virtio_mmio_init(), before calling device__register(). This avoids the problem and looks actually much more straightforward. Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> --- devices.c | 4 ---- include/kvm/virtio-mmio.h | 1 - virtio/mmio.c | 10 ++-------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/devices.c b/devices.c index a7c666a7..2c8b2665 100644 --- a/devices.c +++ b/devices.c @@ -1,7 +1,6 @@ #include "kvm/devices.h" #include "kvm/kvm.h" #include "kvm/pci.h" -#include "kvm/virtio-mmio.h" #include <linux/err.h> #include <linux/rbtree.h> @@ -33,9 +32,6 @@ int device__register(struct device_header *dev) case DEVICE_BUS_PCI: pci__assign_irq(dev); break; - case DEVICE_BUS_MMIO: - virtio_mmio_assign_irq(dev); - break; default: break; } diff --git a/include/kvm/virtio-mmio.h b/include/kvm/virtio-mmio.h index 0528947a..6bc50bd1 100644 --- a/include/kvm/virtio-mmio.h +++ b/include/kvm/virtio-mmio.h @@ -57,5 +57,4 @@ int virtio_mmio_exit(struct kvm *kvm, struct virtio_device *vdev); int virtio_mmio_reset(struct kvm *kvm, struct virtio_device *vdev); int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class); -void virtio_mmio_assign_irq(struct device_header *dev_hdr); #endif diff --git a/virtio/mmio.c b/virtio/mmio.c index 5537c393..875a288c 100644 --- a/virtio/mmio.c +++ b/virtio/mmio.c @@ -280,14 +280,6 @@ static void generate_virtio_mmio_fdt_node(void *fdt, } #endif -void virtio_mmio_assign_irq(struct device_header *dev_hdr) -{ - struct virtio_mmio *vmmio = container_of(dev_hdr, - struct virtio_mmio, - dev_hdr); - vmmio->irq = irq__alloc_line(); -} - int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, int device_id, int subsys_id, int class) { @@ -316,6 +308,8 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, .data = generate_virtio_mmio_fdt_node, }; + vmmio->irq = irq__alloc_line(); + r = device__register(&vmmio->dev_hdr); if (r < 0) { kvm__deregister_mmio(kvm, vmmio->addr); -- 2.17.1