All of lore.kernel.org
 help / color / mirror / Atom feed
* ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")
@ 2017-06-22  7:48 Borislav Petkov
  2017-06-22  9:03 ` Thomas Backlund
  2017-06-27 11:12 ` Greg KH
  0 siblings, 2 replies; 7+ messages in thread
From: Borislav Petkov @ 2017-06-22  7:48 UTC (permalink / raw)
  To: stable
  Cc: Thomas Gleixner, Linus Walleij, Shah, Nehal-bakulchandra, Xue,
	Ken, S-k, Shyam-sundar, Sherry Hurwitz

Hi guys,

please pick up the commit in $Subject to where it applies as it fixes
boot issues on AMD Zen machines.

Thanks.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")
  2017-06-22  7:48 ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained") Borislav Petkov
@ 2017-06-22  9:03 ` Thomas Backlund
  2017-06-22  9:16   ` Borislav Petkov
  2017-06-27 11:12 ` Greg KH
  1 sibling, 1 reply; 7+ messages in thread
From: Thomas Backlund @ 2017-06-22  9:03 UTC (permalink / raw)
  To: Borislav Petkov, stable
  Cc: Thomas Gleixner, Linus Walleij, Shah, Nehal-bakulchandra, Xue,
	Ken, S-k, Shyam-sundar, Sherry Hurwitz

Den 22.06.2017 kl. 10:48, skrev Borislav Petkov:
> Hi guys,
> 
> please pick up the commit in $Subject to where it applies as it fixes
> boot issues on AMD Zen machines.
> 
> Thanks.
> 

If it's intended for 4.9 -longterm, a proper backport is needed.

--
Thomas

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")
  2017-06-22  9:03 ` Thomas Backlund
@ 2017-06-22  9:16   ` Borislav Petkov
  0 siblings, 0 replies; 7+ messages in thread
From: Borislav Petkov @ 2017-06-22  9:16 UTC (permalink / raw)
  To: Thomas Backlund
  Cc: stable, Thomas Gleixner, Linus Walleij, Shah, Nehal-bakulchandra,
	Xue, Ken, S-k, Shyam-sundar, Sherry Hurwitz

On Thu, Jun 22, 2017 at 12:03:50PM +0300, Thomas Backlund wrote:
> If it's intended for 4.9 -longterm, a proper backport is needed.

Something like this, I guess. But I need to find a box to test it.

---
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index c9a146948192..531e2224f38f 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -476,64 +476,54 @@ static struct irq_chip amd_gpio_irqchip = {
 	.irq_set_type = amd_gpio_irq_set_type,
 };
 
-static void amd_gpio_irq_handler(struct irq_desc *desc)
+#define PIN_IRQ_PENDING	(BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
+
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 {
-	u32 i;
-	u32 off;
-	u32 reg;
-	u32 pin_reg;
-	u64 reg64;
-	int handled = 0;
-	unsigned int irq;
+	struct amd_gpio *gpio_dev = dev_id;
+	struct gpio_chip *gc = &gpio_dev->gc;
+	irqreturn_t ret = IRQ_NONE;
+	unsigned int i, irqnr;
 	unsigned long flags;
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+	u32 *regs, regval;
+	u64 status, mask;
 
-	chained_irq_enter(chip, desc);
-	/*enable GPIO interrupt again*/
+	/* Read the wake status */
 	spin_lock_irqsave(&gpio_dev->lock, flags);
-	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
-	reg64 = reg;
-	reg64 = reg64 << 32;
-
-	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
-	reg64 |= reg;
+	status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
+	status <<= 32;
+	status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-	/*
-	 * first 46 bits indicates interrupt status.
-	 * one bit represents four interrupt sources.
-	*/
-	for (off = 0; off < 46 ; off++) {
-		if (reg64 & BIT(off)) {
-			for (i = 0; i < 4; i++) {
-				pin_reg = readl(gpio_dev->base +
-						(off * 4 + i) * 4);
-				if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
-					(pin_reg & BIT(WAKE_STS_OFF))) {
-					irq = irq_find_mapping(gc->irqdomain,
-								off * 4 + i);
-					generic_handle_irq(irq);
-					writel(pin_reg,
-						gpio_dev->base
-						+ (off * 4 + i) * 4);
-					handled++;
-				}
-			}
+	/* Bit 0-45 contain the relevant status bits */
+	status &= (1ULL << 46) - 1;
+	regs = gpio_dev->base;
+	for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
+		if (!(status & mask))
+			continue;
+		status &= ~mask;
+
+		/* Each status bit covers four pins */
+		for (i = 0; i < 4; i++) {
+			regval = readl(regs + i);
+			if (!(regval & PIN_IRQ_PENDING))
+				continue;
+			irq = irq_find_mapping(gc->irqdomain, irqnr + i);
+			generic_handle_irq(irq);
+			/* Clear interrupt */
+			writel(regval, regs + i);
+			ret = IRQ_HANDLED;
 		}
 	}
 
-	if (handled == 0)
-		handle_bad_irq(desc);
-
+	/* Signal EOI to the GPIO unit */
 	spin_lock_irqsave(&gpio_dev->lock, flags);
-	reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
-	reg |= EOI_MASK;
-	writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
+	regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
+	regval |= EOI_MASK;
+	writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-	chained_irq_exit(chip, desc);
+	return ret;
 }
 
 static int amd_get_groups_count(struct pinctrl_dev *pctldev)
@@ -801,10 +791,11 @@ static int amd_gpio_probe(struct platform_device *pdev)
 		goto out2;
 	}
 
-	gpiochip_set_chained_irqchip(&gpio_dev->gc,
-				 &amd_gpio_irqchip,
-				 irq_base,
-				 amd_gpio_irq_handler);
+	ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0,
+			       KBUILD_MODNAME, gpio_dev);
+	if (ret)
+		goto out2;
+
 
 	platform_set_drvdata(pdev, gpio_dev);
 

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")
  2017-06-22  7:48 ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained") Borislav Petkov
  2017-06-22  9:03 ` Thomas Backlund
@ 2017-06-27 11:12 ` Greg KH
  2017-06-27 12:33   ` Borislav Petkov
  1 sibling, 1 reply; 7+ messages in thread
From: Greg KH @ 2017-06-27 11:12 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: stable, Thomas Gleixner, Linus Walleij, Shah, Nehal-bakulchandra,
	Xue, Ken, S-k, Shyam-sundar, Sherry Hurwitz

On Thu, Jun 22, 2017 at 09:48:53AM +0200, Borislav Petkov wrote:
> Hi guys,
> 
> please pick up the commit in $Subject to where it applies as it fixes
> boot issues on AMD Zen machines.

Doesn't apply to any stable trees that I manage, can you please provide
a working backport if you want to see it added?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")
  2017-06-27 11:12 ` Greg KH
@ 2017-06-27 12:33   ` Borislav Petkov
  2017-06-28  8:44     ` Borislav Petkov
  0 siblings, 1 reply; 7+ messages in thread
From: Borislav Petkov @ 2017-06-27 12:33 UTC (permalink / raw)
  To: Greg KH
  Cc: stable, Thomas Gleixner, Linus Walleij, Shah, Nehal-bakulchandra,
	Xue, Ken, S-k, Shyam-sundar, Sherry Hurwitz

On Tue, Jun 27, 2017 at 01:12:00PM +0200, Greg KH wrote:
> Doesn't apply to any stable trees that I manage, can you please provide
> a working backport if you want to see it added?

Yeah, let me find the hw to test the backport first. I'll let you know.

Thanks.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")
  2017-06-27 12:33   ` Borislav Petkov
@ 2017-06-28  8:44     ` Borislav Petkov
  2017-07-03  8:42       ` Greg KH
  0 siblings, 1 reply; 7+ messages in thread
From: Borislav Petkov @ 2017-06-28  8:44 UTC (permalink / raw)
  To: Greg KH
  Cc: stable, Thomas Gleixner, Linus Walleij, Shah, Nehal-bakulchandra,
	Xue, Ken, S-k, Shyam-sundar, Sherry Hurwitz

On Tue, Jun 27, 2017 at 02:33:53PM +0200, Borislav Petkov wrote:
> On Tue, Jun 27, 2017 at 01:12:00PM +0200, Greg KH wrote:
> > Doesn't apply to any stable trees that I manage, can you please provide
> > a working backport if you want to see it added?
> 
> Yeah, let me find the hw to test the backport first. I'll let you know.

Ok, here's a 4.11 backport which applies cleanly ontop of 4.11.7 and has
been tested by a user.

---
From: Thomas Gleixner <tglx@linutronix.de>
Date: Tue, 23 May 2017 23:23:32 +0200
Subject: pinctrl/amd: Use regular interrupt instead of chained

commit ba714a9c1dea85e0bf2899d02dfeb9c70040427c upstream.

The AMD pinctrl driver uses a chained interrupt to demultiplex the GPIO
interrupts. Kevin Vandeventer reported, that his new AMD Ryzen locks up
hard on boot when the AMD pinctrl driver is initialized. The reason is an
interrupt storm. It's not clear whether that's caused by hardware or
firmware or both.

Using chained interrupts on X86 is a dangerous endavour. If a system is
misconfigured or the hardware buggy there is no safety net to catch an
interrupt storm.

Convert the driver to use a regular interrupt for the demultiplex
handler. This allows the interrupt storm detector to catch the malfunction
and lets the system boot up.

This should be backported to stable because it's likely that more users run
into this problem as the AMD Ryzen machines are spreading.

Reported-by: Kevin Vandeventer
Link: https://bugzilla.suse.com/show_bug.cgi?id=1034261
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
---
 drivers/pinctrl/pinctrl-amd.c |   91 ++++++++++++++++++------------------------
 1 file changed, 41 insertions(+), 50 deletions(-)

--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -495,64 +495,54 @@ static struct irq_chip amd_gpio_irqchip
 	.flags        = IRQCHIP_SKIP_SET_WAKE,
 };
 
-static void amd_gpio_irq_handler(struct irq_desc *desc)
+#define PIN_IRQ_PENDING	(BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
+
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 {
-	u32 i;
-	u32 off;
-	u32 reg;
-	u32 pin_reg;
-	u64 reg64;
-	int handled = 0;
-	unsigned int irq;
+	struct amd_gpio *gpio_dev = dev_id;
+	struct gpio_chip *gc = &gpio_dev->gc;
+	irqreturn_t ret = IRQ_NONE;
+	unsigned int i, irqnr;
 	unsigned long flags;
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+	u32 *regs, regval;
+	u64 status, mask;
 
-	chained_irq_enter(chip, desc);
-	/*enable GPIO interrupt again*/
+	/* Read the wake status */
 	spin_lock_irqsave(&gpio_dev->lock, flags);
-	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
-	reg64 = reg;
-	reg64 = reg64 << 32;
-
-	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
-	reg64 |= reg;
+	status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
+	status <<= 32;
+	status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-	/*
-	 * first 46 bits indicates interrupt status.
-	 * one bit represents four interrupt sources.
-	*/
-	for (off = 0; off < 46 ; off++) {
-		if (reg64 & BIT(off)) {
-			for (i = 0; i < 4; i++) {
-				pin_reg = readl(gpio_dev->base +
-						(off * 4 + i) * 4);
-				if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
-					(pin_reg & BIT(WAKE_STS_OFF))) {
-					irq = irq_find_mapping(gc->irqdomain,
-								off * 4 + i);
-					generic_handle_irq(irq);
-					writel(pin_reg,
-						gpio_dev->base
-						+ (off * 4 + i) * 4);
-					handled++;
-				}
-			}
+	/* Bit 0-45 contain the relevant status bits */
+	status &= (1ULL << 46) - 1;
+	regs = gpio_dev->base;
+	for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
+		if (!(status & mask))
+			continue;
+		status &= ~mask;
+
+		/* Each status bit covers four pins */
+		for (i = 0; i < 4; i++) {
+			regval = readl(regs + i);
+			if (!(regval & PIN_IRQ_PENDING))
+				continue;
+			irq = irq_find_mapping(gc->irqdomain, irqnr + i);
+			generic_handle_irq(irq);
+			/* Clear interrupt */
+			writel(regval, regs + i);
+			ret = IRQ_HANDLED;
 		}
 	}
 
-	if (handled == 0)
-		handle_bad_irq(desc);
-
+	/* Signal EOI to the GPIO unit */
 	spin_lock_irqsave(&gpio_dev->lock, flags);
-	reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
-	reg |= EOI_MASK;
-	writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
+	regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
+	regval |= EOI_MASK;
+	writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);
 
-	chained_irq_exit(chip, desc);
+	return ret;
 }
 
 static int amd_get_groups_count(struct pinctrl_dev *pctldev)
@@ -821,10 +811,11 @@ static int amd_gpio_probe(struct platfor
 		goto out2;
 	}
 
-	gpiochip_set_chained_irqchip(&gpio_dev->gc,
-				 &amd_gpio_irqchip,
-				 irq_base,
-				 amd_gpio_irq_handler);
+	ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0,
+			       KBUILD_MODNAME, gpio_dev);
+	if (ret)
+		goto out2;
+
 	platform_set_drvdata(pdev, gpio_dev);
 
 	dev_dbg(&pdev->dev, "amd gpio driver loaded\n");


-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")
  2017-06-28  8:44     ` Borislav Petkov
@ 2017-07-03  8:42       ` Greg KH
  0 siblings, 0 replies; 7+ messages in thread
From: Greg KH @ 2017-07-03  8:42 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: stable, Thomas Gleixner, Linus Walleij, Shah, Nehal-bakulchandra,
	Xue, Ken, S-k, Shyam-sundar, Sherry Hurwitz

On Wed, Jun 28, 2017 at 10:44:47AM +0200, Borislav Petkov wrote:
> On Tue, Jun 27, 2017 at 02:33:53PM +0200, Borislav Petkov wrote:
> > On Tue, Jun 27, 2017 at 01:12:00PM +0200, Greg KH wrote:
> > > Doesn't apply to any stable trees that I manage, can you please provide
> > > a working backport if you want to see it added?
> > 
> > Yeah, let me find the hw to test the backport first. I'll let you know.
> 
> Ok, here's a 4.11 backport which applies cleanly ontop of 4.11.7 and has
> been tested by a user.

Thanks, now queued up.

greg k-h

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-07-03  8:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-22  7:48 ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained") Borislav Petkov
2017-06-22  9:03 ` Thomas Backlund
2017-06-22  9:16   ` Borislav Petkov
2017-06-27 11:12 ` Greg KH
2017-06-27 12:33   ` Borislav Petkov
2017-06-28  8:44     ` Borislav Petkov
2017-07-03  8:42       ` Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.