diff mbox series

[v1] ioeventfd: introduce get_ioeventfd()

Message ID 20200731085939.629-1-yezhenyu2@huawei.com (mailing list archive)
State New, archived
Headers show
Series [v1] ioeventfd: introduce get_ioeventfd() | expand

Commit Message

Zhenyu Ye July 31, 2020, 8:59 a.m. UTC
Get corresponding ioeventfd from kvm->ioeventfds. If no match
is found, return NULL.  This is used in kvm_assign_ioeventfd_idx()
and kvm_deassign_ioeventfd_idx().

Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
 virt/kvm/eventfd.c | 53 ++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 25 deletions(-)
diff mbox series

Patch

diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index ef7ed916ad4a..77f7d81c1138 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -28,6 +28,11 @@ 
 
 #include <kvm/iodev.h>
 
+#define warn_if(expr, msg) do {				\
+	if (expr)					\
+		pr_warn("ioeventfd: %s\n", msg);	\
+} while (0)
+
 #ifdef CONFIG_HAVE_KVM_IRQFD
 
 static struct workqueue_struct *irqfd_cleanup_wq;
@@ -756,21 +761,23 @@  static const struct kvm_io_device_ops ioeventfd_ops = {
 };
 
 /* assumes kvm->slots_lock held */
-static bool
-ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
+static inline struct _ioeventfd *
+get_ioeventfd(struct kvm *kvm, enum kvm_bus bus_idx,
+	      struct kvm_ioeventfd *args)
 {
-	struct _ioeventfd *_p;
+	static struct _ioeventfd *_p;
+	bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH);
 
 	list_for_each_entry(_p, &kvm->ioeventfds, list)
-		if (_p->bus_idx == p->bus_idx &&
-		    _p->addr == p->addr &&
-		    (!_p->length || !p->length ||
-		     (_p->length == p->length &&
-		      (_p->wildcard || p->wildcard ||
-		       _p->datamatch == p->datamatch))))
-			return true;
+		if (_p->bus_idx == bus_idx &&
+		    _p->addr == args->addr &&
+		    (!_p->length || !args->len ||
+		     (_p->length == args->len &&
+		      (_p->wildcard || wildcard ||
+		       _p->datamatch == args->datamatch))))
+			return _p;
 
-	return false;
+	return NULL;
 }
 
 static enum kvm_bus ioeventfd_bus_from_flags(__u32 flags)
@@ -816,7 +823,7 @@  static int kvm_assign_ioeventfd_idx(struct kvm *kvm,
 	mutex_lock(&kvm->slots_lock);
 
 	/* Verify that there isn't a match already */
-	if (ioeventfd_check_collision(kvm, p)) {
+	if (get_ioeventfd(kvm, bus_idx, args)) {
 		ret = -EEXIST;
 		goto unlock_fail;
 	}
@@ -849,7 +856,7 @@  static int
 kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx,
 			   struct kvm_ioeventfd *args)
 {
-	struct _ioeventfd        *p, *tmp;
+	struct _ioeventfd        *p;
 	struct eventfd_ctx       *eventfd;
 	struct kvm_io_bus	 *bus;
 	int                       ret = -ENOENT;
@@ -860,18 +867,15 @@  kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx,
 
 	mutex_lock(&kvm->slots_lock);
 
-	list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) {
+	p = get_ioeventfd(kvm, bus_idx, args);
+	if (p) {
 		bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH);
-
-		if (p->bus_idx != bus_idx ||
-		    p->eventfd != eventfd  ||
-		    p->addr != args->addr  ||
-		    p->length != args->len ||
-		    p->wildcard != wildcard)
-			continue;
-
-		if (!p->wildcard && p->datamatch != args->datamatch)
-			continue;
+		warn_if(p->eventfd != eventfd, "eventfd should be the same!");
+		warn_if(p->length != args->len,	"length should be the same!");
+		warn_if(p->length && p->wildcard != wildcard,
+				"wildcard should be the same!");
+		warn_if(p->length && !p->wildcard && p->datamatch != args->datamatch,
+				"datamatch should be the same!");
 
 		kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
 		bus = kvm_get_bus(kvm, bus_idx);
@@ -879,7 +883,6 @@  kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx,
 			bus->ioeventfd_count--;
 		ioeventfd_release(p);
 		ret = 0;
-		break;
 	}
 
 	mutex_unlock(&kvm->slots_lock);