Patchwork xics: added end-of-interrupt (EOI) handlers

login
register
mail settings
Submitter Alexey Kardashevskiy
Date July 10, 2012, 1:46 p.m.
Message ID <1341927973-5615-5-git-send-email-aik@ozlabs.ru>
Download mbox | patch
Permalink /patch/170183/
State New
Headers show

Comments

Alexey Kardashevskiy - July 10, 2012, 1:46 p.m.
Normally when the host driver gets called via interrupt, it disables IRQ
first, then handles it and enables back. In the case of PCI pass through,
the actual handling is done by the guest so the host driver needs to know
when to enable IRQ back.

The patch introduces add/remove callback API and EOI initialization for
the XICS interrupt controller.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 hw/xics.c |   18 ++++++++++++++++++
 hw/xics.h |    5 +++++
 2 files changed, 23 insertions(+)
Alexey Kardashevskiy - July 13, 2012, 8:04 a.m.
Already outdated :)

On 10/07/12 23:46, Alexey Kardashevskiy wrote:
> Normally when the host driver gets called via interrupt, it disables IRQ
> first, then handles it and enables back. In the case of PCI pass through,
> the actual handling is done by the guest so the host driver needs to know
> when to enable IRQ back.
> 
> The patch introduces add/remove callback API and EOI initialization for
> the XICS interrupt controller.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
>  hw/xics.c |   18 ++++++++++++++++++
>  hw/xics.h |    5 +++++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/hw/xics.c b/hw/xics.c
> index 668a0d6..de7833e 100644
> --- a/hw/xics.c
> +++ b/hw/xics.c
> @@ -170,6 +170,7 @@ struct ics_irq_state {
>      int sent:1;
>      int rejected:1;
>      int masked_pending:1;
> +    NotifierList eoi_notifier;
>  };
>  
>  struct ics_state {
> @@ -309,6 +310,8 @@ static void ics_eoi(struct ics_state *ics, int nr)
>      if (irq->type == XICS_LSI) {
>          irq->sent = 0;
>      }
> +
> +    notifier_list_notify(&irq->eoi_notifier, NULL);
>  }
>  
>  /*
> @@ -536,6 +539,7 @@ struct icp_state *xics_system_init(int nr_irqs)
>      for (i = 0; i < nr_irqs; i++) {
>          ics->irqs[i].priority = 0xff;
>          ics->irqs[i].saved_priority = 0xff;
> +        notifier_list_init(&ics->irqs[i].eoi_notifier);
>      }
>  
>      ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, nr_irqs);
> @@ -552,3 +556,17 @@ struct icp_state *xics_system_init(int nr_irqs)
>  
>      return icp;
>  }
> +
> +void xics_add_eoi_notifier(Notifier *notify, uint32_t srcno)
> +{
> +    struct ics_state *ics = spapr->icp->ics;
> +    struct ics_irq_state *irq = &ics->irqs[srcno - ics->offset];
> +
> +    notifier_list_add(&irq->eoi_notifier, notify);
> +}
> +
> +void xics_remove_eoi_notifier(Notifier *notify)
> +{
> +    notifier_remove(notify);
> +}
> +
> diff --git a/hw/xics.h b/hw/xics.h
> index 2080159..762243c 100644
> --- a/hw/xics.h
> +++ b/hw/xics.h
> @@ -27,6 +27,8 @@
>  #if !defined(__XICS_H__)
>  #define __XICS_H__
>  
> +#include "notify.h"
> +
>  #define XICS_IPI        0x2
>  
>  struct icp_state;
> @@ -41,4 +43,7 @@ qemu_irq xics_assign_irq(struct icp_state *icp, int irq,
>  
>  struct icp_state *xics_system_init(int nr_irqs);
>  
> +void xics_add_eoi_notifier(Notifier *notify, uint32_t srcno);
> +void xics_remove_eoi_notifier(Notifier *notify);
> +
>  #endif /* __XICS_H__ */
>

Patch

diff --git a/hw/xics.c b/hw/xics.c
index 668a0d6..de7833e 100644
--- a/hw/xics.c
+++ b/hw/xics.c
@@ -170,6 +170,7 @@  struct ics_irq_state {
     int sent:1;
     int rejected:1;
     int masked_pending:1;
+    NotifierList eoi_notifier;
 };
 
 struct ics_state {
@@ -309,6 +310,8 @@  static void ics_eoi(struct ics_state *ics, int nr)
     if (irq->type == XICS_LSI) {
         irq->sent = 0;
     }
+
+    notifier_list_notify(&irq->eoi_notifier, NULL);
 }
 
 /*
@@ -536,6 +539,7 @@  struct icp_state *xics_system_init(int nr_irqs)
     for (i = 0; i < nr_irqs; i++) {
         ics->irqs[i].priority = 0xff;
         ics->irqs[i].saved_priority = 0xff;
+        notifier_list_init(&ics->irqs[i].eoi_notifier);
     }
 
     ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, nr_irqs);
@@ -552,3 +556,17 @@  struct icp_state *xics_system_init(int nr_irqs)
 
     return icp;
 }
+
+void xics_add_eoi_notifier(Notifier *notify, uint32_t srcno)
+{
+    struct ics_state *ics = spapr->icp->ics;
+    struct ics_irq_state *irq = &ics->irqs[srcno - ics->offset];
+
+    notifier_list_add(&irq->eoi_notifier, notify);
+}
+
+void xics_remove_eoi_notifier(Notifier *notify)
+{
+    notifier_remove(notify);
+}
+
diff --git a/hw/xics.h b/hw/xics.h
index 2080159..762243c 100644
--- a/hw/xics.h
+++ b/hw/xics.h
@@ -27,6 +27,8 @@ 
 #if !defined(__XICS_H__)
 #define __XICS_H__
 
+#include "notify.h"
+
 #define XICS_IPI        0x2
 
 struct icp_state;
@@ -41,4 +43,7 @@  qemu_irq xics_assign_irq(struct icp_state *icp, int irq,
 
 struct icp_state *xics_system_init(int nr_irqs);
 
+void xics_add_eoi_notifier(Notifier *notify, uint32_t srcno);
+void xics_remove_eoi_notifier(Notifier *notify);
+
 #endif /* __XICS_H__ */