From patchwork Tue Feb 4 16:53:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Deacon X-Patchwork-Id: 3577981 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B2702C02DC for ; Tue, 4 Feb 2014 16:55:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C130F2018E for ; Tue, 4 Feb 2014 16:55:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C515A2018B for ; Tue, 4 Feb 2014 16:55:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932242AbaBDQy3 (ORCPT ); Tue, 4 Feb 2014 11:54:29 -0500 Received: from cam-admin0.cambridge.arm.com ([217.140.96.50]:49663 "EHLO cam-admin0.cambridge.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932244AbaBDQy1 (ORCPT ); Tue, 4 Feb 2014 11:54:27 -0500 Received: from mudshark.cambridge.arm.com (mudshark.cambridge.arm.com [10.1.203.36]) by cam-admin0.cambridge.arm.com (8.12.6/8.12.6) with ESMTP id s14Gs9kk003406; Tue, 4 Feb 2014 16:54:10 GMT Received: by mudshark.cambridge.arm.com (Postfix, from userid 1000) id 28AF6C2B19; Tue, 4 Feb 2014 16:54:09 +0000 (GMT) From: Will Deacon To: kvm@vger.kernel.org Cc: kvmarm@lists.cs.columbia.edu, penberg@kernel.org, marc.zyngier@arm.com, arnd@arndb.de, Will Deacon Subject: [PATCH 09/17] kvm tools: irq: replace the x86 irq rbtree with the PCI device tree Date: Tue, 4 Feb 2014 16:53:57 +0000 Message-Id: <1391532845-2177-10-git-send-email-will.deacon@arm.com> X-Mailer: git-send-email 1.8.2.2 In-Reply-To: <1391532845-2177-1-git-send-email-will.deacon@arm.com> References: <1391532845-2177-1-git-send-email-will.deacon@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 #include @@ -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); } /*