aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2020-04-23 18:38:40 +0100
committerWill Deacon <will@kernel.org>2020-04-24 17:58:49 +0100
commitaf731be31279c5f98530cf5af121e08b09af7f95 (patch)
tree4e70660cf19da3a266603b76c5031cbc02bc09a5
parente554aefd04bd38a8b6e9040022d494e5b7ae7a59 (diff)
downloadkvmtool-af731be31279c5f98530cf5af121e08b09af7f95.tar.gz
virtio-mmio: Assign IRQ line directly before registering device
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. Tested-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--devices.c4
-rw-r--r--include/kvm/virtio-mmio.h1
-rw-r--r--virtio/mmio.c10
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);