aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2015-09-15 02:41:57 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2015-09-15 10:59:46 -0400
commit8f4216c7d28976f7ec1b2bcbfa0a9f787133c45e (patch)
tree1e530734d606cc871c6a01a2b41567dae350104c
parenteefd6b06b17c5478e7c24bea6f64beaa2c431ca6 (diff)
kvm: fix zero length mmio searching
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: stable@vger.kernel.org Cc: Gleb Natapov <gleb@kernel.org> Cc: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--virt/kvm/kvm_main.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index eb4c9d2849dc..9af68db73c6a 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3157,10 +3157,25 @@ static void kvm_io_bus_destroy(struct kvm_io_bus *bus)
3157static inline int kvm_io_bus_cmp(const struct kvm_io_range *r1, 3157static inline int kvm_io_bus_cmp(const struct kvm_io_range *r1,
3158 const struct kvm_io_range *r2) 3158 const struct kvm_io_range *r2)
3159{ 3159{
3160 if (r1->addr < r2->addr) 3160 gpa_t addr1 = r1->addr;
3161 gpa_t addr2 = r2->addr;
3162
3163 if (addr1 < addr2)
3161 return -1; 3164 return -1;
3162 if (r1->addr + r1->len > r2->addr + r2->len) 3165
3166 /* If r2->len == 0, match the exact address. If r2->len != 0,
3167 * accept any overlapping write. Any order is acceptable for
3168 * overlapping ranges, because kvm_io_bus_get_first_dev ensures
3169 * we process all of them.
3170 */
3171 if (r2->len) {
3172 addr1 += r1->len;
3173 addr2 += r2->len;
3174 }
3175
3176 if (addr1 > addr2)
3163 return 1; 3177 return 1;
3178
3164 return 0; 3179 return 0;
3165} 3180}
3166 3181