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 <[email protected]>
---
 virt/kvm/eventfd.c | 53 ++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 25 deletions(-)

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);
-- 
2.19.1


Reply via email to