[PATCH 13/17] kvm tools: irq: move irq line allocation into device registration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For the MMIO and PCI buses, drivers typically allocate an IRQ line for
their device before registering the device with the device tree for the
relevant bus.

This patch moves the IRQ allocation into the bus code, which is then
called directly by the device tree when a new device is registered.
IOPORT devices, however, tend to use hardcoded IRQs for legacy reasons,
so they are still required to deal with their interrupts (which also
require remapping for non-x86 architectures).

Signed-off-by: Will Deacon <will.deacon@xxxxxxx>
---
 tools/kvm/devices.c                 | 13 +++++++++++++
 tools/kvm/hw/pci-shmem.c            |  4 ----
 tools/kvm/hw/vesa.c                 |  2 --
 tools/kvm/include/kvm/pci.h         |  2 ++
 tools/kvm/include/kvm/virtio-mmio.h |  1 +
 tools/kvm/pci.c                     | 15 +++++++++++++++
 tools/kvm/virtio/mmio.c             |  9 ++++++++-
 tools/kvm/virtio/pci.c              |  2 --
 8 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/tools/kvm/devices.c b/tools/kvm/devices.c
index 5b627e9adee2..b560a59944e0 100644
--- a/tools/kvm/devices.c
+++ b/tools/kvm/devices.c
@@ -1,5 +1,7 @@
 #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>
@@ -27,6 +29,17 @@ int device__register(struct device_header *dev)
 	bus = &device_trees[dev->bus_type];
 	dev->dev_num = bus->dev_num++;
 
+	switch (dev->bus_type) {
+	case DEVICE_BUS_PCI:
+		pci__assign_irq(dev);
+		break;
+	case DEVICE_BUS_MMIO:
+		virtio_mmio_assign_irq(dev);
+		break;
+	default:
+		break;
+	}
+
 	node = &bus->root.rb_node;
 	while (*node) {
 		int num = rb_entry(*node, struct device_header, node)->dev_num;
diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c
index 057118332981..34de74770ea9 100644
--- a/tools/kvm/hw/pci-shmem.c
+++ b/tools/kvm/hw/pci-shmem.c
@@ -358,10 +358,6 @@ int pci_shmem__init(struct kvm *kvm)
 	if (shmem_region == NULL)
 		return 0;
 
-	/* Register good old INTx */
-	pci_shmem_pci_device.irq_pin = 1;
-	pci_shmem_pci_device.irq_line = irq__alloc_line();
-
 	/* Register MMIO space for MSI-X */
 	r = ioport__register(kvm, IOPORT_EMPTY, &shmem_pci__io_ops, IOPORT_SIZE, NULL);
 	if (r < 0)
diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c
index c7b8e66cc531..a0b15a77998b 100644
--- a/tools/kvm/hw/vesa.c
+++ b/tools/kvm/hw/vesa.c
@@ -65,8 +65,6 @@ struct framebuffer *vesa__init(struct kvm *kvm)
 	if (r < 0)
 		return ERR_PTR(r);
 
-	vesa_pci_device.irq_pin		= 1;
-	vesa_pci_device.irq_line	= irq__alloc_line();
 	vesa_base_addr			= (u16)r;
 	vesa_pci_device.bar[0]		= cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO);
 	device__register(&vesa_device);
diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index e1e621d51470..b0c28a10af6a 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -6,6 +6,7 @@
 #include <linux/pci_regs.h>
 #include <endian.h>
 
+#include "kvm/devices.h"
 #include "kvm/kvm.h"
 #include "kvm/msi.h"
 
@@ -88,6 +89,7 @@ int pci__init(struct kvm *kvm);
 int pci__exit(struct kvm *kvm);
 struct pci_device_header *pci__find_dev(u8 dev_num);
 u32 pci_get_io_space_block(u32 size);
+void pci__assign_irq(struct device_header *dev_hdr);
 void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size);
 void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size);
 
diff --git a/tools/kvm/include/kvm/virtio-mmio.h b/tools/kvm/include/kvm/virtio-mmio.h
index 4d6a671c79c5..835f421bcb8d 100644
--- a/tools/kvm/include/kvm/virtio-mmio.h
+++ b/tools/kvm/include/kvm/virtio-mmio.h
@@ -56,4 +56,5 @@ int virtio_mmio_signal_config(struct kvm *kvm, struct virtio_device *vdev);
 int virtio_mmio_exit(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/tools/kvm/pci.c b/tools/kvm/pci.c
index c4442c85b5cf..c2da15252019 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -1,6 +1,7 @@
 #include "kvm/devices.h"
 #include "kvm/pci.h"
 #include "kvm/ioport.h"
+#include "kvm/irq.h"
 #include "kvm/util.h"
 #include "kvm/kvm.h"
 
@@ -28,6 +29,20 @@ u32 pci_get_io_space_block(u32 size)
 	return block;
 }
 
+void pci__assign_irq(struct device_header *dev_hdr)
+{
+	struct pci_device_header *pci_hdr = dev_hdr->data;
+
+	/*
+	 * PCI supports only INTA#,B#,C#,D# per device.
+	 *
+	 * A#,B#,C#,D# are allowed for multifunctional devices so stick
+	 * with A# for our single function devices.
+	 */
+	pci_hdr->irq_pin	= 1;
+	pci_hdr->irq_line	= irq__alloc_line();
+}
+
 static void *pci_config_address_ptr(u16 port)
 {
 	unsigned long offset;
diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c
index 1cb186b452e6..e1fca2b05546 100644
--- a/tools/kvm/virtio/mmio.c
+++ b/tools/kvm/virtio/mmio.c
@@ -256,6 +256,14 @@ 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)
 {
@@ -276,7 +284,6 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 		.queue_num_max	= 256,
 	};
 
-	vmmio->irq = irq__alloc_line();
 	vmmio->dev_hdr = (struct device_header) {
 		.bus_type	= DEVICE_BUS_MMIO,
 		.data		= generate_virtio_mmio_fdt_node,
diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index dbd67580fb03..fa7aa0021a29 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -408,8 +408,6 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 	if (kvm__supports_extension(kvm, KVM_CAP_SIGNAL_MSI))
 		vpci->features |= VIRTIO_PCI_F_SIGNAL_MSI;
 
-	vpci->pci_hdr.irq_pin	= 1;
-	vpci->pci_hdr.irq_line	= irq__alloc_line();
 	r = device__register(&vpci->dev_hdr);
 	if (r < 0)
 		goto free_msix_mmio;
-- 
1.8.2.2

_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm




[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux