All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gregory Haskins <ghaskins@novell.com>
To: kvm@vger.kernel.org
Cc: mst@redhat.com, avi@redhat.com
Subject: [QEMU-KVM PATCH] qemu-kvm: add ioeventfd support
Date: Tue, 07 Jul 2009 17:32:41 -0400	[thread overview]
Message-ID: <20090707213241.23998.91195.stgit@dev.haskins.net> (raw)
In-Reply-To: <20090707213127.23998.68153.stgit@dev.haskins.net>

An ioeventfd allows an eventfd to attach to a specific PIO/MMIO region in the
guest.  Any guest-writes to that region will trigger an eventfd signal.

Signed-off-by: Gregory Haskins <ghaskins@novell.com>
---

 libkvm-all.h |   44 +++++++++++++++++++++++++++++++++++++
 qemu-kvm.c   |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 0 deletions(-)

diff --git a/libkvm-all.h b/libkvm-all.h
index e16646c..b21bb7e 100644
--- a/libkvm-all.h
+++ b/libkvm-all.h
@@ -943,6 +943,50 @@ int kvm_get_irq_route_gsi(kvm_context_t kvm);
  */
 int kvm_irqfd(kvm_context_t kvm, int gsi, int flags);
 
+enum {
+	ioeventfd_option_pio,
+	ioeventfd_option_datamatch,
+};
+
+#define IOEVENTFD_FLAG_PIO      (1 << ioeventfd_option_pio)
+#define IOEVENTFD_FLAG_DATAMATCH  (1 << ioeventfd_option_datamatch)
+
+/*!
+ * \brief Assign an eventfd to an IO port (PIO or MMIO)
+ *
+ * Assigns an eventfd based file-descriptor to a specific PIO or MMIO
+ * address range.  Any guest writes to the specified range will generate
+ * an eventfd signal.
+ *
+ * A data-match pointer can be optionally provided in "datamatch" and only
+ * writes which match this value exactly will generate an event.  The length
+ * of the datamatch is established by the length of the overall IO range, and
+ * therefore must be in a natural byte-width for the IO routines of your
+ * particular architecture (e.g. 1, 2, 4, or 8 bytes on x86_64).
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param addr The IO address
+ * \param len The length of the IO region at the address
+ * \param fd The eventfd file-descriptor
+ * \param datamatch A optional data-match token
+ * \param flags FLAG_PIO: PIO, else MMIO, FLAG_DATAMATCH, datamatch valid
+ */
+int kvm_assign_ioeventfd(kvm_context_t kvm, unsigned long addr, size_t len,
+			  int fd, __u64 datamatch, int flags);
+
+/*!
+ * \brief Deassign an ioeventfd from a previously registered IO port
+ *
+ * Deassigns an ioeventfd previously registered with kvm_assign_ioeventfd()
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param addr The IO address to deassign
+ * \param fd The eventfd file-descriptor
+ * \param flags FLAG_PIO: PIO, else MMIO
+ */
+int kvm_deassign_ioeventfd(kvm_context_t kvm, unsigned long addr,
+			    int fd, int flags);
+
 #ifdef KVM_CAP_DEVICE_MSIX
 int kvm_assign_set_msix_nr(kvm_context_t kvm,
 			   struct kvm_assigned_msix_nr *msix_nr);
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 982ad33..ae77e0a 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1688,6 +1688,75 @@ int kvm_irqfd(kvm_context_t kvm, int gsi, int flags)
 }
 
 #endif /* KVM_CAP_IRQFD */
+
+#ifdef KVM_CAP_IOEVENTFD
+
+#include <sys/eventfd.h>
+
+int kvm_assign_ioeventfd(kvm_context_t kvm, unsigned long addr, size_t len,
+			  int fd, __u64 datamatch, int flags)
+{
+	int r;
+	int type = flags & IOEVENTFD_FLAG_PIO; 
+	struct kvm_ioeventfd data = {
+		.datamatch = datamatch,
+		.addr    = addr,
+		.len     = len,
+		.fd      = fd,
+	};
+
+	data.flags |= flags & IOEVENTFD_FLAG_DATAMATCH ?
+	  KVM_IOEVENTFD_FLAG_DATAMATCH : 0;
+	data.flags |= type ? KVM_IOEVENTFD_FLAG_PIO : 0;
+
+	if (!kvm_check_extension(kvm, KVM_CAP_IOEVENTFD))
+		return -ENOENT;
+
+	r = ioctl(kvm->vm_fd, KVM_IOEVENTFD, &data);
+	if (r == -1)
+		r = -errno;
+	return r;
+}
+
+int kvm_deassign_ioeventfd(kvm_context_t kvm, unsigned long addr, int fd,
+			    int flags)
+{
+	int r;
+	int type = flags & IOEVENTFD_FLAG_PIO; 
+	struct kvm_ioeventfd data = {
+		.addr    = addr,
+		.fd      = fd,
+		.flags   = KVM_IOEVENTFD_FLAG_DEASSIGN |
+		(type ? KVM_IOEVENTFD_FLAG_PIO : 0),
+	};
+
+	if (!kvm_check_extension(kvm, KVM_CAP_IOEVENTFD))
+		return -ENOENT;
+
+	r = ioctl(kvm->vm_fd, KVM_IOEVENTFD, &data);
+	if (r == -1)
+		r = -errno;
+	return r;
+}
+
+#else /* KVM_CAP_IOEVENTFD */
+
+int kvm_assign_ioeventfd(kvm_context_t kvm, unsigned long addr, size_t len,
+			  int fd, __u64 datamatch, int flags)
+{
+	return -ENOSYS;
+}
+
+int kvm_deassign_ioeventfd(kvm_context_t kvm, unsigned long addr, int fd,
+			    int flags)
+{
+	return -ENOSYS;
+}
+
+#endif /* KVM_CAP_IOEVENTFD */
+
+
+
 static inline unsigned long kvm_get_thread_id(void)
 {
     return syscall(SYS_gettid);


      reply	other threads:[~2009-07-07 21:32 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-07 21:32 [QEMU-KVM PATCH] ioeventfd Gregory Haskins
2009-07-07 21:32 ` Gregory Haskins [this message]

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=20090707213241.23998.91195.stgit@dev.haskins.net \
    --to=ghaskins@novell.com \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mst@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.