[PATCH 09/17] kvm tools: irq: replace the x86 irq rbtree with the PCI device tree

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

 



The x86 code keeps its own rbtree of PCI devices in order to allocate
interrupts. However, this functionality can be moved into the generic
PCI device tree and be reused by other architectures.

This patch removes the x86 tree and reworks the ACPI mptable generation
to use the PCI device tree for enumerating the bus.

Signed-off-by: Will Deacon <will.deacon@xxxxxxx>
---
 tools/kvm/include/kvm/irq.h |  14 ------
 tools/kvm/x86/irq.c         | 109 +-------------------------------------------
 tools/kvm/x86/mptable.c     |  35 ++++++--------
 3 files changed, 15 insertions(+), 143 deletions(-)

diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h
index 20213c064b0b..7652b8587464 100644
--- a/tools/kvm/include/kvm/irq.h
+++ b/tools/kvm/include/kvm/irq.h
@@ -10,22 +10,8 @@
 
 struct kvm;
 
-struct irq_line {
-	u8			line;
-	struct list_head	node;
-};
-
-struct pci_dev {
-	struct rb_node		node;
-	u32			id;
-	u8			pin;
-	struct list_head	lines;
-};
-
 int irq__register_device(u32 dev, u8 *line);
 
-struct rb_node *irq__get_pci_tree(void);
-
 int irq__init(struct kvm *kvm);
 int irq__exit(struct kvm *kvm);
 int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg);
diff --git a/tools/kvm/x86/irq.c b/tools/kvm/x86/irq.c
index 17db2110e96f..ef5ec34aebff 100644
--- a/tools/kvm/x86/irq.c
+++ b/tools/kvm/x86/irq.c
@@ -17,7 +17,6 @@
 #define IRQCHIP_IOAPIC			2
 
 static u8		next_line	= 5;
-static struct rb_root	pci_tree	= RB_ROOT;
 
 /* First 24 GSIs are routed between IRQCHIPs and IOAPICs */
 static u32 gsi = 24;
@@ -40,92 +39,10 @@ static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin)
 	return 0;
 }
 
-static struct pci_dev *search(struct rb_root *root, u32 id)
-{
-	struct rb_node *node = root->rb_node;
-
-	while (node) {
-		struct pci_dev *data = rb_entry(node, struct pci_dev, node);
-		int result;
-
-		result = id - data->id;
-
-		if (result < 0)
-			node = node->rb_left;
-		else if (result > 0)
-			node = node->rb_right;
-		else
-			return data;
-	}
-	return NULL;
-}
-
-static int insert(struct rb_root *root, struct pci_dev *data)
-{
-	struct rb_node **new = &(root->rb_node), *parent = NULL;
-
-	/* Figure out where to put new node */
-	while (*new) {
-		struct pci_dev *this	= container_of(*new, struct pci_dev, node);
-		int result		= data->id - this->id;
-
-		parent = *new;
-		if (result < 0)
-			new = &((*new)->rb_left);
-		else if (result > 0)
-			new = &((*new)->rb_right);
-		else
-			return -EEXIST;
-	}
-
-	/* Add new node and rebalance tree. */
-	rb_link_node(&data->node, parent, new);
-	rb_insert_color(&data->node, root);
-
-	return 0;
-}
-
 int irq__register_device(u32 dev, u8 *line)
 {
-	struct pci_dev *node;
-	int r;
-
-	node = search(&pci_tree, dev);
-
-	if (!node) {
-		/* We haven't found a node - First device of it's kind */
-		node = malloc(sizeof(*node));
-		if (node == NULL)
-			return -ENOMEM;
-
-		*node = (struct pci_dev) {
-			.id	= dev,
-		};
-
-		INIT_LIST_HEAD(&node->lines);
-
-		r = insert(&pci_tree, node);
-		if (r) {
-			free(node);
-			return r;
-		}
-	}
-
-	if (node) {
-		/* This device already has a pin assigned, give out a new line and device id */
-		struct irq_line *new = malloc(sizeof(*new));
-		if (new == NULL)
-			return -ENOMEM;
-
-		new->line	= next_line++;
-		*line		= new->line;
-
-		list_add(&new->node, &node->lines);
-
-		return 0;
-	}
-
-	return -EFAULT;
+	*line = next_line++;
+	return 0;
 }
 
 int irq__init(struct kvm *kvm)
@@ -166,24 +83,7 @@ dev_base_init(irq__init);
 
 int irq__exit(struct kvm *kvm)
 {
-	struct rb_node *ent;
-
 	free(irq_routing);
-
-	while ((ent = rb_first(&pci_tree))) {
-		struct pci_dev *dev;
-		struct irq_line *line;
-
-		dev = rb_entry(ent, struct pci_dev, node);
-		while (!list_empty(&dev->lines)) {
-			line = list_first_entry(&dev->lines, struct irq_line, node);
-			list_del(&line->node);
-			free(line);
-		}
-		rb_erase(&dev->node, &pci_tree);
-		free(dev);
-	}
-
 	return 0;
 }
 dev_base_exit(irq__exit);
@@ -207,8 +107,3 @@ int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg)
 
 	return gsi++;
 }
-
-struct rb_node *irq__get_pci_tree(void)
-{
-	return rb_first(&pci_tree);
-}
diff --git a/tools/kvm/x86/mptable.c b/tools/kvm/x86/mptable.c
index ea8c6e8c848f..a984de9eca9c 100644
--- a/tools/kvm/x86/mptable.c
+++ b/tools/kvm/x86/mptable.c
@@ -3,7 +3,8 @@
 #include "kvm/apic.h"
 #include "kvm/mptable.h"
 #include "kvm/util.h"
-#include "kvm/irq.h"
+#include "kvm/devices.h"
+#include "kvm/pci.h"
 
 #include <linux/kernel.h>
 #include <string.h>
@@ -80,7 +81,7 @@ int mptable__init(struct kvm *kvm)
 	struct mpc_bus *mpc_bus;
 	struct mpc_ioapic *mpc_ioapic;
 	struct mpc_intsrc *mpc_intsrc;
-	struct rb_node *pci_tree;
+	struct device_header *dev_hdr;
 
 	const int pcibusid = 0;
 	const int isabusid = 1;
@@ -171,31 +172,21 @@ int mptable__init(struct kvm *kvm)
 
 	/*
 	 * IRQ sources.
-	 *
-	 * FIXME: Same issue as with buses. We definitely
-	 * need kind of collector routine which enumerate
-	 * resources used first and pass them here.
-	 * At moment we know we have only virtio block device
-	 * and virtio console but this is g00berfish.
-	 *
 	 * Also note we use PCI irqs here, no for ISA bus yet.
 	 */
 
-	for (pci_tree = irq__get_pci_tree(); pci_tree; pci_tree = rb_next(pci_tree)) {
-		struct pci_dev *dev = rb_entry(pci_tree, struct pci_dev, node);
-		struct irq_line *irq_line;
+	dev_hdr = device__first_dev(DEVICE_BUS_PCI);
+	while (dev_hdr) {
+		unsigned char srcbusirq;
+		struct pci_device_header *pci_hdr = dev_hdr->data;
 
-		list_for_each_entry(irq_line, &dev->lines, node) {
-			unsigned char srcbusirq;
+		srcbusirq = (pci_hdr->subsys_id << 2) | (pci_hdr->irq_pin - 1);
+		mpc_intsrc = last_addr;
+		mptable_add_irq_src(mpc_intsrc, pcibusid, srcbusirq, ioapicid, pci_hdr->irq_line);
 
-			srcbusirq = (dev->id << 2) | (dev->pin - 1);
-
-			mpc_intsrc = last_addr;
-
-			mptable_add_irq_src(mpc_intsrc, pcibusid, srcbusirq, ioapicid, irq_line->line);
-			last_addr = (void *)&mpc_intsrc[1];
-			nentries++;
-		}
+		last_addr = (void *)&mpc_intsrc[dev_hdr->dev_num];
+		nentries++;
+		dev_hdr = device__next_dev(dev_hdr);
 	}
 
 	/*
-- 
1.8.2.2

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux