[1/6] xive: Mark a freed IRQ's IVE as valid and masked

Message ID 20171206173928.25628-1-benh@kernel.crashing.org
State Superseded
Headers show
Series
  • [1/6] xive: Mark a freed IRQ's IVE as valid and masked
Related show

Commit Message

Benjamin Herrenschmidt Dec. 6, 2017, 5:39 p.m.
Removing the valid bit means a FIR will trip if it's accessed
inadvertently. Under some circumstances, the XIVE will speculatively
access an IVE for a masked interrupt and trip it. So make sure that
freed entries are still marked valid (but masked).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 hw/xive.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Oliver Dec. 7, 2017, 12:39 a.m. | #1
Tested-by: Oliver O'Halloran <oohall@gmail.com>

On Thu, Dec 7, 2017 at 4:39 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> Removing the valid bit means a FIR will trip if it's accessed
> inadvertently. Under some circumstances, the XIVE will speculatively
> access an IVE for a masked interrupt and trip it. So make sure that
> freed entries are still marked valid (but masked).
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>  hw/xive.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/xive.c b/hw/xive.c
> index e9aa030d..364be549 100644
> --- a/hw/xive.c
> +++ b/hw/xive.c
> @@ -5116,7 +5116,7 @@ static int64_t opal_xive_free_irq(uint32_t girq)
>         xive_update_irq_mask(s, girq - s->esb_base, true);
>
>         /* Mark the IVE masked and invalid */
> -       ive->w = IVE_MASKED;
> +       ive->w = IVE_MASKED | IVE_VALID;
>         xive_ivc_scrub(x, x->block_id, idx);
>
>         /* Free it */
> --
> 2.14.3
>
> _______________________________________________
> Skiboot mailing list
> Skiboot@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot

Patch

diff --git a/hw/xive.c b/hw/xive.c
index e9aa030d..364be549 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -5116,7 +5116,7 @@  static int64_t opal_xive_free_irq(uint32_t girq)
 	xive_update_irq_mask(s, girq - s->esb_base, true);
 
 	/* Mark the IVE masked and invalid */
-	ive->w = IVE_MASKED;
+	ive->w = IVE_MASKED | IVE_VALID;
 	xive_ivc_scrub(x, x->block_id, idx);
 
 	/* Free it */