On 09/11/2015 03:46 PM, Cornelia Huck wrote: > 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/ Will fix this in V5. >> double free[1] during exit. Fixing this by using allocate two > s/using allocate/allocating/ Will fix this in V5. > >> 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. Ok. > >> + >> + 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. I was thinking maybe this should be done in a separate patch on top. What's your opinion? >> + 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? Actually, it's the same. (the deassign of fast mmio will return -ENOENT and will be ignored.) But I admit do what you suggested here is better. Will do this. Thanks -- 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