From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sasha Levin Subject: [PATCH 1/4] kvm tools: Use GSI routing Date: Thu, 28 Jul 2011 12:01:52 +0300 Message-ID: <1311843715-5464-1-git-send-email-levinsasha928@gmail.com> Cc: kvm@vger.kernel.org, mingo@elte.hu, asias.hejun@gmail.com, gorcunov@gmail.com, prasadjoshi124@gmail.com, Sasha Levin To: penberg@kernel.org Return-path: Received: from mail-fx0-f46.google.com ([209.85.161.46]:64718 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755184Ab1G1JDA (ORCPT ); Thu, 28 Jul 2011 05:03:00 -0400 Received: by fxh19 with SMTP id 19so1069134fxh.19 for ; Thu, 28 Jul 2011 02:02:59 -0700 (PDT) Sender: kvm-owner@vger.kernel.org List-ID: 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 | 3 ++ tools/kvm/irq.c | 75 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 0 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index 941129c..f9c3e7e 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->single_step = single_step; ioeventfd__init(); diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h index 7a75a0c..2f00b18 100644 --- a/tools/kvm/include/kvm/irq.h +++ b/tools/kvm/include/kvm/irq.h @@ -21,4 +21,7 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line); struct rb_node *irq__get_pci_tree(void); +void irq__init(void); +u32 irq__add_msix_route(u32 low, u32 high, u32 data); + #endif diff --git a/tools/kvm/irq.c b/tools/kvm/irq.c index 15f4702..fc5d800 100644 --- a/tools/kvm/irq.c +++ b/tools/kvm/irq.c @@ -1,16 +1,47 @@ #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; + +extern struct kvm *kvm; + +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 +137,50 @@ int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line) return -1; } +void irq__init(void) +{ + int i, r; + + irq_routing = malloc(sizeof(struct kvm_irq_routing) + + IRQ_MAX_GSI * sizeof(struct kvm_irq_routing_entry)); + + /* 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"); +} + +u32 irq__add_msix_route(u32 low, u32 high, u32 data) +{ + 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, + }; + + if (ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing)) + return -1; + + return gsi++; +} + struct rb_node *irq__get_pci_tree(void) { return rb_first(&pci_tree); -- 1.7.6