[Qemu-devel] [PATCH 10/27] ppc/xive: Make XIVE generate the proper interrupt types

Cédric Le Goater posted 27 patches 6 years, 8 months ago
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Laurent Vivier <lvivier@redhat.com>, David Gibson <david@gibson.dropbear.id.au>, Thomas Huth <thuth@redhat.com>, "Cédric Le Goater" <clg@kaod.org>
There is a newer version of this series
[Qemu-devel] [PATCH 10/27] ppc/xive: Make XIVE generate the proper interrupt types
Posted by Cédric Le Goater 6 years, 8 months ago
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

It should be generic Hypervisor Virtualization interrupts for HV
directed rings and traditional External Interrupts for the OS directed
ring.

Don't generate anything for the user ring as it isn't actually
supported.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ppc/xive.h |  3 ++-
 hw/intc/xive.c        | 22 +++++++++++++++++++---
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
index c4f27742ca09..6b89dc7679f9 100644
--- a/include/hw/ppc/xive.h
+++ b/include/hw/ppc/xive.h
@@ -313,7 +313,8 @@ typedef struct XiveTCTX {
     DeviceState parent_obj;
 
     CPUState    *cs;
-    qemu_irq    output;
+    qemu_irq    hv_output;
+    qemu_irq    os_output;
 
     uint8_t     regs[XIVE_TM_RING_COUNT * XIVE_TM_RING_SIZE];
 } XiveTCTX;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index a0b87001da25..237e7b256dc0 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -61,13 +61,28 @@ static uint8_t exception_mask(uint8_t ring)
     }
 }
 
+static qemu_irq xive_tctx_output(XiveTCTX *tctx, uint8_t ring)
+{
+        switch (ring) {
+        case TM_QW0_USER:
+                return 0; /* Not supported */
+        case TM_QW1_OS:
+                return tctx->os_output;
+        case TM_QW2_HV_POOL:
+        case TM_QW3_HV_PHYS:
+                return tctx->hv_output;
+        default:
+                return 0;
+        }
+}
+
 static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
 {
     uint8_t *regs = &tctx->regs[ring];
     uint8_t nsr = regs[TM_NSR];
     uint8_t mask = exception_mask(ring);
 
-    qemu_irq_lower(tctx->output);
+    qemu_irq_lower(xive_tctx_output(tctx, ring));
 
     if (regs[TM_NSR] & mask) {
         uint8_t cppr = regs[TM_PIPR];
@@ -100,7 +115,7 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
         default:
             g_assert_not_reached();
         }
-        qemu_irq_raise(tctx->output);
+        qemu_irq_raise(xive_tctx_output(tctx, ring));
     }
 }
 
@@ -546,7 +561,8 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp)
     env = &cpu->env;
     switch (PPC_INPUT(env)) {
     case PPC_FLAGS_INPUT_POWER9:
-        tctx->output = env->irq_inputs[POWER9_INPUT_INT];
+        tctx->hv_output = env->irq_inputs[POWER9_INPUT_HINT];
+        tctx->os_output = env->irq_inputs[POWER9_INPUT_INT];
         break;
 
     default:
-- 
2.20.1


Re: [Qemu-devel] [PATCH 10/27] ppc/xive: Make XIVE generate the proper interrupt types
Posted by David Gibson 6 years, 8 months ago
On Wed, Mar 06, 2019 at 09:50:15AM +0100, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> It should be generic Hypervisor Virtualization interrupts for HV
> directed rings and traditional External Interrupts for the OS directed
> ring.
> 
> Don't generate anything for the user ring as it isn't actually
> supported.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  include/hw/ppc/xive.h |  3 ++-
>  hw/intc/xive.c        | 22 +++++++++++++++++++---
>  2 files changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index c4f27742ca09..6b89dc7679f9 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -313,7 +313,8 @@ typedef struct XiveTCTX {
>      DeviceState parent_obj;
>  
>      CPUState    *cs;
> -    qemu_irq    output;
> +    qemu_irq    hv_output;
> +    qemu_irq    os_output;
>  
>      uint8_t     regs[XIVE_TM_RING_COUNT * XIVE_TM_RING_SIZE];
>  } XiveTCTX;
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index a0b87001da25..237e7b256dc0 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -61,13 +61,28 @@ static uint8_t exception_mask(uint8_t ring)
>      }
>  }
>  
> +static qemu_irq xive_tctx_output(XiveTCTX *tctx, uint8_t ring)
> +{
> +        switch (ring) {
> +        case TM_QW0_USER:
> +                return 0; /* Not supported */

IIUC hitting this case would indicate a code error, not a guest error,
in which case g_assert_not_reached() would be more appropriate that
returning 0.

Return "0" is kind of weird.  qemu_irq is actually a pointer so this
is really returning NULL.  But I don't think most things that handle
qemu_irq expect them to be NULL, so it's likely that this will just
crash further on.

Apart from that, LGTM.

> +        case TM_QW1_OS:
> +                return tctx->os_output;
> +        case TM_QW2_HV_POOL:
> +        case TM_QW3_HV_PHYS:
> +                return tctx->hv_output;
> +        default:
> +                return 0;
> +        }
> +}
> +
>  static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
>  {
>      uint8_t *regs = &tctx->regs[ring];
>      uint8_t nsr = regs[TM_NSR];
>      uint8_t mask = exception_mask(ring);
>  
> -    qemu_irq_lower(tctx->output);
> +    qemu_irq_lower(xive_tctx_output(tctx, ring));
>  
>      if (regs[TM_NSR] & mask) {
>          uint8_t cppr = regs[TM_PIPR];
> @@ -100,7 +115,7 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
>          default:
>              g_assert_not_reached();
>          }
> -        qemu_irq_raise(tctx->output);
> +        qemu_irq_raise(xive_tctx_output(tctx, ring));
>      }
>  }
>  
> @@ -546,7 +561,8 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp)
>      env = &cpu->env;
>      switch (PPC_INPUT(env)) {
>      case PPC_FLAGS_INPUT_POWER9:
> -        tctx->output = env->irq_inputs[POWER9_INPUT_INT];
> +        tctx->hv_output = env->irq_inputs[POWER9_INPUT_HINT];
> +        tctx->os_output = env->irq_inputs[POWER9_INPUT_INT];
>          break;
>  
>      default:

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson