Signed-off-by: Gregory Haskins <[EMAIL PROTECTED]> --- drivers/kvm/kvm.h | 1 + drivers/kvm/kvm_main.c | 55 +++++++++++++++++++++++++++++++++++++++++++----- include/linux/kvm.h | 1 + 3 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index d5783dc..e1ba066 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -332,6 +332,7 @@ struct kvm_vcpu_irq { int pending; int deferred; int guest_cpu; + int eventfd; }; struct kvm_vcpu { diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 0c6a62a..7109b66 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -40,6 +40,7 @@ #include <linux/file.h> #include <linux/fs.h> #include <linux/mount.h> +#include <linux/eventfd.h> #include "x86_emulate.h" #include "segment_descriptor.h" @@ -326,6 +327,7 @@ static struct kvm *kvm_create_vm(void) memset(&vcpu->irq, 0, sizeof(vcpu->irq)); spin_lock_init(&vcpu->irq.lock); vcpu->irq.deferred = -1; + vcpu->irq.eventfd = -1; vcpu->cpu = -1; vcpu->kvm = kvm; @@ -2358,6 +2360,7 @@ static void kvm_vcpu_intr(struct kvm_irqsink *this, { struct kvm_vcpu *vcpu = (struct kvm_vcpu*)this->private; int direct_ipi = -1; + int eventfd = -1; spin_lock_irq(&vcpu->irq.lock); @@ -2379,7 +2382,14 @@ static void kvm_vcpu_intr(struct kvm_irqsink *this, */ direct_ipi = vcpu->irq.guest_cpu; BUG_ON(direct_ipi == smp_processor_id()); - } + } else + /* + * otherwise, we must assume that we could be + * blocked anywhere, including userspace. Send + * a signal to give everyone a chance to get + * notification + */ + eventfd = vcpu->irq.eventfd; } } @@ -2401,6 +2411,12 @@ static void kvm_vcpu_intr(struct kvm_irqsink *this, smp_call_function_single(direct_ipi, kvm_vcpu_guest_intr, vcpu, 0, 0); + + if (eventfd != -1) { + struct file *filp = eventfd_fget(eventfd); + if (!IS_ERR(filp)) + eventfd_signal(filp, 1); + } } static void kvm_vcpu_irqsink_init(struct kvm_vcpu *vcpu) @@ -2584,6 +2600,17 @@ static int kvm_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) return 0; } +static int kvm_vcpu_ioctl_set_eventfd(struct kvm_vcpu *vcpu, int fd) +{ + if (IS_ERR(eventfd_fget(fd))) + return -EINVAL; + + vcpu->irq.eventfd = fd; + smp_wmb(); + + return 0; +} + static long kvm_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -2753,6 +2780,15 @@ static long kvm_vcpu_ioctl(struct file *filp, r = 0; break; } + case KVM_SET_EVENTFD: { + int eventfd = (long)argp; + + r = kvm_vcpu_ioctl_set_eventfd(vcpu, eventfd); + if (r) + goto out; + r = 0; + break; + } default: ; } @@ -2937,12 +2973,19 @@ static long kvm_dev_ioctl(struct file *filp, r = 0; break; } - case KVM_CHECK_EXTENSION: - /* - * No extensions defined at present. - */ - r = 0; + case KVM_CHECK_EXTENSION: { + int ext = (long)argp; + + switch (ext) { + case KVM_SET_EVENTFD: + r = 1; + break; + default: + r = 0; + break; + } break; + } case KVM_GET_VCPU_MMAP_SIZE: r = -EINVAL; if (arg) diff --git a/include/linux/kvm.h b/include/linux/kvm.h index e6edca8..f13ec8c 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -300,5 +300,6 @@ struct kvm_signal_mask { #define KVM_SET_SIGNAL_MASK _IOW(KVMIO, 0x8b, struct kvm_signal_mask) #define KVM_GET_FPU _IOR(KVMIO, 0x8c, struct kvm_fpu) #define KVM_SET_FPU _IOW(KVMIO, 0x8d, struct kvm_fpu) +#define KVM_SET_EVENTFD _IO(KVMIO, 0x8e) #endif ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel