From patchwork Thu Jul 28 17:56:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 1017412 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p6SHvDbE019383 for ; Thu, 28 Jul 2011 17:57:13 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753282Ab1G1R5K (ORCPT ); Thu, 28 Jul 2011 13:57:10 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:55820 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752457Ab1G1R5J (ORCPT ); Thu, 28 Jul 2011 13:57:09 -0400 Received: by wyg8 with SMTP id 8so327734wyg.19 for ; Thu, 28 Jul 2011 10:57:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; bh=JGVeG9tHvwmfUuaf123OFiVyhkXyK9Qg5EOp6lwBpyU=; b=DHOA2hKTWEXPUAIfiPYopOslnAXdJVG4YaICe579e9zo0w7xTefdDDvJ4KnuRV4tyr Kbfx7meA4dKm1Z9vz+76+/0pwjwixIl0tFuxH/MXjj4WYgRo+TJf9p+X1bXYd5nFSCR7 swHBviSEOzfBEVfoGS5IWAtnBjNofpU6OYjqo= Received: by 10.227.62.195 with SMTP id y3mr323812wbh.94.1311875828155; Thu, 28 Jul 2011 10:57:08 -0700 (PDT) Received: from localhost.localdomain (bzq-79-182-210-47.red.bezeqint.net [79.182.210.47]) by mx.google.com with ESMTPS id fp3sm1051561wbb.13.2011.07.28.10.57.05 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 28 Jul 2011 10:57:07 -0700 (PDT) From: Sasha Levin To: penberg@kernel.org Cc: kvm@vger.kernel.org, mingo@elte.hu, asias.hejun@gmail.com, gorcunov@gmail.com, prasadjoshi124@gmail.com, Sasha Levin Subject: [PATCH v2 1/4] kvm tools: Use GSI routing Date: Thu, 28 Jul 2011 20:56:18 +0300 Message-Id: <1311875781-691-1-git-send-email-levinsasha928@gmail.com> X-Mailer: git-send-email 1.7.6 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 (demeter2.kernel.org [140.211.167.43]); Thu, 28 Jul 2011 17:57:13 +0000 (UTC) Map GSIs manually when starting the guest. This will allow us mapping new GSIs for MSIX in the future. Signed-off-by: Sasha Levin --- tools/kvm/builtin-run.c | 3 ++ tools/kvm/include/kvm/irq.h | 5 +++ tools/kvm/irq.c | 80 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 0 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index 941129c..bf54448 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -35,6 +35,7 @@ #include #include #include +#include /* header files for gitish interface */ #include @@ -573,6 +574,8 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) kvm = kvm__init(kvm_dev, ram_size, guest_name); + irq__init(kvm); + kvm->single_step = single_step; ioeventfd__init(); diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 7a75a0c..401bee9 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -5,6 +5,8 @@ #include #include +struct kvm; + struct irq_line { u8 line; struct list_head node; @@ -21,4 +23,7 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line); struct rb_node *irq__get_pci_tree(void); +void irq__init(struct kvm *kvm); +int irq__add_msix_route(struct kvm *kvm, u32 low, u32 high, u32 data); + #endif diff --git a/tools/kvm/irq.c b/tools/kvm/irq.c index 15f4702..85e2238 100644 --- a/tools/kvm/irq.c +++ b/tools/kvm/irq.c @@ -1,16 +1,46 @@ #include "kvm/irq.h" +#include "kvm/kvm.h" +#include "kvm/util.h" #include #include #include +#include +#include #include #include +#define IRQ_MAX_GSI 64 +#define IRQCHIP_MASTER 0 +#define IRQCHIP_SLAVE 1 +#define IRQCHIP_IOAPIC 2 + static u8 next_line = 3; static u8 next_dev = 1; static struct rb_root pci_tree = RB_ROOT; +/* First 24 GSIs are routed between IRQCHIPs and IOAPICs */ +static u32 gsi = 24; + +struct kvm_irq_routing *irq_routing; + +static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin) +{ + if (gsi >= IRQ_MAX_GSI) + return -ENOSPC; + + irq_routing->entries[irq_routing->nr++] = + (struct kvm_irq_routing_entry) { + .gsi = gsi, + .type = type, + .u.irqchip.irqchip = irqchip, + .u.irqchip.pin = pin, + }; + + return 0; +} + static struct pci_dev *search(struct rb_root *root, u32 id) { struct rb_node *node = root->rb_node; @@ -106,6 +136,56 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line) return -1; } +void irq__init(struct kvm *kvm) +{ + int i, r; + + irq_routing = malloc(sizeof(struct kvm_irq_routing) + + IRQ_MAX_GSI * sizeof(struct kvm_irq_routing_entry)); + if (irq_routing == NULL) + die("Failed allocating space for GSI table"); + + /* Hook first 8 GSIs to master IRQCHIP */ + for (i = 0; i < 8; i++) + irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_MASTER, i); + + /* Hook next 8 GSIs to slave IRQCHIP */ + for (i = 8; i < 16; i++) + irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_SLAVE, 8-i); + + /* Last but not least, IOAPIC */ + for (i = 0; i < 24; i++) { + if (i == 0) + irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, 2); + else + irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, i); + } + + r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing); + if (r) + die("Failed setting GSI routes"); +} + +int irq__add_msix_route(struct kvm *kvm, u32 low, u32 high, u32 data) +{ + int r; + + irq_routing->entries[irq_routing->nr++] = + (struct kvm_irq_routing_entry) { + .gsi = gsi, + .type = KVM_IRQ_ROUTING_MSI, + .u.msi.address_lo = low, + .u.msi.address_hi = high, + .u.msi.data = data, + }; + + r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing); + if (r) + return r; + + return gsi++; +} + struct rb_node *irq__get_pci_tree(void) { return rb_first(&pci_tree);