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

Reply via email to