On Mon, Jun 29, 2009 at 11:44:20AM -0400, Gregory Haskins wrote: > DEASSIGN allows us to optionally disassociate an IRQFD from its underlying > eventfd without destroying the eventfd in the process. This is useful > for conditions like live-migration which may have an eventfd associated > with a device and an IRQFD. We need to be able to decouple the guest > from the event source while not perturbing the event source itself. > > Signed-off-by: Gregory Haskins <ghaskins@xxxxxxxxxx> > CC: Michael S. Tsirkin <mst@xxxxxxxxxx> Very happy to see this feature back. ACK. > --- > > include/linux/kvm.h | 2 ++ > virt/kvm/eventfd.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- > 2 files changed, 46 insertions(+), 2 deletions(-) > > diff --git a/include/linux/kvm.h b/include/linux/kvm.h > index 38ff31e..6710518 100644 > --- a/include/linux/kvm.h > +++ b/include/linux/kvm.h > @@ -490,6 +490,8 @@ struct kvm_x86_mce { > }; > #endif > > +#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0) > + > struct kvm_irqfd { > __u32 fd; > __u32 gsi; > diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c > index 76ad125..409d9e1 100644 > --- a/virt/kvm/eventfd.c > +++ b/virt/kvm/eventfd.c > @@ -152,8 +152,8 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh, > add_wait_queue(wqh, &irqfd->wait); > } > > -int > -kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags) > +static int > +kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) > { > struct _irqfd *irqfd; > struct file *file = NULL; > @@ -233,6 +233,48 @@ kvm_irqfd_init(struct kvm *kvm) > } > > /* > + * shutdown any irqfd's that match fd+gsi > + */ > +static int > +kvm_irqfd_deassign(struct kvm *kvm, int fd, int gsi) > +{ > + struct _irqfd *irqfd, *tmp; > + struct eventfd_ctx *eventfd; > + > + eventfd = eventfd_ctx_fdget(fd); > + if (IS_ERR(eventfd)) > + return PTR_ERR(eventfd); > + > + spin_lock_irq(&kvm->irqfds.lock); > + > + list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) { > + if (irqfd->eventfd == eventfd && irqfd->gsi == gsi) > + irqfd_deactivate(irqfd); > + } > + > + spin_unlock_irq(&kvm->irqfds.lock); > + eventfd_ctx_put(eventfd); > + > + /* > + * Block until we know all outstanding shutdown jobs have completed > + * so that we guarantee there will not be any more interrupts on this > + * gsi once this deassign function returns. > + */ > + flush_workqueue(irqfd_cleanup_wq); > + > + return 0; > +} > + > +int > +kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags) > +{ > + if (flags & KVM_IRQFD_FLAG_DEASSIGN) > + return kvm_irqfd_deassign(kvm, fd, gsi); > + > + return kvm_irqfd_assign(kvm, fd, gsi); > +} > + > +/* > * This function is called as the kvm VM fd is being released. Shutdown all > * irqfds that still remain open > */ -- 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