summaryrefslogtreecommitdiff
path: root/virt
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2013-04-04 10:27:21 (GMT)
committerGleb Natapov <gleb@redhat.com>2013-04-07 11:53:47 (GMT)
commit05e07f9bdb0ea3c1c52029e6c4db77c9f7c92a5c (patch)
treed84ca956c581c7657c21d495062354d8fb1a349c /virt
parentb8c07d55d010702eff61562cf9a77366833d9da2 (diff)
downloadlinux-fsl-qoriq-05e07f9bdb0ea3c1c52029e6c4db77c9f7c92a5c.tar.xz
kvm: fix MMIO/PIO collision misdetection
PIO and MMIO are separate address spaces, but ioeventfd registration code mistakenly detected two eventfds as duplicate if they use the same address, even if one is PIO and another one MMIO. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/eventfd.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 020522e..4879098 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -574,6 +574,7 @@ struct _ioeventfd {
struct eventfd_ctx *eventfd;
u64 datamatch;
struct kvm_io_device dev;
+ u8 bus_idx;
bool wildcard;
};
@@ -666,7 +667,8 @@ ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
struct _ioeventfd *_p;
list_for_each_entry(_p, &kvm->ioeventfds, list)
- if (_p->addr == p->addr && _p->length == p->length &&
+ if (_p->bus_idx == p->bus_idx &&
+ _p->addr == p->addr && _p->length == p->length &&
(_p->wildcard || p->wildcard ||
_p->datamatch == p->datamatch))
return true;
@@ -723,6 +725,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
INIT_LIST_HEAD(&p->list);
p->addr = args->addr;
+ p->bus_idx = bus_idx;
p->length = args->len;
p->eventfd = eventfd;
@@ -781,7 +784,8 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) {
bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH);
- if (p->eventfd != eventfd ||
+ if (p->bus_idx != bus_idx ||
+ p->eventfd != eventfd ||
p->addr != args->addr ||
p->length != args->len ||
p->wildcard != wildcard)