Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 454

kvm-83-164.el5_5.9.src.rpm

From 0845b93a0a327bfc7a2ab0e1418da878aed840f0 Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi@redhat.com>
Date: Thu, 21 May 2009 17:08:35 -0700
Subject: [PATCH 06/15] kvm: libkvm: support for irq routing

Signed-off-by: Avi Kivity <avi@redhat.com>
(cherry picked from commit 67e684f00b53b58e5f2067fd3379ae1b00e725bd)
Signed-off-by: Chris Wright <chrisw@redhat.com>
Bugzilla: 498084
Message-Id: <1242950924-30161-5-git-send-email-chrisw@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Upstream-status: applied
Acked-by: Juan Quintela <quintela@redhat.com>
Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
Acked-by: Don Dutile <ddutile@redhat.com>
---
 libkvm/kvm-common.h |    4 ++
 libkvm/libkvm.c     |  107 +++++++++++++++++++++++++++++++++++++++++++++++++++
 libkvm/libkvm.h     |   62 +++++++++++++++++++++++++++++
 3 files changed, 173 insertions(+), 0 deletions(-)

diff --git a/libkvm/kvm-common.h b/libkvm/kvm-common.h
index ee010fb..976e6bd 100644
--- a/libkvm/kvm-common.h
+++ b/libkvm/kvm-common.h
@@ -63,6 +63,10 @@ struct kvm_context {
 	int pit_in_kernel;
 	/// in-kernel coalesced mmio
 	int coalesced_mmio;
+#ifdef KVM_CAP_IRQ_ROUTING
+	struct kvm_irq_routing *irq_routes;
+	int nr_allocated_irq_routes;
+#endif
 };
 
 void init_slots(void);
diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
index 25494be..8d77708 100644
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -381,6 +381,14 @@ int kvm_create_vm(kvm_context_t kvm)
 {
 	int fd = kvm->fd;
 
+#ifdef KVM_CAP_IRQ_ROUTING
+	kvm->irq_routes = malloc(sizeof(*kvm->irq_routes));
+	if (!kvm->irq_routes)
+		return -ENOMEM;
+	memset(kvm->irq_routes, 0, sizeof(*kvm->irq_routes));
+	kvm->nr_allocated_irq_routes = 0;
+#endif
+
 	kvm->vcpu_fd[0] = -1;
 
 	fd = ioctl(fd, KVM_CREATE_VM, 0);
@@ -1177,3 +1185,102 @@ int kvm_reinject_control(kvm_context_t kvm, int pit_reinject)
 #endif
 	return -ENOSYS;
 }
+
+int kvm_has_gsi_routing(kvm_context_t kvm)
+{
+    int r = 0;
+
+#ifdef KVM_CAP_IRQ_ROUTING
+    r = kvm_check_extension(kvm, KVM_CAP_IRQ_ROUTING);
+#endif
+    return r;
+}
+
+int kvm_get_gsi_count(kvm_context_t kvm)
+{
+#ifdef KVM_CAP_IRQ_ROUTING
+	return kvm_check_extension(kvm, KVM_CAP_IRQ_ROUTING);
+#else
+	return -EINVAL;
+#endif
+}
+
+int kvm_clear_gsi_routes(kvm_context_t kvm)
+{
+#ifdef KVM_CAP_IRQ_ROUTING
+	kvm->irq_routes->nr = 0;
+	return 0;
+#else
+	return -EINVAL;
+#endif
+}
+
+int kvm_add_irq_route(kvm_context_t kvm, int gsi, int irqchip, int pin)
+{
+#ifdef KVM_CAP_IRQ_ROUTING
+	struct kvm_irq_routing *z;
+	struct kvm_irq_routing_entry *e;
+	int n, size;
+
+	if (kvm->irq_routes->nr == kvm->nr_allocated_irq_routes) {
+		n = kvm->nr_allocated_irq_routes * 2;
+		if (n < 64)
+			n = 64;
+		size = sizeof(struct kvm_irq_routing);
+		size += n * sizeof(*e);
+		z = realloc(kvm->irq_routes, size);
+		if (!z)
+			return -ENOMEM;
+		kvm->nr_allocated_irq_routes = n;
+		kvm->irq_routes = z;
+	}
+	n = kvm->irq_routes->nr++;
+	e = &kvm->irq_routes->entries[n];
+	memset(e, 0, sizeof(*e));
+	e->gsi = gsi;
+	e->type = KVM_IRQ_ROUTING_IRQCHIP;
+	e->flags = 0;
+	e->u.irqchip.irqchip = irqchip;
+	e->u.irqchip.pin = pin;
+	return 0;
+#else
+	return -ENOSYS;
+#endif
+}
+
+int kvm_del_irq_route(kvm_context_t kvm, int gsi, int irqchip, int pin)
+{
+#ifdef KVM_CAP_IRQ_ROUTING
+	struct kvm_irq_routing_entry *e, *p;
+	int i;
+
+	for (i = 0; i < kvm->irq_routes->nr; ++i) {
+		e = &kvm->irq_routes->entries[i];
+		if (e->type == KVM_IRQ_ROUTING_IRQCHIP
+		    && e->gsi == gsi
+		    && e->u.irqchip.irqchip == irqchip
+		    && e->u.irqchip.pin == pin) {
+			p = &kvm->irq_routes->entries[--kvm->irq_routes->nr];
+			*e = *p;
+			return 0;
+		}
+	}
+	return -ESRCH;
+#else
+	return -ENOSYS;
+#endif
+}
+
+int kvm_commit_irq_routes(kvm_context_t kvm)
+{
+#ifdef KVM_CAP_IRQ_ROUTING
+	int r;
+
+	kvm->irq_routes->flags = 0;
+	r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, kvm->irq_routes);
+	if (r == -1)
+		r = -errno;
+#else
+	return -ENOSYS;
+#endif
+}
diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
index b24b655..40275d7 100644
--- a/libkvm/libkvm.h
+++ b/libkvm/libkvm.h
@@ -720,4 +720,66 @@ int kvm_assign_irq(kvm_context_t kvm,
  */
 int kvm_destroy_memory_region_works(kvm_context_t kvm);
 #endif
+
+
+/*!
+ * \brief Checks whether the generic irq routing capability is present
+ *
+ * Checks whether kvm can reroute interrupts among the various interrupt
+ * controllers.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_has_gsi_routing(kvm_context_t kvm);
+
+/*!
+ * \brief Determines the number of gsis that can be routed
+ *
+ * Returns the number of distinct gsis that can be routed by kvm.  This is
+ * also the number of distinct routes (if a gsi has two routes, than another
+ * gsi cannot be used...)
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_get_gsi_count(kvm_context_t kvm);
+
+/*!
+ * \brief Clears the temporary irq routing table
+ *
+ * Clears the temporary irq routing table.  Nothing is committed to the
+ * running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_clear_gsi_routes(kvm_context_t kvm);
+
+/*!
+ * \brief Adds an irq route to the temporary irq routing table
+ *
+ * Adds an irq route to the temporary irq routing table.  Nothing is
+ * committed to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_add_irq_route(kvm_context_t kvm, int gsi, int irqchip, int pin);
+
+/*!
+ * \brief Removes an irq route from the temporary irq routing table
+ *
+ * Adds an irq route to the temporary irq routing table.  Nothing is
+ * committed to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_del_irq_route(kvm_context_t kvm, int gsi, int irqchip, int pin);
+
+/*!
+ * \brief Commit the temporary irq routing table
+ *
+ * Commit the temporary irq routing table to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_commit_irq_routes(kvm_context_t kvm);
+
 #endif
-- 
1.6.3.rc4.29.g8146