aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2013-04-04 06:27:21 -0400
committerGleb Natapov <gleb@redhat.com>2013-04-07 07:53:47 -0400
commit05e07f9bdb0ea3c1c52029e6c4db77c9f7c92a5c (patch)
treed84ca956c581c7657c21d495062354d8fb1a349c /virt
parentb8c07d55d010702eff61562cf9a77366833d9da2 (diff)
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 020522ed9094..48790989f8d2 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -574,6 +574,7 @@ struct _ioeventfd {
574 struct eventfd_ctx *eventfd; 574 struct eventfd_ctx *eventfd;
575 u64 datamatch; 575 u64 datamatch;
576 struct kvm_io_device dev; 576 struct kvm_io_device dev;
577 u8 bus_idx;
577 bool wildcard; 578 bool wildcard;
578}; 579};
579 580
@@ -666,7 +667,8 @@ ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
666 struct _ioeventfd *_p; 667 struct _ioeventfd *_p;
667 668
668 list_for_each_entry(_p, &kvm->ioeventfds, list) 669 list_for_each_entry(_p, &kvm->ioeventfds, list)
669 if (_p->addr == p->addr && _p->length == p->length && 670 if (_p->bus_idx == p->bus_idx &&
671 _p->addr == p->addr && _p->length == p->length &&
670 (_p->wildcard || p->wildcard || 672 (_p->wildcard || p->wildcard ||
671 _p->datamatch == p->datamatch)) 673 _p->datamatch == p->datamatch))
672 return true; 674 return true;
@@ -723,6 +725,7 @@ kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
723 725
724 INIT_LIST_HEAD(&p->list); 726 INIT_LIST_HEAD(&p->list);
725 p->addr = args->addr; 727 p->addr = args->addr;
728 p->bus_idx = bus_idx;
726 p->length = args->len; 729 p->length = args->len;
727 p->eventfd = eventfd; 730 p->eventfd = eventfd;
728 731
@@ -781,7 +784,8 @@ kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
781 list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) { 784 list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) {
782 bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH); 785 bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH);
783 786
784 if (p->eventfd != eventfd || 787 if (p->bus_idx != bus_idx ||
788 p->eventfd != eventfd ||
785 p->addr != args->addr || 789 p->addr != args->addr ||
786 p->length != args->len || 790 p->length != args->len ||
787 p->wildcard != wildcard) 791 p->wildcard != wildcard)