qemu-kvm: add irqfd support
PATCH v2 1/1 qemu-kvm: add irqfd support
(applies to kvm-userspace.git 84474e4f39)
This adds userspace support for the irqfd mechanism in the kernel, published here:
http://lkml.org/lkml/2009/4/24/6
This is v2. Changes since v1:
*) bug-fix to prevent returning "0" for success on allocation
---------------------
There are no current users, though the future virtual-bus v4 has plans to adopt it.
---
libkvm/libkvm.c | 33 +++++++++++++++++++++++++++++++++ libkvm/libkvm.h | 13 +++++++++++++ 2 files changed, 46 insertions(+), 0 deletions(-)
libkvm/libkvm.c +33 -0
@@ -35,6 +35,7 @@#include <errno.h> #include <sys/ioctl.h> #include <inttypes.h> +#include <sys/eventfd.h> #include "libkvm.h" #if defined(__x86_64__) || defined(__i386__)
@@ -1440,3 +1441,35 @@ int kvm_assign_set_msix_entry(kvm_context_t kvm,return ret; }#endif + +static int assign_irqfd (kvm_context_t kvm,int fd,int gsi) +{ +int r; +struct kvm_irqfd data = { + .fd = fd, + .gsi = gsi, + }; + + r =ioctl (kvm->vm_fd,KVM_ASSIGN_IRQFD , &data); +if (r ==-1 ) + r = -errno; +return r; +} + +int kvm_irqfd (kvm_context_t kvm,int gsi) +{ +int fd, r; + +if (!kvm_check_extension (kvm,KVM_CAP_IRQFD )) +return -ENOENT ; + + fd =eventfd (0 ,0 ); +if (fd <0 ) +return fd; + + r =assign_irqfd (kvm, fd, gsi); +if (r <0 ) +return r; + +return fd; +}
libkvm/libkvm.h +13 -0
@@ -856,6 +856,19 @@ int kvm_commit_irq_routes(kvm_context_t kvm);*/ int kvm_get_irq_route_gsi (kvm_context_t kvm); +/*! +* \brief Create a file descriptor for injecting interrupts +* +* Creates an eventfd based file-descriptor that maps to a specific GSI +* in the guest. eventfd compliant signaling (write() from userspace, or +* eventfd_signal() from kernelspace) will cause the GSI to inject +* itself into the guest at the next available window. +* +* \param kvm Pointer to the current kvm_context +* \param gsi GSI to assign to this fd +*/ +int kvm_irqfd (kvm_context_t kvm,int gsi); +#ifdef KVM_CAP_DEVICE_MSIX int kvm_assign_set_msix_nr (kvm_context_t kvm,struct kvm_assigned_msix_nr *msix_nr);
Quoted 4 lines · Gregory Haskins
libkvm/libkvm.c +4
-0+int kvm_irqfd (kvm_context_t kvm,int gsi) +{ +int fd, r; +
libkvm/libkvm.c int kvm_assign_set_msix_entry(kvm_context_t kvm, · line 1472
Quoted 10 lines
libkvm/libkvm.c +10
-0+if (!kvm_check_extension (kvm,KVM_CAP_IRQFD )) +return -ENOENT ; + + fd =eventfd (0 ,0 ); +if (fd <0 ) +return fd; + + r =assign_irqfd (kvm, fd, gsi); +if (r <0 ) +return r;
Do we need to close fd on error?
Quoted 3 lines
libkvm/libkvm.c +3
-0+ +return fd; +}
Quoted 11 lines · Michael S. Tsirkin
Quoted 9 lines · Gregory Haskins
libkvm/libkvm.c +9
-0+int kvm_irqfd (kvm_context_t kvm,int gsi) +{ +int fd, r; + +if (!kvm_check_extension (kvm,KVM_CAP_IRQFD )) +return -ENOENT ; + + fd =eventfd (0 ,0 ); +if (fd <0 )
Quoted 9 lines
libkvm/libkvm.c int kvm_assign_set_msix_entry(kvm_context_t kvm, · line 1472
Quoted 6 lines
libkvm/libkvm.c +5
-0+return fd; + + r =assign_irqfd (kvm, fd, gsi); +if (r <0 ) +return r;Do we need to close fd on error?
Good catch. This will be changing in v3 to do the allocation in kernel, but I will be sure to properly cleanup this type of leak, however that ends up looking.
Thanks Michael.
-Greg
Quoted 5 lines
Quoted 5 lines
libkvm/libkvm.c +3
-0+ +return fd; +}