On 1/13/20 2:01 PM, Cédric Le Goater wrote:
> From: Frederic Barrat <fbar...@linux.ibm.com>
> 
> A load on an ESB page returning all 1's means that the underlying
> device has invalidated the access to the PQ state of the interrupt
> through mmio. It may happen, for example when querying a PHB interrupt
> while the PHB is in an error state.
> 
> In that case, we should consider the interrupt to be invalid when
> checking its state in the irq_get_irqchip_state() handler.


and we need also these tags :

Fixes: da15c03b047d ("powerpc/xive: Implement get_irqchip_state method for XIVE 
to fix shutdown race")
Cc: sta...@vger.kernel.org # v5.3+



> Cc: Paul Mackerras <pau...@ozlabs.org>
> Signed-off-by: Frederic Barrat <fbar...@linux.ibm.com>
> [ clg: - wrote a commit log
>        - introduced XIVE_ESB_INVALID ]
> Signed-off-by: Cédric Le Goater <c...@kaod.org>
> ---
>  arch/powerpc/include/asm/xive-regs.h |  1 +
>  arch/powerpc/sysdev/xive/common.c    | 15 ++++++++++++---
>  2 files changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/xive-regs.h 
> b/arch/powerpc/include/asm/xive-regs.h
> index f2dfcd50a2d3..33aee7490cbb 100644
> --- a/arch/powerpc/include/asm/xive-regs.h
> +++ b/arch/powerpc/include/asm/xive-regs.h
> @@ -39,6 +39,7 @@
>  
>  #define XIVE_ESB_VAL_P               0x2
>  #define XIVE_ESB_VAL_Q               0x1
> +#define XIVE_ESB_INVALID     0xFF
>  
>  /*
>   * Thread Management (aka "TM") registers
> diff --git a/arch/powerpc/sysdev/xive/common.c 
> b/arch/powerpc/sysdev/xive/common.c
> index f5fadbd2533a..9651ca061828 100644
> --- a/arch/powerpc/sysdev/xive/common.c
> +++ b/arch/powerpc/sysdev/xive/common.c
> @@ -972,12 +972,21 @@ static int xive_get_irqchip_state(struct irq_data *data,
>                                 enum irqchip_irq_state which, bool *state)
>  {
>       struct xive_irq_data *xd = irq_data_get_irq_handler_data(data);
> +     u8 pq;
>  
>       switch (which) {
>       case IRQCHIP_STATE_ACTIVE:
> -             *state = !xd->stale_p &&
> -                      (xd->saved_p ||
> -                       !!(xive_esb_read(xd, XIVE_ESB_GET) & XIVE_ESB_VAL_P));
> +             pq = xive_esb_read(xd, XIVE_ESB_GET);
> +
> +             /*
> +              * The esb value being all 1's means we couldn't get
> +              * the PQ state of the interrupt through mmio. It may
> +              * happen, for example when querying a PHB interrupt
> +              * while the PHB is in an error state. We consider the
> +              * interrupt to be inactive in that case.
> +              */
> +             *state = (pq != XIVE_ESB_INVALID) && !xd->stale_p &&
> +                     (xd->saved_p || !!(pq & XIVE_ESB_VAL_P));
>               return 0;
>       default:
>               return -EINVAL;
> 

Reply via email to