Commit 05e07f9b authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by Gleb Natapov

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: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarGleb Natapov <gleb@redhat.com>
parent b8c07d55
...@@ -574,6 +574,7 @@ struct _ioeventfd { ...@@ -574,6 +574,7 @@ struct _ioeventfd {
struct eventfd_ctx *eventfd; struct eventfd_ctx *eventfd;
u64 datamatch; u64 datamatch;
struct kvm_io_device dev; struct kvm_io_device dev;
u8 bus_idx;
bool wildcard; bool wildcard;
}; };
...@@ -666,7 +667,8 @@ ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p) ...@@ -666,7 +667,8 @@ ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
struct _ioeventfd *_p; struct _ioeventfd *_p;
list_for_each_entry(_p, &kvm->ioeventfds, list) 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->wildcard || p->wildcard ||
_p->datamatch == p->datamatch)) _p->datamatch == p->datamatch))
return true; return true;
...@@ -723,6 +725,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) ...@@ -723,6 +725,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
INIT_LIST_HEAD(&p->list); INIT_LIST_HEAD(&p->list);
p->addr = args->addr; p->addr = args->addr;
p->bus_idx = bus_idx;
p->length = args->len; p->length = args->len;
p->eventfd = eventfd; p->eventfd = eventfd;
...@@ -781,7 +784,8 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) ...@@ -781,7 +784,8 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) { list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) {
bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH); 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->addr != args->addr ||
p->length != args->len || p->length != args->len ||
p->wildcard != wildcard) p->wildcard != wildcard)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment