diff mbox

[4/5] ioeventfd: Introduce KVM_IOEVENTFD_FLAG_NOWRITE

Message ID 1309927078-5983-4-git-send-email-levinsasha928@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sasha Levin July 6, 2011, 4:37 a.m. UTC
The new flag specifies whether writes to the address specified
in the ioeventfd shouldn't raise the event.

Cc: Avi Kivity <avi@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 Documentation/virtual/kvm/api.txt |    5 +++++
 include/linux/kvm.h               |    2 ++
 virt/kvm/eventfd.c                |    9 +++++++++
 3 files changed, 16 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 8179bc1..317d86a 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1347,6 +1347,7 @@  The following flags are defined:
 #define KVM_IOEVENTFD_FLAG_PIO       (1 << kvm_ioeventfd_flag_nr_pio)
 #define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
 #define KVM_IOEVENTFD_FLAG_READ      (1 << kvm_ioeventfd_flag_nr_read)
+#define KVM_IOEVENTFD_FLAG_NOWRITE   (1 << kvm_ioeventfd_flag_nr_nowrite)
 
 If datamatch flag is set, the event will be signaled only if the written value
 to the registered address is equal to datamatch in struct kvm_ioeventfd.
@@ -1355,6 +1356,10 @@  If the read flag is set, the event will be signaled when the specified address
 is being read from. The value actually read by the guest will be the value
 passed in datamatch.
 
+If the nowrite flag is set, the event won't be signaled when the specified address
+is being written to.
+
+
 5. The kvm_run structure
 
 Application code obtains a pointer to the kvm_run structure by
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index ce4cc89..8a12711 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -388,6 +388,7 @@  enum {
 	kvm_ioeventfd_flag_nr_pio,
 	kvm_ioeventfd_flag_nr_deassign,
 	kvm_ioeventfd_flag_nr_read,
+	kvm_ioeventfd_flag_nr_nowrite,
 	kvm_ioeventfd_flag_nr_max,
 };
 
@@ -395,6 +396,7 @@  enum {
 #define KVM_IOEVENTFD_FLAG_PIO       (1 << kvm_ioeventfd_flag_nr_pio)
 #define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
 #define KVM_IOEVENTFD_FLAG_READ      (1 << kvm_ioeventfd_flag_nr_read)
+#define KVM_IOEVENTFD_FLAG_NOWRITE   (1 << kvm_ioeventfd_flag_nr_nowrite)
 
 #define KVM_IOEVENTFD_VALID_FLAG_MASK  ((1 << kvm_ioeventfd_flag_nr_max) - 1)
 
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index e0f24bf..5f2d203 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -429,6 +429,7 @@  struct _ioeventfd {
 	struct kvm_io_device dev;
 	bool                 wildcard;
 	bool                 track_reads;
+	bool                 track_writes;
 };
 
 static inline struct _ioeventfd *
@@ -516,6 +517,10 @@  ioeventfd_write(struct kvm_io_device *this, gpa_t addr, int len,
 {
 	struct _ioeventfd *p = to_ioeventfd(this);
 
+	/* Exit if signaling on writes isn't requested */
+	if (!p->track_writes)
+		return -EOPNOTSUPP;
+
 	if (!ioeventfd_in_range(p, addr, len, val))
 		return -EOPNOTSUPP;
 
@@ -624,6 +629,10 @@  kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
 	if (args->flags & KVM_IOEVENTFD_FLAG_READ)
 		p->track_reads = true;
 
+	/* Don't raise signal on writes to address if requested */
+	if (!(args->flags & KVM_IOEVENTFD_FLAG_NOWRITE))
+		p->track_writes = true;
+
 	kvm_iodevice_init(&p->dev, &ioeventfd_ops);
 
 	ret = kvm_io_bus_register_dev(kvm, bus_idx, &p->dev);