kvm: fix zero length mmio searching
authorJason Wang <[email protected]>
Tue, 15 Sep 2015 06:41:57 +0000 (14:41 +0800)
committerPaolo Bonzini <[email protected]>
Tue, 15 Sep 2015 14:59:46 +0000 (16:59 +0200)
Currently, if we had a zero length mmio eventfd assigned on
KVM_MMIO_BUS. It will never be found by kvm_io_bus_cmp() since it
always compares the kvm_io_range() with the length that guest
wrote. This will cause e.g for vhost, kick will be trapped by qemu
userspace instead of vhost. Fixing this by using zero length if an
iodevice is zero length.

Cc: [email protected]
Cc: Gleb Natapov <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Signed-off-by: Jason Wang <[email protected]>
Reviewed-by: Cornelia Huck <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
virt/kvm/kvm_main.c

index eb4c9d2849dc76b18e92ccba55f1a36cc8b1b08b..9af68db73c6aabc7314adb7e4633a1fb1c968d7c 100644 (file)
@@ -3157,10 +3157,25 @@ static void kvm_io_bus_destroy(struct kvm_io_bus *bus)
 static inline int kvm_io_bus_cmp(const struct kvm_io_range *r1,
                                 const struct kvm_io_range *r2)
 {
-       if (r1->addr < r2->addr)
+       gpa_t addr1 = r1->addr;
+       gpa_t addr2 = r2->addr;
+
+       if (addr1 < addr2)
                return -1;
-       if (r1->addr + r1->len > r2->addr + r2->len)
+
+       /* If r2->len == 0, match the exact address.  If r2->len != 0,
+        * accept any overlapping write.  Any order is acceptable for
+        * overlapping ranges, because kvm_io_bus_get_first_dev ensures
+        * we process all of them.
+        */
+       if (r2->len) {
+               addr1 += r1->len;
+               addr2 += r2->len;
+       }
+
+       if (addr1 > addr2)
                return 1;
+
        return 0;
 }