diff mbox

[RESEND,v16,3/6] kvm-all.c: add qemu_irq/gsi hash table and utility routines

Message ID 1434386038-9246-4-git-send-email-eric.auger@linaro.org
State New
Headers show

Commit Message

Eric Auger June 15, 2015, 4:33 p.m. UTC
VFIO platform device needs to setup irqfd but it does not know the
gsi corresponding to the device qemu_irq. This series proposes to
store a hash table in kvm_state using the qemu_irq as key and the gsi
as a value.

kvm_irqchip_set_qemuirq_gsi allows to insert such a pair. The interrupt
controller is supposed to use it.

kvm_irqchip_[add, remove]_irqfd_notifier allows to setup/tear down
irqfd directly from the qemu_irq.

Signed-off-by: Eric Auger <eric.auger@linaro.org>
Tested-by: Vikram Sethi <vikrams@codeaurora.org>

---

v15 -> v16:
- Added Vikram's T-b

v13 -> v14:
- correct checkpatch warning

v2 -> v3 (integration into VFIO series v13):
- rename kvm_irqchip_[add, remove]_qemuirq_irqfd_notifier into
  kvm_irqchip_[add, remove]_irqfd_notifier. Possible since legacy
  functions were also renamed with _gsi suffix.

V1 -> v2:
- qemu_irq get_gsi callback replaced by hash table stored in kvm
---
 include/sysemu/kvm.h |  6 ++++++
 kvm-all.c            | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

Comments

Paolo Bonzini June 24, 2015, 9:53 a.m. UTC | #1
On 15/06/2015 18:33, Eric Auger wrote:
> VFIO platform device needs to setup irqfd but it does not know the
> gsi corresponding to the device qemu_irq. This series proposes to
> store a hash table in kvm_state using the qemu_irq as key and the gsi
> as a value.
> 
> kvm_irqchip_set_qemuirq_gsi allows to insert such a pair. The interrupt
> controller is supposed to use it.
> 
> kvm_irqchip_[add, remove]_irqfd_notifier allows to setup/tear down
> irqfd directly from the qemu_irq.
> 
> Signed-off-by: Eric Auger <eric.auger@linaro.org>
> Tested-by: Vikram Sethi <vikrams@codeaurora.org>

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

> ---
> 
> v15 -> v16:
> - Added Vikram's T-b
> 
> v13 -> v14:
> - correct checkpatch warning
> 
> v2 -> v3 (integration into VFIO series v13):
> - rename kvm_irqchip_[add, remove]_qemuirq_irqfd_notifier into
>   kvm_irqchip_[add, remove]_irqfd_notifier. Possible since legacy
>   functions were also renamed with _gsi suffix.
> 
> V1 -> v2:
> - qemu_irq get_gsi callback replaced by hash table stored in kvm
> ---
>  include/sysemu/kvm.h |  6 ++++++
>  kvm-all.c            | 37 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index acb3025..ba612fc 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -19,6 +19,7 @@
>  #include "qemu/queue.h"
>  #include "qom/cpu.h"
>  #include "exec/memattrs.h"
> +#include "hw/irq.h"
>  
>  #ifdef CONFIG_KVM
>  #include <linux/kvm.h>
> @@ -420,6 +421,11 @@ int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>                                         EventNotifier *rn, int virq);
>  int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>                                            int virq);
> +int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
> +                                   EventNotifier *rn, qemu_irq irq);
> +int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
> +                                      qemu_irq irq);
> +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);
> diff --git a/kvm-all.c b/kvm-all.c
> index 730b818..939bfc4 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -37,6 +37,7 @@
>  #include "exec/address-spaces.h"
>  #include "qemu/event_notifier.h"
>  #include "trace.h"
> +#include "hw/irq.h"
>  
>  #include "hw/boards.h"
>  
> @@ -98,6 +99,7 @@ struct KVMState
>       * unsigned, and treating them as signed here can break things */
>      unsigned irq_set_ioctl;
>      unsigned int sigmask_len;
> +    GHashTable *gsimap;
>  #ifdef KVM_CAP_IRQ_ROUTING
>      struct kvm_irq_routing *irq_routes;
>      int nr_allocated_irq_routes;
> @@ -1339,6 +1341,39 @@ int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>             false);
>  }
>  
> +int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
> +                                   EventNotifier *rn, qemu_irq irq)
> +{
> +    gpointer key, gsi;
> +    gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
> +
> +    if (!found) {
> +        return -ENXIO;
> +    } else {
> +        return kvm_irqchip_add_irqfd_notifier_gsi(s, n, rn,
> +                                                  GPOINTER_TO_UINT(gsi));
> +    }
> +}
> +
> +int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
> +                                      qemu_irq irq)
> +{
> +    gpointer key, gsi;
> +    gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
> +
> +    if (!found) {
> +        return -ENXIO;
> +    } else {
> +        return kvm_irqchip_remove_irqfd_notifier_gsi(s, n,
> +                                                     GPOINTER_TO_INT(gsi));
> +    }
> +}
> +
> +void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi)
> +{
> +    g_hash_table_insert(s->gsimap, irq, GINT_TO_POINTER(gsi));
> +}
> +
>  static int kvm_irqchip_create(MachineState *machine, KVMState *s)
>  {
>      int ret;
> @@ -1371,6 +1406,8 @@ static int kvm_irqchip_create(MachineState *machine, KVMState *s)
>  
>      kvm_init_irq_routing(s);
>  
> +    s->gsimap = g_hash_table_new(g_direct_hash, g_direct_equal);
> +
>      return 0;
>  }
>  
>
Peter Maydell June 26, 2015, 11:41 a.m. UTC | #2
On 15 June 2015 at 17:33, Eric Auger <eric.auger@linaro.org> wrote:
> VFIO platform device needs to setup irqfd but it does not know the
> gsi corresponding to the device qemu_irq. This series proposes to
> store a hash table in kvm_state using the qemu_irq as key and the gsi
> as a value.
>
> kvm_irqchip_set_qemuirq_gsi allows to insert such a pair. The interrupt
> controller is supposed to use it.
>
> kvm_irqchip_[add, remove]_irqfd_notifier allows to setup/tear down
> irqfd directly from the qemu_irq.
>
> Signed-off-by: Eric Auger <eric.auger@linaro.org>
> Tested-by: Vikram Sethi <vikrams@codeaurora.org>
>
> ---
>
> v15 -> v16:
> - Added Vikram's T-b
>
> v13 -> v14:
> - correct checkpatch warning
>
> v2 -> v3 (integration into VFIO series v13):
> - rename kvm_irqchip_[add, remove]_qemuirq_irqfd_notifier into
>   kvm_irqchip_[add, remove]_irqfd_notifier. Possible since legacy
>   functions were also renamed with _gsi suffix.
>
> V1 -> v2:
> - qemu_irq get_gsi callback replaced by hash table stored in kvm
> ---
>  include/sysemu/kvm.h |  6 ++++++
>  kvm-all.c            | 37 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 43 insertions(+)
>
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index acb3025..ba612fc 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -19,6 +19,7 @@
>  #include "qemu/queue.h"
>  #include "qom/cpu.h"
>  #include "exec/memattrs.h"
> +#include "hw/irq.h"
>
>  #ifdef CONFIG_KVM
>  #include <linux/kvm.h>
> @@ -420,6 +421,11 @@ int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>                                         EventNotifier *rn, int virq);
>  int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>                                            int virq);
> +int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
> +                                   EventNotifier *rn, qemu_irq irq);
> +int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
> +                                      qemu_irq irq);
> +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);
> diff --git a/kvm-all.c b/kvm-all.c
> index 730b818..939bfc4 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -37,6 +37,7 @@
>  #include "exec/address-spaces.h"
>  #include "qemu/event_notifier.h"
>  #include "trace.h"
> +#include "hw/irq.h"
>
>  #include "hw/boards.h"
>
> @@ -98,6 +99,7 @@ struct KVMState
>       * unsigned, and treating them as signed here can break things */
>      unsigned irq_set_ioctl;
>      unsigned int sigmask_len;
> +    GHashTable *gsimap;
>  #ifdef KVM_CAP_IRQ_ROUTING
>      struct kvm_irq_routing *irq_routes;
>      int nr_allocated_irq_routes;
> @@ -1339,6 +1341,39 @@ int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>             false);
>  }
>
> +int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
> +                                   EventNotifier *rn, qemu_irq irq)
> +{
> +    gpointer key, gsi;
> +    gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
> +
> +    if (!found) {
> +        return -ENXIO;
> +    } else {
> +        return kvm_irqchip_add_irqfd_notifier_gsi(s, n, rn,
> +                                                  GPOINTER_TO_UINT(gsi));

Why do we use GPOINTER_TO_UINT() here...


> +    }
> +}
> +
> +int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
> +                                      qemu_irq irq)
> +{
> +    gpointer key, gsi;
> +    gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
> +
> +    if (!found) {
> +        return -ENXIO;
> +    } else {
> +        return kvm_irqchip_remove_irqfd_notifier_gsi(s, n,
> +                                                     GPOINTER_TO_INT(gsi));

...but GPOINTER_TO_INT() here?

(Aside: you don't need to put this code in an else {} clause, because
the if() part is returning anyway.)

> +    }
> +}
> +
> +void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi)
> +{
> +    g_hash_table_insert(s->gsimap, irq, GINT_TO_POINTER(gsi));
> +}
> +
>  static int kvm_irqchip_create(MachineState *machine, KVMState *s)
>  {
>      int ret;
> @@ -1371,6 +1406,8 @@ static int kvm_irqchip_create(MachineState *machine, KVMState *s)
>
>      kvm_init_irq_routing(s);
>
> +    s->gsimap = g_hash_table_new(g_direct_hash, g_direct_equal);
> +
>      return 0;
>  }

thanks
-- PMM
Eric Auger June 26, 2015, 11:56 a.m. UTC | #3
Hi Peter,

On 06/26/2015 01:41 PM, Peter Maydell wrote:
> On 15 June 2015 at 17:33, Eric Auger <eric.auger@linaro.org> wrote:
>> VFIO platform device needs to setup irqfd but it does not know the
>> gsi corresponding to the device qemu_irq. This series proposes to
>> store a hash table in kvm_state using the qemu_irq as key and the gsi
>> as a value.
>>
>> kvm_irqchip_set_qemuirq_gsi allows to insert such a pair. The interrupt
>> controller is supposed to use it.
>>
>> kvm_irqchip_[add, remove]_irqfd_notifier allows to setup/tear down
>> irqfd directly from the qemu_irq.
>>
>> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>> Tested-by: Vikram Sethi <vikrams@codeaurora.org>
>>
>> ---
>>
>> v15 -> v16:
>> - Added Vikram's T-b
>>
>> v13 -> v14:
>> - correct checkpatch warning
>>
>> v2 -> v3 (integration into VFIO series v13):
>> - rename kvm_irqchip_[add, remove]_qemuirq_irqfd_notifier into
>>   kvm_irqchip_[add, remove]_irqfd_notifier. Possible since legacy
>>   functions were also renamed with _gsi suffix.
>>
>> V1 -> v2:
>> - qemu_irq get_gsi callback replaced by hash table stored in kvm
>> ---
>>  include/sysemu/kvm.h |  6 ++++++
>>  kvm-all.c            | 37 +++++++++++++++++++++++++++++++++++++
>>  2 files changed, 43 insertions(+)
>>
>> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
>> index acb3025..ba612fc 100644
>> --- a/include/sysemu/kvm.h
>> +++ b/include/sysemu/kvm.h
>> @@ -19,6 +19,7 @@
>>  #include "qemu/queue.h"
>>  #include "qom/cpu.h"
>>  #include "exec/memattrs.h"
>> +#include "hw/irq.h"
>>
>>  #ifdef CONFIG_KVM
>>  #include <linux/kvm.h>
>> @@ -420,6 +421,11 @@ int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>>                                         EventNotifier *rn, int virq);
>>  int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>>                                            int virq);
>> +int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
>> +                                   EventNotifier *rn, qemu_irq irq);
>> +int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
>> +                                      qemu_irq irq);
>> +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);
>> diff --git a/kvm-all.c b/kvm-all.c
>> index 730b818..939bfc4 100644
>> --- a/kvm-all.c
>> +++ b/kvm-all.c
>> @@ -37,6 +37,7 @@
>>  #include "exec/address-spaces.h"
>>  #include "qemu/event_notifier.h"
>>  #include "trace.h"
>> +#include "hw/irq.h"
>>
>>  #include "hw/boards.h"
>>
>> @@ -98,6 +99,7 @@ struct KVMState
>>       * unsigned, and treating them as signed here can break things */
>>      unsigned irq_set_ioctl;
>>      unsigned int sigmask_len;
>> +    GHashTable *gsimap;
>>  #ifdef KVM_CAP_IRQ_ROUTING
>>      struct kvm_irq_routing *irq_routes;
>>      int nr_allocated_irq_routes;
>> @@ -1339,6 +1341,39 @@ int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
>>             false);
>>  }
>>
>> +int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
>> +                                   EventNotifier *rn, qemu_irq irq)
>> +{
>> +    gpointer key, gsi;
>> +    gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
>> +
>> +    if (!found) {
>> +        return -ENXIO;
>> +    } else {
>> +        return kvm_irqchip_add_irqfd_notifier_gsi(s, n, rn,
>> +                                                  GPOINTER_TO_UINT(gsi));
> 
> Why do we use GPOINTER_TO_UINT() here...
Hum yes GPOINTER_TO_INT is in accordance with
kvm_irqchip_add_irqfd_notifier_gsi signature
> 
> 
>> +    }
>> +}
>> +
>> +int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
>> +                                      qemu_irq irq)
>> +{
>> +    gpointer key, gsi;
>> +    gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
>> +
>> +    if (!found) {
>> +        return -ENXIO;
>> +    } else {
>> +        return kvm_irqchip_remove_irqfd_notifier_gsi(s, n,
>> +                                                     GPOINTER_TO_INT(gsi));
> 
> ...but GPOINTER_TO_INT() here?

> 
> (Aside: you don't need to put this code in an else {} clause, because
> the if() part is returning anyway.)
Indeed.

Do you wish I re-submit all the VFIO remaining patches as v17 or only
that one?

Thanks

Eric
> 
>> +    }
>> +}
>> +
>> +void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi)
>> +{
>> +    g_hash_table_insert(s->gsimap, irq, GINT_TO_POINTER(gsi));
>> +}
>> +
>>  static int kvm_irqchip_create(MachineState *machine, KVMState *s)
>>  {
>>      int ret;
>> @@ -1371,6 +1406,8 @@ static int kvm_irqchip_create(MachineState *machine, KVMState *s)
>>
>>      kvm_init_irq_routing(s);
>>
>> +    s->gsimap = g_hash_table_new(g_direct_hash, g_direct_equal);
>> +
>>      return 0;
>>  }
> 
> thanks
> -- PMM
>
diff mbox

Patch

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index acb3025..ba612fc 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -19,6 +19,7 @@ 
 #include "qemu/queue.h"
 #include "qom/cpu.h"
 #include "exec/memattrs.h"
+#include "hw/irq.h"
 
 #ifdef CONFIG_KVM
 #include <linux/kvm.h>
@@ -420,6 +421,11 @@  int kvm_irqchip_add_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
                                        EventNotifier *rn, int virq);
 int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
                                           int virq);
+int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
+                                   EventNotifier *rn, qemu_irq irq);
+int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
+                                      qemu_irq irq);
+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);
diff --git a/kvm-all.c b/kvm-all.c
index 730b818..939bfc4 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -37,6 +37,7 @@ 
 #include "exec/address-spaces.h"
 #include "qemu/event_notifier.h"
 #include "trace.h"
+#include "hw/irq.h"
 
 #include "hw/boards.h"
 
@@ -98,6 +99,7 @@  struct KVMState
      * unsigned, and treating them as signed here can break things */
     unsigned irq_set_ioctl;
     unsigned int sigmask_len;
+    GHashTable *gsimap;
 #ifdef KVM_CAP_IRQ_ROUTING
     struct kvm_irq_routing *irq_routes;
     int nr_allocated_irq_routes;
@@ -1339,6 +1341,39 @@  int kvm_irqchip_remove_irqfd_notifier_gsi(KVMState *s, EventNotifier *n,
            false);
 }
 
+int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
+                                   EventNotifier *rn, qemu_irq irq)
+{
+    gpointer key, gsi;
+    gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
+
+    if (!found) {
+        return -ENXIO;
+    } else {
+        return kvm_irqchip_add_irqfd_notifier_gsi(s, n, rn,
+                                                  GPOINTER_TO_UINT(gsi));
+    }
+}
+
+int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
+                                      qemu_irq irq)
+{
+    gpointer key, gsi;
+    gboolean found = g_hash_table_lookup_extended(s->gsimap, irq, &key, &gsi);
+
+    if (!found) {
+        return -ENXIO;
+    } else {
+        return kvm_irqchip_remove_irqfd_notifier_gsi(s, n,
+                                                     GPOINTER_TO_INT(gsi));
+    }
+}
+
+void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi)
+{
+    g_hash_table_insert(s->gsimap, irq, GINT_TO_POINTER(gsi));
+}
+
 static int kvm_irqchip_create(MachineState *machine, KVMState *s)
 {
     int ret;
@@ -1371,6 +1406,8 @@  static int kvm_irqchip_create(MachineState *machine, KVMState *s)
 
     kvm_init_irq_routing(s);
 
+    s->gsimap = g_hash_table_new(g_direct_hash, g_direct_equal);
+
     return 0;
 }