All of lore.kernel.org
 help / color / mirror / Atom feed
From: Glauber Costa <glommer@redhat.com>
To: kvm@vger.kernel.org
Cc: mtosatti@redhat.com
Subject: [PATCH 10/10] Do GSI routing
Date: Fri, 26 Feb 2010 17:12:21 -0300	[thread overview]
Message-ID: <1267215141-13629-11-git-send-email-glommer@redhat.com> (raw)
In-Reply-To: <1267215141-13629-10-git-send-email-glommer@redhat.com>

To follow correctly what our bios ACPI tables say, we have to be able to program
our irqchips with GSI routing mappings. This support is already in qemu-kvm

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kvm-all.c         |    4 +-
 kvm.h             |    3 +
 target-i386/kvm.c |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 1 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 3038465..5c4151f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -71,6 +71,8 @@ struct KVMState
 #endif
     int irqchip_in_kernel;
     int pit_in_kernel;
+
+    KVMArchState *arch_state;
 };
 
 static KVMState *kvm_state;
@@ -627,6 +629,7 @@ int kvm_init(int smp_cpus)
 
     s = qemu_mallocz(sizeof(KVMState));
 
+    kvm_state = s;
 #ifdef KVM_CAP_SET_GUEST_DEBUG
     QTAILQ_INIT(&s->kvm_sw_breakpoints);
 #endif
@@ -710,7 +713,6 @@ int kvm_init(int smp_cpus)
     if (ret < 0)
         goto err;
 
-    kvm_state = s;
     cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client);
 
     return 0;
diff --git a/kvm.h b/kvm.h
index 480e651..14d6e91 100644
--- a/kvm.h
+++ b/kvm.h
@@ -70,7 +70,10 @@ int kvm_set_irq(int irq, int level, int *status);
 /* internal API */
 
 struct KVMState;
+struct KVMArchState;
+
 typedef struct KVMState KVMState;
+typedef struct KVMArchState KVMArchState;
 
 int kvm_ioctl(KVMState *s, int type, ...);
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index e9a7585..58b1551 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -45,6 +45,16 @@
 
 #ifdef KVM_CAP_EXT_CPUID
 
+struct KVMArchState
+{
+    struct kvm_irq_routing *irq_routes;
+    int nr_allocated_irq_routes;
+    void *used_gsi_bitmap;
+    int max_gsi;
+};
+
+static KVMArchState *kvm_arch_state;
+
 static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
 {
     struct kvm_cpuid2 *cpuid;
@@ -340,10 +350,118 @@ static int kvm_has_msr_star(CPUState *env)
     return 0;
 }
 
+/*
+ * Setup x86 specific IRQ routing
+ */
+static inline void set_gsi(KVMArchState *s, unsigned int gsi)
+{
+    uint32_t *bitmap = s->used_gsi_bitmap;
+
+    if (gsi < s->max_gsi)
+        bitmap[gsi / 32] |= 1U << (gsi % 32);
+    else
+        fprintf(stderr, "Invalid GSI %d\n", gsi);
+}
+
+static int kvm_add_routing_entry(KVMArchState *s, struct kvm_irq_routing_entry *entry)
+{
+    struct kvm_irq_routing *z;
+    struct kvm_irq_routing_entry *new;
+    int n, size;
+
+    if (s->irq_routes->nr == s->nr_allocated_irq_routes) {
+        n = s->nr_allocated_irq_routes * 2;
+        if (n < 64)
+            n = 64;
+        size = sizeof(struct kvm_irq_routing);
+        size += n * sizeof(*new);
+        z = realloc(s->irq_routes, size);
+        if (!z)
+            return -ENOMEM;
+        s->nr_allocated_irq_routes = n;
+        s->irq_routes = z;
+    }
+    n = s->irq_routes->nr++;
+    new = &s->irq_routes->entries[n];
+    memset(new, 0, sizeof(*new));
+    new->gsi = entry->gsi;
+    new->type = entry->type;
+    new->flags = entry->flags;
+    new->u = entry->u;
+
+    set_gsi(s, entry->gsi);
+
+    return 0;
+}
+
+static int kvm_add_irq_route(KVMArchState *s, int gsi, int irqchip, int pin)
+{
+    struct kvm_irq_routing_entry e;
+
+    e.gsi = gsi;
+    e.type = KVM_IRQ_ROUTING_IRQCHIP;
+    e.flags = 0;
+    e.u.irqchip.irqchip = irqchip;
+    e.u.irqchip.pin = pin;
+    return kvm_add_routing_entry(s, &e);
+}
+
+static int kvm_init_irq_routing(KVMState *s)
+{
+    int i, r;
+    int gsi_count, gsi_bits;
+
+    gsi_count = kvm_check_extension(s, KVM_CAP_IRQ_ROUTING);
+    if (!kvm_irqchip_in_kernel() && (gsi_count > 0)) {
+        return 0;
+    }
+
+        /* Round up so we can search ints using ffs */
+    gsi_bits = ((gsi_count - 31) & ~31);
+    kvm_arch_state->used_gsi_bitmap = qemu_mallocz(gsi_bits / 8);
+    kvm_arch_state->max_gsi = gsi_bits;
+
+    /* Mark any over-allocated bits as already in use */
+    for (i = gsi_count; i < gsi_bits; i++) {
+        set_gsi(kvm_arch_state, i);
+    }
+
+    kvm_arch_state->irq_routes->nr = 0;
+
+    for (i = 0; i < 8; ++i) {
+        if (i == 2)
+            continue;
+        r = kvm_add_irq_route(kvm_arch_state, i, KVM_IRQCHIP_PIC_MASTER, i);
+        if (r < 0)
+            return r;
+    }
+    for (i = 8; i < 16; ++i) {
+        r = kvm_add_irq_route(kvm_arch_state, i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
+        if (r < 0)
+            return r;
+    }
+    for (i = 0; i < 24; ++i) {
+        if (i == 0) {
+            r = kvm_add_irq_route(kvm_arch_state, i, KVM_IRQCHIP_IOAPIC, 2);
+        } else if (i != 2) {
+            r = kvm_add_irq_route(kvm_arch_state, i, KVM_IRQCHIP_IOAPIC, i);
+        }
+        if (r < 0)
+            return r;
+    }
+
+    kvm_arch_state->irq_routes->flags = 0;
+    return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, kvm_arch_state->irq_routes);
+}
 int kvm_arch_init(KVMState *s, int smp_cpus)
 {
     int ret;
 
+    kvm_arch_state = qemu_mallocz(sizeof(*kvm_arch_state));
+    kvm_arch_state->irq_routes = qemu_mallocz(sizeof(*kvm_arch_state->irq_routes));
+
+    kvm_init_irq_routing(s);
+
     /* create vm86 tss.  KVM uses vm86 mode to emulate 16-bit code
      * directly.  In order to use vm86 mode, a TSS is needed.  Since this
      * must be part of guest physical memory, we need to allocate it.  Older
-- 
1.6.6


  reply	other threads:[~2010-02-26 20:12 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-26 20:12 [PATCH 00/10] uq/master: irqchip-in-kernel support Glauber Costa
2010-02-26 20:12 ` [PATCH 01/10] introduce VMSTATE_U64 Glauber Costa
2010-02-26 20:12   ` [PATCH 02/10] Provide ioapic-kvm Glauber Costa
2010-02-26 20:12     ` [PATCH 03/10] provide apic_set_irq_delivered Glauber Costa
2010-02-26 20:12       ` [PATCH 04/10] provide i8259-kvm Glauber Costa
2010-02-26 20:12         ` [PATCH 05/10] Don't call apic functions directly from kvm code Glauber Costa
2010-02-26 20:12           ` [PATCH 06/10] export kvm_put_mp_state Glauber Costa
2010-02-26 20:12             ` [PATCH 07/10] provide apic-kvm Glauber Costa
2010-02-26 20:12               ` [PATCH 08/10] Add -kvm option Glauber Costa
2010-02-26 20:12                 ` [PATCH 09/10] Initialize in-kernel irqchip Glauber Costa
2010-02-26 20:12                   ` Glauber Costa [this message]
2010-03-02  4:31                   ` Marcelo Tosatti
2010-03-02 18:25                     ` Glauber Costa
2010-03-09 13:21                       ` Avi Kivity
2010-02-27 10:35                 ` [PATCH 08/10] Add -kvm option Jan Kiszka
2010-03-04 16:20                   ` Jan Kiszka
2010-03-04 19:39                     ` Glauber Costa
2010-03-02  4:31                 ` Marcelo Tosatti
2010-03-02 18:25                   ` Glauber Costa
2010-03-04 19:41                     ` Anthony Liguori
2010-03-04 19:38                 ` Anthony Liguori
2010-03-04 16:49               ` [PATCH 07/10] provide apic-kvm Jan Kiszka
2010-03-09 13:27           ` [PATCH 05/10] Don't call apic functions directly from kvm code Avi Kivity
2010-03-17 14:00             ` Glauber Costa
2010-03-17 16:29               ` Avi Kivity
2010-03-02  4:28     ` [PATCH 02/10] Provide ioapic-kvm Marcelo Tosatti
2010-03-02 18:26       ` Glauber Costa
2010-02-27 10:28 ` [PATCH 00/10] uq/master: irqchip-in-kernel support Jan Kiszka
2010-03-01 15:19   ` Marcelo Tosatti
2010-03-04 16:33 ` Jan Kiszka
2010-03-08 20:56   ` Marcelo Tosatti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1267215141-13629-11-git-send-email-glommer@redhat.com \
    --to=glommer@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.