From patchwork Fri May 6 11:24:10 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 761952 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p46BOj01025641 for ; Fri, 6 May 2011 11:24:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755303Ab1EFLYl (ORCPT ); Fri, 6 May 2011 07:24:41 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:43965 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755265Ab1EFLYk (ORCPT ); Fri, 6 May 2011 07:24:40 -0400 Received: by wwa36 with SMTP id 36so3407754wwa.1 for ; Fri, 06 May 2011 04:24:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer; bh=/Z8Oa+EERZ0Be5wj6R73ejYwoZW+7sTmAXLiKOhy1lU=; b=JNQBDm2onsbPmSPtq8Hk7yB4egedV5sI/d+nZUQU0KCootnCcg2UIRsXtOXiujqiWG u0//ZxWU+JOJnDITI7ceGOER/iunbBN9RUxTN4XdyeU2Y3b/fgZODwo12tlLNZJqcGAQ mh4JhpOBD1VB4B8cM0LqDLsjxbp1S5ZOUv4gc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=PKnS+cZNg4OK1Zu27s6gQFC1/Mjw06iCYK6eBZsl5DRS7AB9yTXhTa54xzjf5Gsw8D vx8cEAKTG4oW1E/v+O6SK+z7B6SA52y6mvG7Zc6on3oFTMakClWH5zy5mWbB/Na69REp nXBEDfR3g2/Xx/Q9zH5UuzvbH/zH+talQglqk= Received: by 10.216.82.77 with SMTP id n55mr3667376wee.52.1304681078983; Fri, 06 May 2011 04:24:38 -0700 (PDT) Received: from localhost.localdomain ([109.65.211.213]) by mx.google.com with ESMTPS id f52sm1560856wes.35.2011.05.06.04.24.30 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 06 May 2011 04:24:38 -0700 (PDT) From: Sasha Levin To: penberg@kernel.org Cc: mingo@elte.hu, asias.hejun@gmail.com, gorcunov@gmail.com, prasadjoshi124@gmail.com, kvm@vger.kernel.org, Sasha Levin Subject: [PATCH 1/3] kvm tools: Introduce IRQ registry Date: Fri, 6 May 2011 14:24:10 +0300 Message-Id: <1304681052-30992-1-git-send-email-levinsasha928@gmail.com> X-Mailer: git-send-email 1.7.5.rc3 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 06 May 2011 11:24:46 +0000 (UTC) Instead of having static definitions of devices, Use a dynamic registry of pci devices. The structure is a rbtree which holds device types (net, blk, etc). Each device entry holds a list of IRQ lines associated with that device (pin). Devices dynamically register upon initialization, and receive a set of: device id, irq pin and irq line. Signed-off-by: Sasha Levin --- tools/kvm/Makefile | 2 + tools/kvm/include/kvm/irq.h | 24 +++++++++ tools/kvm/include/linux/module.h | 6 ++ tools/kvm/irq.c | 107 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 0 deletions(-) create mode 100644 tools/kvm/include/kvm/irq.h create mode 100644 tools/kvm/include/linux/module.h create mode 100644 tools/kvm/irq.c diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index 89c7e3d..fb839fc 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -39,6 +39,8 @@ OBJS += kvm-run.o OBJS += qcow.o OBJS += mptable.o OBJS += threadpool.o +OBJS += irq.o +OBJS += ../../lib/rbtree.o DEPS := $(patsubst %.o,%.d,$(OBJS)) diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h new file mode 100644 index 0000000..7a75a0c --- /dev/null +++ b/tools/kvm/include/kvm/irq.h @@ -0,0 +1,24 @@ +#ifndef KVM__IRQ_H +#define KVM__IRQ_H + +#include +#include +#include + +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 *num, u8 *pin, u8 *line); + +struct rb_node *irq__get_pci_tree(void); + +#endif diff --git a/tools/kvm/include/linux/module.h b/tools/kvm/include/linux/module.h new file mode 100644 index 0000000..0e4c6a3 --- /dev/null +++ b/tools/kvm/include/linux/module.h @@ -0,0 +1,6 @@ +#ifndef KVM__LINUX_MODULE_H +#define KVM__LINUX_MODULE_H + +#define EXPORT_SYMBOL(name) + +#endif diff --git a/tools/kvm/irq.c b/tools/kvm/irq.c new file mode 100644 index 0000000..4f4305f --- /dev/null +++ b/tools/kvm/irq.c @@ -0,0 +1,107 @@ +#include "kvm/irq.h" + +#include +#include +#include + +#include +#include + +static u8 next_pin = 1; +static u8 next_line = 3; +static u8 next_dev = 1; +static struct rb_root pci_tree = RB_ROOT; + +static struct pci_dev *search(struct rb_root *root, u32 id) +{ + struct rb_node *node = root->rb_node; + + while (node) { + struct pci_dev *data = container_of(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 0; + } + + /* Add new node and rebalance tree. */ + rb_link_node(&data->node, parent, new); + rb_insert_color(&data->node, root); + + return 1; +} + +int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line) +{ + struct pci_dev *node; + + 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 -1; + + *node = (struct pci_dev) { + .id = dev, + .pin = next_pin++, + }; + + INIT_LIST_HEAD(&node->lines); + + if (insert(&pci_tree, node) != 1) { + free(node); + return -1; + } + } + + 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 -1; + + new->line = next_line++; + *line = new->line; + *pin = node->pin; + *num = next_dev++; + + list_add(&new->node, &node->lines); + + return 0; + } + + return -1; +} + +struct rb_node *irq__get_pci_tree(void) +{ + return rb_first(&pci_tree); +}