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; >