On Fri, 11 Sep 2015 11:17:35 +0800 Jason Wang <jasowang@xxxxxxxxxx> wrote: > We register wildcard mmio eventfd on two buses, one for KVM_MMIO_BUS > and another is KVM_FAST_MMIO_BUS but with a single iodev > instance. This will lead an issue: kvm_io_bus_destroy() knows nothing > about the devices on two buses points to a single dev. Which will lead s/points/pointing/ > double free[1] during exit. Fixing this by using allocate two s/using allocate/allocating/ > instances of iodevs then register one on KVM_MMIO_BUS and another on > KVM_FAST_MMIO_BUS. > (...) > @@ -929,8 +878,66 @@ kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx, > static int kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) > { > enum kvm_bus bus_idx = ioeventfd_bus_from_flags(args->flags); > + int ret = kvm_deassign_ioeventfd_idx(kvm, bus_idx, args); > + > + if (!args->len) > + kvm_deassign_ioeventfd_idx(kvm, KVM_FAST_MMIO_BUS, args); I think it would be good to explicitly check for bus_idx == KVM_MMIO_BUS here. > + > + return ret; > +} > > - return kvm_deassign_ioeventfd_idx(kvm, bus_idx, args); > +static int > +kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) > +{ > + enum kvm_bus bus_idx; > + int ret; > + > + bus_idx = ioeventfd_bus_from_flags(args->flags); > + /* must be natural-word sized, or 0 to ignore length */ > + switch (args->len) { > + case 0: > + case 1: > + case 2: > + case 4: > + case 8: > + break; > + default: > + return -EINVAL; > + } > + > + /* check for range overflow */ > + if (args->addr + args->len < args->addr) > + return -EINVAL; > + > + /* check for extra flags that we don't understand */ > + if (args->flags & ~KVM_IOEVENTFD_VALID_FLAG_MASK) > + return -EINVAL; > + > + /* ioeventfd with no length can't be combined with DATAMATCH */ > + if (!args->len && > + args->flags & (KVM_IOEVENTFD_FLAG_PIO | > + KVM_IOEVENTFD_FLAG_DATAMATCH)) > + return -EINVAL; > + > + ret = kvm_assign_ioeventfd_idx(kvm, bus_idx, args); > + if (ret) > + goto fail; > + > + /* When length is ignored, MMIO is also put on a separate bus, for > + * faster lookups. > + */ > + if (!args->len && !(args->flags & KVM_IOEVENTFD_FLAG_PIO)) { Dito on a positive check for bus_idx == KVM_MMIO_BUS. > + ret = kvm_assign_ioeventfd_idx(kvm, KVM_FAST_MMIO_BUS, args); > + if (ret < 0) > + goto fast_fail; > + } > + > + return 0; > + > +fast_fail: > + kvm_deassign_ioeventfd(kvm, args); Shouldn't you use kvm_deassign_ioeventfd(kvm, bus_idx, args) here? > +fail: > + return ret; > } > > int -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html