diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-05-21 17:18:54 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-05-21 17:18:54 +1000 |
commit | 108b242058dd3e847b578dd620b1e39b483fd87f (patch) | |
tree | 0054c4de5e0832e11b96b002a34e8012e2cd983d | |
parent | 9db08eca1525e1474396535a56ee0fad9292cd1e (diff) |
Revert "KVM: irqfd"
This reverts commit 302471ec2b5b6f74eba06973fb85e4584d20ef1e.
-rw-r--r-- | arch/x86/kvm/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 1 | ||||
-rw-r--r-- | include/linux/kvm.h | 11 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 4 | ||||
-rw-r--r-- | virt/kvm/eventfd.c | 228 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 11 |
6 files changed, 1 insertions, 256 deletions
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index 01e3c61f749a..bee9512cd60d 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -2,7 +2,7 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ - coalesced_mmio.o irq_comm.o eventfd.o) + coalesced_mmio.o irq_comm.o) kvm-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 98c24347a38a..7978d32fa11f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1084,7 +1084,6 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_REINJECT_CONTROL: case KVM_CAP_IRQ_INJECT_STATUS: case KVM_CAP_ASSIGN_DEV_IRQ: - case KVM_CAP_IRQFD: r = 1; break; case KVM_CAP_COALESCED_MMIO: diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 8f53f24e5274..7b17141c47c9 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -418,7 +418,6 @@ struct kvm_trace_rec { #ifdef __KVM_HAVE_MCE #define KVM_CAP_MCE 31 #endif -#define KVM_CAP_IRQFD 32 #ifdef KVM_CAP_IRQ_ROUTING @@ -471,15 +470,6 @@ struct kvm_x86_mce { }; #endif -#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0) - -struct kvm_irqfd { - __u32 fd; - __u32 gsi; - __u32 flags; - __u8 pad[20]; -}; - /* * ioctls for VM fds */ @@ -524,7 +514,6 @@ struct kvm_irqfd { #define KVM_ASSIGN_SET_MSIX_ENTRY \ _IOW(KVMIO, 0x74, struct kvm_assigned_msix_entry) #define KVM_DEASSIGN_DEV_IRQ _IOW(KVMIO, 0x75, struct kvm_assigned_irq) -#define KVM_IRQFD _IOW(KVMIO, 0x76, struct kvm_irqfd) /* * ioctls for vcpu fds diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3b6caf511422..8f410d32b0c7 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -134,7 +134,6 @@ struct kvm { struct list_head vm_list; struct kvm_io_bus mmio_bus; struct kvm_io_bus pio_bus; - struct list_head irqfds; struct kvm_vm_stat stat; struct kvm_arch arch; atomic_t users_count; @@ -529,7 +528,4 @@ static inline void kvm_free_irq_routing(struct kvm *kvm) {} #endif -int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags); -void kvm_irqfd_release(struct kvm *kvm); - #endif diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c deleted file mode 100644 index 72a282e39c3f..000000000000 --- a/virt/kvm/eventfd.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * kvm eventfd support - use eventfd objects to signal various KVM events - * - * Copyright 2009 Novell. All Rights Reserved. - * - * Author: - * Gregory Haskins <ghaskins@novell.com> - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include <linux/kvm_host.h> -#include <linux/workqueue.h> -#include <linux/syscalls.h> -#include <linux/wait.h> -#include <linux/poll.h> -#include <linux/file.h> -#include <linux/list.h> - -/* - * -------------------------------------------------------------------- - * irqfd: Allows an fd to be used to inject an interrupt to the guest - * - * Credit goes to Avi Kivity for the original idea. - * -------------------------------------------------------------------- - */ -struct _irqfd { - struct kvm *kvm; - int gsi; - struct file *file; - struct list_head list; - poll_table pt; - wait_queue_head_t *wqh; - wait_queue_t wait; - struct work_struct work; -}; - -static void -irqfd_inject(struct work_struct *work) -{ - struct _irqfd *irqfd = container_of(work, struct _irqfd, work); - struct kvm *kvm = irqfd->kvm; - - mutex_lock(&kvm->lock); - kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1); - kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0); - mutex_unlock(&kvm->lock); -} - -static int -irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key) -{ - struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait); - - /* - * The wake_up is called with interrupts disabled. Therefore we need - * to defer the IRQ injection until later since we need to acquire the - * kvm->lock to do so. - */ - schedule_work(&irqfd->work); - - return 0; -} - -static void -irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh, - poll_table *pt) -{ - struct _irqfd *irqfd = container_of(pt, struct _irqfd, pt); - - irqfd->wqh = wqh; - add_wait_queue(wqh, &irqfd->wait); -} - -static int -kvm_assign_irqfd(struct kvm *kvm, int fd, int gsi) -{ - struct _irqfd *irqfd; - struct file *file = NULL; - int ret; - - irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL); - if (!irqfd) - return -ENOMEM; - - irqfd->kvm = kvm; - irqfd->gsi = gsi; - INIT_LIST_HEAD(&irqfd->list); - INIT_WORK(&irqfd->work, irqfd_inject); - - /* - * Embed the file* lifetime in the irqfd. - */ - file = fget(fd); - if (IS_ERR(file)) { - ret = PTR_ERR(file); - goto fail; - } - - /* - * Install our own custom wake-up handling so we are notified via - * a callback whenever someone signals the underlying eventfd - */ - init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup); - init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc); - - ret = file->f_op->poll(file, &irqfd->pt); - if (ret < 0) - goto fail; - - irqfd->file = file; - - mutex_lock(&kvm->lock); - list_add_tail(&irqfd->list, &kvm->irqfds); - mutex_unlock(&kvm->lock); - - return 0; - -fail: - if (irqfd->wqh) - remove_wait_queue(irqfd->wqh, &irqfd->wait); - - if (file && !IS_ERR(file)) - fput(file); - - kfree(irqfd); - return ret; -} - -static void -irqfd_release(struct _irqfd *irqfd) -{ - /* - * The ordering is important. We must remove ourselves from the wqh - * first to ensure no more event callbacks are issued, and then flush - * any previously scheduled work prior to freeing the memory - */ - remove_wait_queue(irqfd->wqh, &irqfd->wait); - - flush_work(&irqfd->work); - - fput(irqfd->file); - kfree(irqfd); -} - -static struct _irqfd * -irqfd_remove(struct kvm *kvm, struct file *file, int gsi) -{ - struct _irqfd *irqfd; - - mutex_lock(&kvm->lock); - - /* - * linear search isn't brilliant, but this should be an infrequent - * slow-path operation, and the list should not grow very large - */ - list_for_each_entry(irqfd, &kvm->irqfds, list) { - if (irqfd->file != file || irqfd->gsi != gsi) - continue; - - list_del(&irqfd->list); - mutex_unlock(&kvm->lock); - - return irqfd; - } - - mutex_unlock(&kvm->lock); - - return NULL; -} - -static int -kvm_deassign_irqfd(struct kvm *kvm, int fd, int gsi) -{ - struct _irqfd *irqfd; - struct file *file; - int count = 0; - - file = fget(fd); - if (IS_ERR(file)) - return PTR_ERR(file); - - while ((irqfd = irqfd_remove(kvm, file, gsi))) { - /* - * We remove the item from the list under the lock, but we - * free it outside the lock to avoid deadlocking with the - * flush_work and the work_item taking the lock - */ - irqfd_release(irqfd); - count++; - } - - fput(file); - - return count ? count : -ENOENT; -} - -int -kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags) -{ - if (flags & KVM_IRQFD_FLAG_DEASSIGN) - return kvm_deassign_irqfd(kvm, fd, gsi); - - return kvm_assign_irqfd(kvm, fd, gsi); -} - -void -kvm_irqfd_release(struct kvm *kvm) -{ - struct _irqfd *irqfd, *tmp; - - /* don't bother with the lock..we are shutting down */ - list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds, list) { - list_del(&irqfd->list); - irqfd_release(irqfd); - } -} diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b58837d61ce6..bebfe59f4c76 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -983,7 +983,6 @@ static struct kvm *kvm_create_vm(void) atomic_inc(&kvm->mm->mm_count); spin_lock_init(&kvm->mmu_lock); kvm_io_bus_init(&kvm->pio_bus); - INIT_LIST_HEAD(&kvm->irqfds); mutex_init(&kvm->lock); kvm_io_bus_init(&kvm->mmio_bus); init_rwsem(&kvm->slots_lock); @@ -1035,7 +1034,6 @@ static void kvm_destroy_vm(struct kvm *kvm) spin_lock(&kvm_lock); list_del(&kvm->vm_list); spin_unlock(&kvm_lock); - kvm_irqfd_release(kvm); kvm_free_irq_routing(kvm); kvm_io_bus_destroy(&kvm->pio_bus); kvm_io_bus_destroy(&kvm->mmio_bus); @@ -2212,15 +2210,6 @@ static long kvm_vm_ioctl(struct file *filp, } #endif #endif /* KVM_CAP_IRQ_ROUTING */ - case KVM_IRQFD: { - struct kvm_irqfd data; - - r = -EFAULT; - if (copy_from_user(&data, argp, sizeof data)) - goto out; - r = kvm_irqfd(kvm, data.fd, data.gsi, data.flags); - break; - } default: r = kvm_arch_vm_ioctl(filp, ioctl, arg); } |