diff mbox

[RFC,18/34] hyperv: add support for KVM_HYPERV_EVENTFD

Message ID 20180206203048.11096-19-rkagan@virtuozzo.com (mailing list archive)
State New, archived
Headers show

Commit Message

Roman Kagan Feb. 6, 2018, 8:30 p.m. UTC
When setting up a notifier for Hyper-V event connection, attempt to use
the KVM-assisted one first, and fall back to userspace handling of the
hypercall if the kernel doesn't provide the requested feature.

Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
---
 include/sysemu/kvm.h |  1 +
 accel/kvm/kvm-all.c  | 15 +++++++++++++++
 target/i386/hyperv.c | 21 ++++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)

Comments

Paolo Bonzini Feb. 7, 2018, 11:01 a.m. UTC | #1
On 06/02/2018 21:30, Roman Kagan wrote:
> When setting up a notifier for Hyper-V event connection, attempt to use
> the KVM-assisted one first, and fall back to userspace handling of the
> hypercall if the kernel doesn't provide the requested feature.
> 
> Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>

As before, I wouldn't mind dropping userspace SIGNAL_EVENT altogether.
It would probably end up in bitrot.

Thanks,

Paolo

> ---
>  include/sysemu/kvm.h |  1 +
>  accel/kvm/kvm-all.c  | 15 +++++++++++++++
>  target/i386/hyperv.c | 21 ++++++++++++++++++++-
>  3 files changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index bbf12a1723..70ad0a54b7 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -496,6 +496,7 @@ void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi);
>  void kvm_pc_gsi_handler(void *opaque, int n, int level);
>  void kvm_pc_setup_irq_routing(bool pci_enabled);
>  void kvm_init_irq_routing(KVMState *s);
> +int kvm_set_hv_event_notifier(KVMState *s, uint32_t conn_id, EventNotifier *n);
>  
>  /**
>   * kvm_arch_irqchip_create:
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index f290f487a5..c3ba87b701 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -1423,6 +1423,21 @@ static void kvm_irqchip_create(MachineState *machine, KVMState *s)
>      s->gsimap = g_hash_table_new(g_direct_hash, g_direct_equal);
>  }
>  
> +int kvm_set_hv_event_notifier(KVMState *s, uint32_t conn_id, EventNotifier *n)
> +{
> +    struct kvm_hyperv_eventfd hvevfd = {
> +        .conn_id = conn_id,
> +        .fd = n ? event_notifier_get_fd(n) : -1,
> +        .flags = n ? 0 : KVM_HYPERV_EVENTFD_DEASSIGN,
> +    };
> +
> +    if (!kvm_check_extension(s, KVM_CAP_HYPERV_EVENTFD)) {
> +        return -ENOSYS;
> +    }
> +
> +    return kvm_vm_ioctl(s, KVM_HYPERV_EVENTFD, &hvevfd);
> +}
> +
>  /* Find number of supported CPUs using the recommended
>   * procedure from the kernel API documentation to cope with
>   * older kernels that may be missing capabilities.
> diff --git a/target/i386/hyperv.c b/target/i386/hyperv.c
> index e43cbb9322..63dcb23fa8 100644
> --- a/target/i386/hyperv.c
> +++ b/target/i386/hyperv.c
> @@ -313,7 +313,8 @@ unlock:
>      return ret;
>  }
>  
> -int hyperv_set_evt_notifier(uint32_t conn_id, EventNotifier *notifier)
> +static int hyperv_set_evt_notifier_userspace(uint32_t conn_id,
> +                                             EventNotifier *notifier)
>  {
>      int ret;
>      EvtHandler *eh;
> @@ -346,6 +347,24 @@ unlock:
>      return ret;
>  }
>  
> +static bool hv_evt_notifier_userspace;
> +
> +int hyperv_set_evt_notifier(uint32_t conn_id, EventNotifier *notifier)
> +{
> +    if (!hv_evt_notifier_userspace) {
> +        int ret = kvm_set_hv_event_notifier(kvm_state, conn_id, notifier);
> +        if (ret != -ENOSYS) {
> +            return ret;
> +        }
> +
> +        hv_evt_notifier_userspace = true;
> +        warn_report("Hyper-V event signaling in KVM not supported; "
> +                    "using slower userspace hypercall processing");
> +    }
> +
> +    return hyperv_set_evt_notifier_userspace(conn_id, notifier);
> +}
> +
>  static uint64_t hvcall_post_message(uint64_t param, bool fast)
>  {
>      uint64_t ret;
>
Roman Kagan Feb. 7, 2018, 7:19 p.m. UTC | #2
On Wed, Feb 07, 2018 at 12:01:41PM +0100, Paolo Bonzini wrote:
> On 06/02/2018 21:30, Roman Kagan wrote:
> > When setting up a notifier for Hyper-V event connection, attempt to use
> > the KVM-assisted one first, and fall back to userspace handling of the
> > hypercall if the kernel doesn't provide the requested feature.
> > 
> > Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
> 
> As before, I wouldn't mind dropping userspace SIGNAL_EVENT altogether.

That would mean not allowing vmbus stuff on a range of otherwise usable
kernels, including 4.14 which AFAIK has been declared LTS.
Note that HYPERV_EVENTFD hasn't even landed in the mainline kernel yet
(with any luck it'll make 4.16).

> It would probably end up in bitrot.

Like every compatibilty code...

Thanks,
Roman.
Paolo Bonzini Feb. 8, 2018, 3:03 p.m. UTC | #3
On 07/02/2018 20:19, Roman Kagan wrote:
>> As before, I wouldn't mind dropping userspace SIGNAL_EVENT altogether.
> That would mean not allowing vmbus stuff on a range of otherwise usable
> kernels, including 4.14 which AFAIK has been declared LTS.
> Note that HYPERV_EVENTFD hasn't even landed in the mainline kernel yet
> (with any luck it'll make 4.16).

Fair enough.

Paolo
diff mbox

Patch

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index bbf12a1723..70ad0a54b7 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -496,6 +496,7 @@  void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi);
 void kvm_pc_gsi_handler(void *opaque, int n, int level);
 void kvm_pc_setup_irq_routing(bool pci_enabled);
 void kvm_init_irq_routing(KVMState *s);
+int kvm_set_hv_event_notifier(KVMState *s, uint32_t conn_id, EventNotifier *n);
 
 /**
  * kvm_arch_irqchip_create:
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f290f487a5..c3ba87b701 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1423,6 +1423,21 @@  static void kvm_irqchip_create(MachineState *machine, KVMState *s)
     s->gsimap = g_hash_table_new(g_direct_hash, g_direct_equal);
 }
 
+int kvm_set_hv_event_notifier(KVMState *s, uint32_t conn_id, EventNotifier *n)
+{
+    struct kvm_hyperv_eventfd hvevfd = {
+        .conn_id = conn_id,
+        .fd = n ? event_notifier_get_fd(n) : -1,
+        .flags = n ? 0 : KVM_HYPERV_EVENTFD_DEASSIGN,
+    };
+
+    if (!kvm_check_extension(s, KVM_CAP_HYPERV_EVENTFD)) {
+        return -ENOSYS;
+    }
+
+    return kvm_vm_ioctl(s, KVM_HYPERV_EVENTFD, &hvevfd);
+}
+
 /* Find number of supported CPUs using the recommended
  * procedure from the kernel API documentation to cope with
  * older kernels that may be missing capabilities.
diff --git a/target/i386/hyperv.c b/target/i386/hyperv.c
index e43cbb9322..63dcb23fa8 100644
--- a/target/i386/hyperv.c
+++ b/target/i386/hyperv.c
@@ -313,7 +313,8 @@  unlock:
     return ret;
 }
 
-int hyperv_set_evt_notifier(uint32_t conn_id, EventNotifier *notifier)
+static int hyperv_set_evt_notifier_userspace(uint32_t conn_id,
+                                             EventNotifier *notifier)
 {
     int ret;
     EvtHandler *eh;
@@ -346,6 +347,24 @@  unlock:
     return ret;
 }
 
+static bool hv_evt_notifier_userspace;
+
+int hyperv_set_evt_notifier(uint32_t conn_id, EventNotifier *notifier)
+{
+    if (!hv_evt_notifier_userspace) {
+        int ret = kvm_set_hv_event_notifier(kvm_state, conn_id, notifier);
+        if (ret != -ENOSYS) {
+            return ret;
+        }
+
+        hv_evt_notifier_userspace = true;
+        warn_report("Hyper-V event signaling in KVM not supported; "
+                    "using slower userspace hypercall processing");
+    }
+
+    return hyperv_set_evt_notifier_userspace(conn_id, notifier);
+}
+
 static uint64_t hvcall_post_message(uint64_t param, bool fast)
 {
     uint64_t ret;