kvm tools: irq: move irq line allocation into device registration

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@arm.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
Will Deacon
2014-02-04 16:54:01 +00:00
parent 9dc5430ce7
commit b59816369a
8 changed files with 39 additions and 9 deletions
+13
View File
@@ -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;
-4
View File
@@ -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)
-2
View File
@@ -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);
+2
View File
@@ -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);
+1
View File
@@ -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
+15
View File
@@ -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;
+8 -1
View File
@@ -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,
-2
View File
@@ -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;