All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] tpm_tis: fix interrupts (again)
@ 2020-10-01 18:09 James Bottomley
  2020-10-01 18:09 ` [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition James Bottomley
                   ` (6 more replies)
  0 siblings, 7 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-01 18:09 UTC (permalink / raw)
  To: linux-integrity
  Cc: Jason Gunthorpe, Jerry Snitselaar, Jarkko Sakkinen, Peter Huewe

The current state of the TIS TPM is that interrupts have been globally
disabled by various changes.  The problems we got reported the last
time they were enabled was interrupt storms.  With my own TIS TPM,
I've found that this is caused because my TPM doesn't do legacy
cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
requires any TIS TPM without legacy cycles not to act on any write to
an interrupt register unless the locality is enabled.  This means if
an interrupt fires after we relinquish the locality, the TPM_EOI in
the interrupt routine is ineffective meaning the same interrupt
triggers over and over again.  This problem also means we can have
trouble setting up interrupts on TIS TPMs because the current init
code does the setup before the locality is claimed for the first time.

James

---

James Bottomley (5):
  tpm_tis: Fix check_locality for correct locality acquisition
  tpm_tis: Clean up locality release
  tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  tpm_tis: fix IRQ probing
  Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing
    IRQ's""

 drivers/char/tpm/tpm_tis_core.c | 185 ++++++++++++++++++++------------
 1 file changed, 117 insertions(+), 68 deletions(-)

-- 
2.28.0


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

* [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition
  2020-10-01 18:09 [PATCH v2 0/5] tpm_tis: fix interrupts (again) James Bottomley
@ 2020-10-01 18:09 ` James Bottomley
  2020-10-05 15:34   ` Jarkko Sakkinen
  2020-10-19 23:16   ` Jerry Snitselaar
  2020-10-01 18:09 ` [PATCH v2 2/5] tpm_tis: Clean up locality release James Bottomley
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-01 18:09 UTC (permalink / raw)
  To: linux-integrity
  Cc: Jason Gunthorpe, Jerry Snitselaar, Jarkko Sakkinen, Peter Huewe

The TPM TIS specification says the TPM signals the acquisition of
locality when the TMP_ACCESS_REQUEST_USE bit goes to one *and* the
TPM_ACCESS_REQUEST_USE bit goes to zero.  Currently we only check the
former not the latter, so check both.  Adding the check on
TPM_ACCESS_REQUEST_USE should fix the case where the locality is
re-requested before the TPM has released it.  In this case the
locality may get released briefly before it is reacquired, which
causes all sorts of problems. However, with the added check,
TPM_ACCESS_REQUEST_USE should remain 1 until the second request for
the locality is granted.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

---

v2: added this patch
---
 drivers/char/tpm/tpm_tis_core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 92c51c6cfd1b..f3ecde8df47d 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -125,7 +125,8 @@ static bool check_locality(struct tpm_chip *chip, int l)
 	if (rc < 0)
 		return false;
 
-	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
+	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID
+		       | TPM_ACCESS_REQUEST_USE)) ==
 	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
 		priv->locality = l;
 		return true;
-- 
2.28.0


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

* [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-01 18:09 [PATCH v2 0/5] tpm_tis: fix interrupts (again) James Bottomley
  2020-10-01 18:09 ` [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition James Bottomley
@ 2020-10-01 18:09 ` James Bottomley
  2020-10-05 17:02   ` Jarkko Sakkinen
                     ` (2 more replies)
  2020-10-01 18:09 ` [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles James Bottomley
                   ` (4 subsequent siblings)
  6 siblings, 3 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-01 18:09 UTC (permalink / raw)
  To: linux-integrity
  Cc: Jason Gunthorpe, Jerry Snitselaar, Jarkko Sakkinen, Peter Huewe

The current release locality code seems to be based on the
misunderstanding that the TPM interrupts when a locality is released:
it doesn't, only when the locality is acquired.

Furthermore, there seems to be no point in waiting for the locality to
be released.  All it does is penalize the last TPM user.  However, if
there's no next TPM user, this is a pointless wait and if there is a
next TPM user, they'll pay the penalty waiting for the new locality
(or possibly not if it's the same as the old locality).

Fix the code by making release_locality as simple write to release
with no waiting for completion.

Fixes: 33bafe90824b ("tpm_tis: verify locality released before returning from release_locality")
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

---

v2: added fixes
---
 drivers/char/tpm/tpm_tis_core.c | 47 +--------------------------------
 1 file changed, 1 insertion(+), 46 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index f3ecde8df47d..431919d5f48a 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -135,58 +135,13 @@ static bool check_locality(struct tpm_chip *chip, int l)
 	return false;
 }
 
-static bool locality_inactive(struct tpm_chip *chip, int l)
-{
-	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
-	int rc;
-	u8 access;
-
-	rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
-	if (rc < 0)
-		return false;
-
-	if ((access & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
-	    == TPM_ACCESS_VALID)
-		return true;
-
-	return false;
-}
-
 static int release_locality(struct tpm_chip *chip, int l)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
-	unsigned long stop, timeout;
-	long rc;
 
 	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
 
-	stop = jiffies + chip->timeout_a;
-
-	if (chip->flags & TPM_CHIP_FLAG_IRQ) {
-again:
-		timeout = stop - jiffies;
-		if ((long)timeout <= 0)
-			return -1;
-
-		rc = wait_event_interruptible_timeout(priv->int_queue,
-						      (locality_inactive(chip, l)),
-						      timeout);
-
-		if (rc > 0)
-			return 0;
-
-		if (rc == -ERESTARTSYS && freezing(current)) {
-			clear_thread_flag(TIF_SIGPENDING);
-			goto again;
-		}
-	} else {
-		do {
-			if (locality_inactive(chip, l))
-				return 0;
-			tpm_msleep(TPM_TIMEOUT);
-		} while (time_before(jiffies, stop));
-	}
-	return -1;
+	return 0;
 }
 
 static int request_locality(struct tpm_chip *chip, int l)
-- 
2.28.0


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

* [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-10-01 18:09 [PATCH v2 0/5] tpm_tis: fix interrupts (again) James Bottomley
  2020-10-01 18:09 ` [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition James Bottomley
  2020-10-01 18:09 ` [PATCH v2 2/5] tpm_tis: Clean up locality release James Bottomley
@ 2020-10-01 18:09 ` James Bottomley
  2020-10-05 17:05   ` Jarkko Sakkinen
                     ` (2 more replies)
  2020-10-01 18:09 ` [PATCH v2 4/5] tpm_tis: fix IRQ probing James Bottomley
                   ` (3 subsequent siblings)
  6 siblings, 3 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-01 18:09 UTC (permalink / raw)
  To: linux-integrity
  Cc: Jason Gunthorpe, Jerry Snitselaar, Jarkko Sakkinen, Peter Huewe

If a TIS TPM doesn't have legacy cycles, any write to the interrupt
registers is ignored unless a locality is active.  This means even to
set up the interrupt vectors a locality must first be activated.  Fix
this by activating the 0 locality in the interrupt probe setup.

Since the TPM_EOI signalling also requires an active locality, the
interrupt routine cannot end an interrupt if the locality is released.
This can lead to a situation where the TPM goes command ready after
locality release and since the interrupt cannot be ended it refires
continuously.  Fix this by disabling all interrupts except locality
change when a locality is released (this only fires when a locality
becomes active, meaning the TPM_EOI should work).

Finally, since we now disable all status based interrupts in the
locality release, they must be re-enabled before waiting to check the
condition, so add interrupt enabling to the status wait.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

---

v2: renamed functions
---
 drivers/char/tpm/tpm_tis_core.c | 125 ++++++++++++++++++++++++++------
 1 file changed, 101 insertions(+), 24 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 431919d5f48a..0c07da8cd680 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -29,6 +29,46 @@
 
 static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
 
+static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8 mask)
+{
+	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+	u32 intmask;
+
+	/* Take control of the TPM's interrupt hardware and shut it off */
+	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
+
+	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
+
+	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
+}
+
+static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8 mask)
+{
+	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+	u32 intmask;
+
+	/* Take control of the TPM's interrupt hardware and shut it off */
+	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
+
+	intmask &= ~mask;
+
+	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
+}
+
+static void tpm_tis_enable_stat_interrupts(struct tpm_chip *chip, u8 stat)
+{
+	u32 mask = 0;
+
+	if (stat & TPM_STS_COMMAND_READY)
+		mask |= TPM_INTF_CMD_READY_INT;
+	if (stat & TPM_STS_VALID)
+		mask |= TPM_INTF_STS_VALID_INT;
+	if (stat & TPM_STS_DATA_AVAIL)
+		mask |= TPM_INTF_DATA_AVAIL_INT;
+
+	tpm_tis_enable_interrupt(chip, mask);
+}
+
 static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
 					bool check_cancel, bool *canceled)
 {
@@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
 		timeout = stop - jiffies;
 		if ((long)timeout <= 0)
 			return -ETIME;
+		tpm_tis_enable_stat_interrupts(chip, mask);
 		rc = wait_event_interruptible_timeout(*queue,
 			wait_for_tpm_stat_cond(chip, mask, check_cancel,
 					       &canceled),
 			timeout);
 		if (rc > 0) {
+			if (rc == 1)
+				dev_err(&chip->dev, "Lost Interrupt waiting for TPM stat\n");
 			if (canceled)
 				return -ECANCELED;
 			return 0;
@@ -138,6 +181,28 @@ static bool check_locality(struct tpm_chip *chip, int l)
 static int release_locality(struct tpm_chip *chip, int l)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+	u32 int_status;
+	int rc;
+
+	/*
+	 * Note that once we relinquish the locality, all writes to
+	 * the interrupt registers become ineffective meaning we can't
+	 * do a TPM_EOI.  This means we must disable every interrupt
+	 * except the locality change one to avoid interrupt
+	 * storms.
+	 */
+	tpm_tis_disable_interrupt(chip, TPM_INTF_CMD_READY_INT
+				  | TPM_INTF_STS_VALID_INT
+				  | TPM_INTF_DATA_AVAIL_INT);
+
+	rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
+	if (rc < 0)
+		return rc;
+
+	/* Clear all pending */
+	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
+	if (rc < 0)
+		return rc;
 
 	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
 
@@ -164,12 +229,17 @@ static int request_locality(struct tpm_chip *chip, int l)
 		timeout = stop - jiffies;
 		if ((long)timeout <= 0)
 			return -1;
+
 		rc = wait_event_interruptible_timeout(priv->int_queue,
 						      (check_locality
 						       (chip, l)),
 						      timeout);
-		if (rc > 0)
+		if (rc > 1)
+			return l;
+		if (rc == 1) {
+			dev_info(&chip->dev, "Lost Interrupt waiting for locality\n");
 			return l;
+		}
 		if (rc == -ERESTARTSYS && freezing(current)) {
 			clear_thread_flag(TIF_SIGPENDING);
 			goto again;
@@ -465,6 +535,10 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	irq = priv->irq;
 	priv->irq = 0;
 	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
+	tpm_tis_enable_interrupt(chip, TPM_INTF_CMD_READY_INT
+				 | TPM_INTF_LOCALITY_CHANGE_INT
+				 | TPM_INTF_DATA_AVAIL_INT
+				 | TPM_INTF_STS_VALID_INT);
 	rc = tpm_tis_send_main(chip, buf, len);
 	priv->irq = irq;
 	chip->flags |= TPM_CHIP_FLAG_IRQ;
@@ -719,7 +793,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
  * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
  * everything and leave in polling mode. Returns 0 on success.
  */
-static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
+static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
 				    int flags, int irq)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
@@ -753,9 +827,11 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
 	if (rc < 0)
 		return rc;
 
-	/* Turn on */
-	rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
-			     intmask | TPM_GLOBAL_INT_ENABLE);
+	/*
+	 * Turn on.  The locality change interrupt is the only one
+	 * always enabled
+	 */
+	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
 	if (rc < 0)
 		return rc;
 
@@ -787,7 +863,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
  * do not have ACPI/etc. We typically expect the interrupt to be declared if
  * present.
  */
-static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
+static void tpm_tis_probe_irq(struct tpm_chip *chip)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 	u8 original_int_vec;
@@ -801,11 +877,9 @@ static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
 	if (!original_int_vec) {
 		if (IS_ENABLED(CONFIG_X86))
 			for (i = 3; i <= 15; i++)
-				if (!tpm_tis_probe_irq_single(chip, intmask, 0,
-							      i))
+				if (!tpm_tis_probe_irq_single(chip, 0, i))
 					return;
-	} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
-					     original_int_vec))
+	} else if (!tpm_tis_probe_irq_single(chip, 0, original_int_vec))
 		return;
 }
 
@@ -1030,8 +1104,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 		}
 
 		if (irq) {
-			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
-						 irq);
+			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
 			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
 				dev_err(&chip->dev, FW_BUG
 					"TPM interrupt not working, polling instead\n");
@@ -1039,7 +1112,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 				disable_interrupts(chip);
 			}
 		} else {
-			tpm_tis_probe_irq(chip, intmask);
+			tpm_tis_probe_irq(chip);
 		}
 	}
 
@@ -1065,12 +1138,23 @@ EXPORT_SYMBOL_GPL(tpm_tis_core_init);
 static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
-	u32 intmask;
 	int rc;
 
 	if (chip->ops->clk_enable != NULL)
 		chip->ops->clk_enable(chip, true);
 
+	/*
+	 * must have the locality before we can enable interrupts, so
+	 * poll for the locality being ready
+	 */
+	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
+	if (request_locality(chip, 0) != 0) {
+		dev_err(&chip->dev, "Failed to enable interrupts after suspend\n");
+		goto out;
+	}
+	chip->flags |= TPM_CHIP_FLAG_IRQ;
+
+
 	/* reenable interrupts that device may have lost or
 	 * BIOS/firmware may have disabled
 	 */
@@ -1078,17 +1162,10 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
 	if (rc < 0)
 		goto out;
 
-	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
-	if (rc < 0)
-		goto out;
-
-	intmask |= TPM_INTF_CMD_READY_INT
-	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
-	    | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
+	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
 
-	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
-
-out:
+ out:
+	release_locality(chip, 0);
 	if (chip->ops->clk_enable != NULL)
 		chip->ops->clk_enable(chip, false);
 
-- 
2.28.0


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

* [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-01 18:09 [PATCH v2 0/5] tpm_tis: fix interrupts (again) James Bottomley
                   ` (2 preceding siblings ...)
  2020-10-01 18:09 ` [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles James Bottomley
@ 2020-10-01 18:09 ` James Bottomley
  2020-10-05 17:05   ` Jarkko Sakkinen
  2020-10-19 23:41   ` Jerry Snitselaar
  2020-10-01 18:09 ` [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's"" James Bottomley
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-01 18:09 UTC (permalink / raw)
  To: linux-integrity
  Cc: Jason Gunthorpe, Jerry Snitselaar, Jarkko Sakkinen, Peter Huewe

There are two problems with our current interrupt probing: firstly the
TPM_CHIP_FLAG_IRQ never gets set initially, so a check for interrupts
is never done.  Fix this by setting the flag before we generate and
interrupt for probing.  Secondly our IRQ setup may be ineffective on a
TPM without legacy access cycles becuase according to the TPM
Interface Specification the interrupt registers are only writeable in
the current locality, so issue a request_locality before setting up
the interrupts.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

---

v2: improved description
---
 drivers/char/tpm/tpm_tis_core.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 0c07da8cd680..12b657ed3a39 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -809,6 +809,19 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
 	}
 	priv->irq = irq;
 
+	/*
+	 * note writes to the interrupt registers are only effective
+	 * when the TPM is in the active locality, so we have to
+	 * request the locality here to get the interrupt set up.
+	 * This request has no corresponding release, because the
+	 * locality will be relinquished at the end of the tpm command
+	 * that probes the interrupts
+	 */
+	if (request_locality(chip, 0) != 0) {
+		dev_err(&chip->dev, "failed to gain locality for irq probe\n");
+		return -EBUSY;
+	}
+
 	rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
 			   &original_int_vec);
 	if (rc < 0)
@@ -836,6 +849,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
 		return rc;
 
 	priv->irq_tested = false;
+	chip->flags |= TPM_CHIP_FLAG_IRQ;
 
 	/* Generate an interrupt by having the core call through to
 	 * tpm_tis_send
-- 
2.28.0


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

* [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's""
  2020-10-01 18:09 [PATCH v2 0/5] tpm_tis: fix interrupts (again) James Bottomley
                   ` (3 preceding siblings ...)
  2020-10-01 18:09 ` [PATCH v2 4/5] tpm_tis: fix IRQ probing James Bottomley
@ 2020-10-01 18:09 ` James Bottomley
  2020-10-19 20:23   ` Jerry Snitselaar
  2020-10-19 23:40   ` Jerry Snitselaar
  2020-10-12  5:39 ` [PATCH v2 0/5] tpm_tis: fix interrupts (again) Jerry Snitselaar
  2020-10-13  1:17 ` Jarkko Sakkinen
  6 siblings, 2 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-01 18:09 UTC (permalink / raw)
  To: linux-integrity
  Cc: Jason Gunthorpe, Jerry Snitselaar, Jarkko Sakkinen, Peter Huewe

Revert the patch aa4a63dd9816 which stops interrupt probing from
working, now that it should be safe to allow interrupt probing on all
systems without incurring interrupt storms.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
 drivers/char/tpm/tpm_tis_core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 12b657ed3a39..23b60583928b 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -1117,6 +1117,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 			goto out_err;
 		}
 
+		tpm_chip_start(chip);
 		if (irq) {
 			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
 			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
@@ -1128,6 +1129,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 		} else {
 			tpm_tis_probe_irq(chip);
 		}
+		tpm_chip_stop(chip);
 	}
 
 	rc = tpm_chip_register(chip);
-- 
2.28.0


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

* Re: [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition
  2020-10-01 18:09 ` [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition James Bottomley
@ 2020-10-05 15:34   ` Jarkko Sakkinen
  2020-10-05 19:00     ` James Bottomley
  2020-10-19 23:16   ` Jerry Snitselaar
  1 sibling, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-05 15:34 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Thu, Oct 01, 2020 at 11:09:21AM -0700, James Bottomley wrote:
> The TPM TIS specification says the TPM signals the acquisition of
> locality when the TMP_ACCESS_REQUEST_USE bit goes to one *and* the
> TPM_ACCESS_REQUEST_USE bit goes to zero.  Currently we only check the

Put a reference to the section.

I'm *guessing* that the spec is

https://trustedcomputinggroup.org/resource/pc-client-work-group-pc-client-specific-tpm-interface-specification-tis

Please have this and also location in this spec.

> former not the latter, so check both.  Adding the check on
> TPM_ACCESS_REQUEST_USE should fix the case where the locality is
> re-requested before the TPM has released it.  In this case the
> locality may get released briefly before it is reacquired, which
> causes all sorts of problems. However, with the added check,
> TPM_ACCESS_REQUEST_USE should remain 1 until the second request for
> the locality is granted.

The description is really good and understandable otherwise.

For me it is not obvious at all, why this is missing a fixes
tag?

> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> ---
> 
> v2: added this patch

Use the cover letter for the changelog. I'm afraid that I might
miss these otherwise.

> ---
>  drivers/char/tpm/tpm_tis_core.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 92c51c6cfd1b..f3ecde8df47d 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -125,7 +125,8 @@ static bool check_locality(struct tpm_chip *chip, int l)
>  	if (rc < 0)
>  		return false;
>  
> -	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
> +	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID
> +		       | TPM_ACCESS_REQUEST_USE)) ==
>  	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
>  		priv->locality = l;
>  		return true;
> -- 
> 2.28.0
> 

/Jarkko

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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-01 18:09 ` [PATCH v2 2/5] tpm_tis: Clean up locality release James Bottomley
@ 2020-10-05 17:02   ` Jarkko Sakkinen
  2020-10-05 19:05     ` James Bottomley
  2020-10-05 17:03   ` Jarkko Sakkinen
  2020-10-19 23:17   ` Jerry Snitselaar
  2 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-05 17:02 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Thu, Oct 01, 2020 at 11:09:22AM -0700, James Bottomley wrote:
> The current release locality code seems to be based on the
> misunderstanding that the TPM interrupts when a locality is released:
> it doesn't, only when the locality is acquired.
> 
> Furthermore, there seems to be no point in waiting for the locality to
> be released.  All it does is penalize the last TPM user.  However, if
> there's no next TPM user, this is a pointless wait and if there is a
> next TPM user, they'll pay the penalty waiting for the new locality
> (or possibly not if it's the same as the old locality).
> 
> Fix the code by making release_locality as simple write to release
> with no waiting for completion.
> 
> Fixes: 33bafe90824b ("tpm_tis: verify locality released before returning from release_locality")
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

So, if I got it right this is dependent on 1/5 to address Jerry's
issue? I.e. if this has a fixes tag and previous does not, it will
not fully fix the situation when backporting?

/Jarkko

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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-01 18:09 ` [PATCH v2 2/5] tpm_tis: Clean up locality release James Bottomley
  2020-10-05 17:02   ` Jarkko Sakkinen
@ 2020-10-05 17:03   ` Jarkko Sakkinen
  2020-10-19 23:17   ` Jerry Snitselaar
  2 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-05 17:03 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Thu, Oct 01, 2020 at 11:09:22AM -0700, James Bottomley wrote:
> The current release locality code seems to be based on the
> misunderstanding that the TPM interrupts when a locality is released:
> it doesn't, only when the locality is acquired.
> 
> Furthermore, there seems to be no point in waiting for the locality to
> be released.  All it does is penalize the last TPM user.  However, if
> there's no next TPM user, this is a pointless wait and if there is a
> next TPM user, they'll pay the penalty waiting for the new locality
> (or possibly not if it's the same as the old locality).
> 
> Fix the code by making release_locality as simple write to release
> with no waiting for completion.
> 
> Fixes: 33bafe90824b ("tpm_tis: verify locality released before returning from release_locality")
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> ---
> 
> v2: added fixes

Also, this should go to cover letter (with some detail on the fixes).

/Jarkko

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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-10-01 18:09 ` [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles James Bottomley
@ 2020-10-05 17:05   ` Jarkko Sakkinen
  2020-10-20  0:14   ` Jerry Snitselaar
  2020-12-01 18:12   ` Jerry Snitselaar
  2 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-05 17:05 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Thu, Oct 01, 2020 at 11:09:23AM -0700, James Bottomley wrote:
> If a TIS TPM doesn't have legacy cycles, any write to the interrupt
> registers is ignored unless a locality is active.  This means even to
> set up the interrupt vectors a locality must first be activated.  Fix
> this by activating the 0 locality in the interrupt probe setup.
> 
> Since the TPM_EOI signalling also requires an active locality, the
> interrupt routine cannot end an interrupt if the locality is released.
> This can lead to a situation where the TPM goes command ready after
> locality release and since the interrupt cannot be ended it refires
> continuously.  Fix this by disabling all interrupts except locality
> change when a locality is released (this only fires when a locality
> becomes active, meaning the TPM_EOI should work).
> 
> Finally, since we now disable all status based interrupts in the
> locality release, they must be re-enabled before waiting to check the
> condition, so add interrupt enabling to the status wait.
> 
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> ---
> 
> v2: renamed functions

Ditto.

/Jarkko

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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-01 18:09 ` [PATCH v2 4/5] tpm_tis: fix IRQ probing James Bottomley
@ 2020-10-05 17:05   ` Jarkko Sakkinen
  2020-10-19 23:41   ` Jerry Snitselaar
  1 sibling, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-05 17:05 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Thu, Oct 01, 2020 at 11:09:24AM -0700, James Bottomley wrote:
> There are two problems with our current interrupt probing: firstly the
> TPM_CHIP_FLAG_IRQ never gets set initially, so a check for interrupts
> is never done.  Fix this by setting the flag before we generate and
> interrupt for probing.  Secondly our IRQ setup may be ineffective on a
> TPM without legacy access cycles becuase according to the TPM
> Interface Specification the interrupt registers are only writeable in
> the current locality, so issue a request_locality before setting up
> the interrupts.
> 
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> ---
> 
> v2: improved description

Ditto.

/Jarkko

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

* Re: [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition
  2020-10-05 15:34   ` Jarkko Sakkinen
@ 2020-10-05 19:00     ` James Bottomley
  2020-10-05 20:32       ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-10-05 19:00 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Mon, 2020-10-05 at 18:34 +0300, Jarkko Sakkinen wrote:
> On Thu, Oct 01, 2020 at 11:09:21AM -0700, James Bottomley wrote:
> > The TPM TIS specification says the TPM signals the acquisition of
> > locality when the TMP_ACCESS_REQUEST_USE bit goes to one *and* the
> > TPM_ACCESS_REQUEST_USE bit goes to zero.  Currently we only check
> > the
> 
> Put a reference to the section.
> 
> I'm *guessing* that the spec is
> 
> https://trustedcomputinggroup.org/resource/pc-client-work-group-pc-client-specific-tpm-interface-specification-tis
> 
> Please have this and also location in this spec.

I can, but the TCG reorganizes its website every few months, so no URLs
like that are permanent.

> > former not the latter, so check both.  Adding the check on
> > TPM_ACCESS_REQUEST_USE should fix the case where the locality is
> > re-requested before the TPM has released it.  In this case the
> > locality may get released briefly before it is reacquired, which
> > causes all sorts of problems. However, with the added check,
> > TPM_ACCESS_REQUEST_USE should remain 1 until the second request for
> > the locality is granted.
> 
> The description is really good and understandable otherwise.
> 
> For me it is not obvious at all, why this is missing a fixes
> tag?

It's been there ever since the initial commit:

commit 27084efee0c3dc0eb15b5ed750aa9f1adb3983c3
Author: Leendert van Doorn <leendert@watson.ibm.com>
Date:   Sat Apr 22 02:38:03 2006 -0700

    [PATCH] tpm: driver for next generation TPM chips

> > Signed-off-by: James Bottomley <
> > James.Bottomley@HansenPartnership.com>
> > 
> > ---
> > 
> > v2: added this patch
> 
> Use the cover letter for the changelog. I'm afraid that I might
> miss these otherwise.

Submitting patches actually recommends doing this ... I think we want
to keep to standard kernel process, but I can gather them in the cover
letter as well.

James



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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-05 17:02   ` Jarkko Sakkinen
@ 2020-10-05 19:05     ` James Bottomley
  2020-10-05 20:34       ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-10-05 19:05 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Mon, 2020-10-05 at 20:02 +0300, Jarkko Sakkinen wrote:
> On Thu, Oct 01, 2020 at 11:09:22AM -0700, James Bottomley wrote:
> > The current release locality code seems to be based on the
> > misunderstanding that the TPM interrupts when a locality is
> > released: it doesn't, only when the locality is acquired.
> > 
> > Furthermore, there seems to be no point in waiting for the locality
> > to be released.  All it does is penalize the last TPM
> > user.  However, if there's no next TPM user, this is a pointless
> > wait and if there is a next TPM user, they'll pay the penalty
> > waiting for the new locality (or possibly not if it's the same as
> > the old locality).
> > 
> > Fix the code by making release_locality as simple write to release
> > with no waiting for completion.
> > 
> > Fixes: 33bafe90824b ("tpm_tis: verify locality released before
> > returning from release_locality")
> > Signed-off-by: James Bottomley <
> > James.Bottomley@HansenPartnership.com>
> 
> So, if I got it right this is dependent on 1/5 to address Jerry's
> issue? I.e. if this has a fixes tag and previous does not, it will
> not fully fix the situation when backporting?

Yes, exactly.  Technically 1/5 isn't really fixing anything at all,
it's changing from the current fix where we wait for the locality to be
released at the back end of a TIS TPM operation to a new fix where we
correctly check the conditions in the locality acquisition.  After the
new fix is done, we can eliminate all the wait code in locality
release.

James



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

* Re: [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition
  2020-10-05 19:00     ` James Bottomley
@ 2020-10-05 20:32       ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-05 20:32 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Mon, Oct 05, 2020 at 12:00:57PM -0700, James Bottomley wrote:
> On Mon, 2020-10-05 at 18:34 +0300, Jarkko Sakkinen wrote:
> > On Thu, Oct 01, 2020 at 11:09:21AM -0700, James Bottomley wrote:
> > > The TPM TIS specification says the TPM signals the acquisition of
> > > locality when the TMP_ACCESS_REQUEST_USE bit goes to one *and* the
> > > TPM_ACCESS_REQUEST_USE bit goes to zero.  Currently we only check
> > > the
> > 
> > Put a reference to the section.
> > 
> > I'm *guessing* that the spec is
> > 
> > https://trustedcomputinggroup.org/resource/pc-client-work-group-pc-client-specific-tpm-interface-specification-tis
> > 
> > Please have this and also location in this spec.
> 
> I can, but the TCG reorganizes its website every few months, so no URLs
> like that are permanent.

OK, that's good enough excuse :-( Let's then ignore this comment.
Just would had save trouble in future if that wasn't the case.

> > > former not the latter, so check both.  Adding the check on
> > > TPM_ACCESS_REQUEST_USE should fix the case where the locality is
> > > re-requested before the TPM has released it.  In this case the
> > > locality may get released briefly before it is reacquired, which
> > > causes all sorts of problems. However, with the added check,
> > > TPM_ACCESS_REQUEST_USE should remain 1 until the second request for
> > > the locality is granted.
> > 
> > The description is really good and understandable otherwise.
> > 
> > For me it is not obvious at all, why this is missing a fixes
> > tag?
> 
> It's been there ever since the initial commit:
> 
> commit 27084efee0c3dc0eb15b5ed750aa9f1adb3983c3
> Author: Leendert van Doorn <leendert@watson.ibm.com>
> Date:   Sat Apr 22 02:38:03 2006 -0700
> 
>     [PATCH] tpm: driver for next generation TPM chips

Then just "Cc: stable@vger.kernel.org" should do.

> > > Signed-off-by: James Bottomley <
> > > James.Bottomley@HansenPartnership.com>
> > > 
> > > ---
> > > 
> > > v2: added this patch
> > 
> > Use the cover letter for the changelog. I'm afraid that I might
> > miss these otherwise.
> 
> Submitting patches actually recommends doing this ... I think we want
> to keep to standard kernel process, but I can gather them in the cover
> letter as well.

Most of the patch sets that I encounter have the cover letter in the
changelog and usually it is great for getting overall image what is
happening.

In section 14 of "submitting patches" there is a remark that the area
just after the diffstat marker is a good place to store this kind of
information. I have not find any explicit instruction for patch sets,
i.e. I just trust the "majority vote".

> James

/Jarkko

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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-05 19:05     ` James Bottomley
@ 2020-10-05 20:34       ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-05 20:34 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe

On Mon, Oct 05, 2020 at 12:05:07PM -0700, James Bottomley wrote:
> On Mon, 2020-10-05 at 20:02 +0300, Jarkko Sakkinen wrote:
> > On Thu, Oct 01, 2020 at 11:09:22AM -0700, James Bottomley wrote:
> > > The current release locality code seems to be based on the
> > > misunderstanding that the TPM interrupts when a locality is
> > > released: it doesn't, only when the locality is acquired.
> > > 
> > > Furthermore, there seems to be no point in waiting for the locality
> > > to be released.  All it does is penalize the last TPM
> > > user.  However, if there's no next TPM user, this is a pointless
> > > wait and if there is a next TPM user, they'll pay the penalty
> > > waiting for the new locality (or possibly not if it's the same as
> > > the old locality).
> > > 
> > > Fix the code by making release_locality as simple write to release
> > > with no waiting for completion.
> > > 
> > > Fixes: 33bafe90824b ("tpm_tis: verify locality released before
> > > returning from release_locality")
> > > Signed-off-by: James Bottomley <
> > > James.Bottomley@HansenPartnership.com>
> > 
> > So, if I got it right this is dependent on 1/5 to address Jerry's
> > issue? I.e. if this has a fixes tag and previous does not, it will
> > not fully fix the situation when backporting?
> 
> Yes, exactly.  Technically 1/5 isn't really fixing anything at all,
> it's changing from the current fix where we wait for the locality to be
> released at the back end of a TIS TPM operation to a new fix where we
> correctly check the conditions in the locality acquisition.  After the
> new fix is done, we can eliminate all the wait code in locality
> release.
> 
> James

OK, ignore my changelog etc. cosmectic comments unless there is need
for another revision. I will add the necessary tags.

I'm holding with reviewed-by up until Jerry can get ack for these
changes. If he ack's, the it's all good as far as I'm concerned.

/Jarkko

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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-01 18:09 [PATCH v2 0/5] tpm_tis: fix interrupts (again) James Bottomley
                   ` (4 preceding siblings ...)
  2020-10-01 18:09 ` [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's"" James Bottomley
@ 2020-10-12  5:39 ` Jerry Snitselaar
  2020-10-13  1:23   ` Jarkko Sakkinen
  2020-10-13  1:17 ` Jarkko Sakkinen
  6 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-12  5:39 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-01 11:09 MST:

> The current state of the TIS TPM is that interrupts have been globally
> disabled by various changes.  The problems we got reported the last
> time they were enabled was interrupt storms.  With my own TIS TPM,
> I've found that this is caused because my TPM doesn't do legacy
> cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
> requires any TIS TPM without legacy cycles not to act on any write to
> an interrupt register unless the locality is enabled.  This means if
> an interrupt fires after we relinquish the locality, the TPM_EOI in
> the interrupt routine is ineffective meaning the same interrupt
> triggers over and over again.  This problem also means we can have
> trouble setting up interrupts on TIS TPMs because the current init
> code does the setup before the locality is claimed for the first time.
>
> James
>


I tested initially with the following commits reverted:

aa4a63dd9816 tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's" | 2020-01-06 | (Stefan Berger)
dda8b2af395b tpm: Revert "tpm_tis_core: Set TPM_CHIP_FLAG_IRQ before probing for interrupts" | 2020-01-06 | (Stefan Berger)

The laptop doesn't become unusable, but I lose the trackpad and get the following:

[    3.070501] irq 31: nobody cared (try booting with the "irqpoll" option)
[    3.070504] CPU: 2 PID: 251 Comm: rngd Not tainted 5.8.13-201.local.fc32.x86_64 #1
[    3.070504] Hardware name: LENOVO 20NYS7K90F/20NYS7K90F, BIOS N2JET83W (1.61 ) 11/22/2019
[    3.070505] Call Trace:
[    3.070511]  dump_stack+0x6b/0x88
[    3.070514]  __report_bad_irq+0x35/0xa7
[    3.070516]  note_interrupt.cold+0xb/0x6a
[    3.070518]  handle_irq_event+0x88/0x8a
[    3.070519]  handle_fasteoi_irq+0x78/0x1c0
[    3.070522]  common_interrupt+0x68/0x140
[    3.070524]  ? asm_common_interrupt+0x8/0x40
[    3.070525]  asm_common_interrupt+0x1e/0x40
[    3.070527] RIP: 0033:0x7f2eea3249b5
[    3.070529] Code: e0 48 c1 e8 3c 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 37 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 1e 83 e0 01 48 31 45 f0 <48> 8b 45 e0 48 c1 e8 1b 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8
[    3.070529] RSP: 002b:00007f2ee3ffebc0 EFLAGS: 00000202
[    3.070530] RAX: 0000000000000001 RBX: 000000000000000a RCX: 000000000000002e
[    3.070531] RDX: 0463400000000000 RSI: 0000000000000000 RDI: 0000000000000001
[    3.070532] RBP: 00007f2ee3ffec10 R08: 0000000000000000 R09: 0000000000000035
[    3.070532] R10: 00007ffde716f080 R11: 00007ffde716f080 R12: 00007f2edc004c00
[    3.070533] R13: 00007ffde700a54f R14: 00007f2ee3ffed10 R15: 00005598a41e3680
[    3.070534] handlers:
[    3.070537] [<000000007b6f3232>] tis_int_handler
[    3.070538] Disabling IRQ #31
...
[   14.956342] irq 16: nobody cared (try booting with the "irqpoll" option)
[   14.956344] CPU: 0 PID: 1013 Comm: rngd Not tainted 5.8.13-201.local.fc32.x86_64 #1
[   14.956344] Hardware name: LENOVO 20NYS7K90F/20NYS7K90F, BIOS N2JET83W (1.61 ) 11/22/2019
[   14.956345] Call Trace:
[   14.956350]  dump_stack+0x6b/0x88
[   14.956353]  __report_bad_irq+0x35/0xa7
[   14.956354]  note_interrupt.cold+0xb/0x6a
[   14.956355]  handle_irq_event+0x88/0x8a
[   14.956356]  handle_fasteoi_irq+0x78/0x1c0
[   14.956358]  common_interrupt+0x68/0x140
[   14.956360]  ? asm_common_interrupt+0x8/0x40
[   14.956361]  asm_common_interrupt+0x1e/0x40
[   14.956362] RIP: 0033:0x7fcaff4399d3
[   14.956363] Code: e0 48 c1 e8 1e 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 1b 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 16 83 e0 01 48 31 45 f0 <48> d1 65 e0 48 8b 45 f0 48 31 45 e0 83 45 d4 01 83 7d d4 40 0f 86
[   14.956364] RSP: 002b:00007fcafe544bc0 EFLAGS: 00000246
[   14.956364] RAX: 0000000000000000 RBX: 000000000000000a RCX: 0000000000000026
[   14.956365] RDX: 000df20000000000 RSI: 0000000000000000 RDI: 0000000000000001
[   14.956365] RBP: 00007fcafe544c10 R08: 0000000000000000 R09: 0000000000000035
[   14.956366] R10: 00007ffc30bd2080 R11: 00007ffc30bd2080 R12: 00007fcaf0004c00
[   14.956366] R13: 00007fcaf0004c00 R14: 00007fcaf0000b60 R15: 0000560216fcf0f2
[   14.956367] handlers:
[   14.956370] [<0000000024c0571e>] i801_isr [i2c_i801]
[   14.956371] Disabling IRQ #16

/proc/interrupts shows:

  16:     100000          0          0          0          0          0          0          0  IR-IO-APIC   16-fasteoi   i801_smbus
  31:          0          0     100000          0          0          0          0          0  IR-IO-APIC   31-fasteoi   tpm0


I also get this behavior with your patchset applied. If I boot with
tpm_tis.interrupts=0 it behaves.  The thought from Hans is to look at
the dmi info and key off the vendor being Lenovo and bios date to
decide if interrupts should be disabled. Since Dan ran also into this
with something internal at Intel I don't know if that will be
sufficient.

I hope to look over this patchset tomorrow.

Regards,
Jerry


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-01 18:09 [PATCH v2 0/5] tpm_tis: fix interrupts (again) James Bottomley
                   ` (5 preceding siblings ...)
  2020-10-12  5:39 ` [PATCH v2 0/5] tpm_tis: fix interrupts (again) Jerry Snitselaar
@ 2020-10-13  1:17 ` Jarkko Sakkinen
  2020-10-13 15:15   ` Jerry Snitselaar
  6 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-13  1:17 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jerry Snitselaar, Peter Huewe,
	Borislav Petkov, Nayna Jain

On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
> The current state of the TIS TPM is that interrupts have been globally
> disabled by various changes.  The problems we got reported the last
> time they were enabled was interrupt storms.  With my own TIS TPM,
> I've found that this is caused because my TPM doesn't do legacy
> cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
> requires any TIS TPM without legacy cycles not to act on any write to
> an interrupt register unless the locality is enabled.  This means if
> an interrupt fires after we relinquish the locality, the TPM_EOI in
> the interrupt routine is ineffective meaning the same interrupt
> triggers over and over again.  This problem also means we can have
> trouble setting up interrupts on TIS TPMs because the current init
> code does the setup before the locality is claimed for the first time.
> 
> James

You should consider expanding the audience. Jerry, once you have some
bandwidth (no rush, does not land before rc2), it would be great that if
you could try this. I'm emphasizing this just because of the
intersection. I think it would also make senset to get tested-by from
Nayna.

Speaking of the changelog, I almost never have encounter a patch set
that does not have a changelog in the cover letter. And I'm not able to
interpret the process text in a way that it would ask to scatter
changelogs to the patches, and not put them to the cover letter [*].

Thus, I trust what I see as commodity. Not only that but it also helps a
lot with to see quickly what has changed, especially if the patches are
such that you have to take them in eventually.

In my own patch sets, I've recently started to xref associated lore korg
discussions in the change log entries, when it applies. I started to do
this with the SGX series when I had missed to address a number of Boris'
comments. It has helped a lot with my own tracking and I assume it is
also helpful for reviewers and maintainers to get the context, when they
need it.

The last paragraph is not something I demand. I'm merely just mentioning
it because I think it is a good practice for any patch set.

[*] https://lore.kernel.org/linux-integrity/14edea1f5092c2b8442165756b2ee32e56bed1eb.camel@HansenPartnership.com/

/Jarkko

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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-12  5:39 ` [PATCH v2 0/5] tpm_tis: fix interrupts (again) Jerry Snitselaar
@ 2020-10-13  1:23   ` Jarkko Sakkinen
  2020-10-18  5:34     ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-13  1:23 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe, Peter Huewe

On Sun, Oct 11, 2020 at 10:39:07PM -0700, Jerry Snitselaar wrote:
> 
> James Bottomley @ 2020-10-01 11:09 MST:
> 
> > The current state of the TIS TPM is that interrupts have been globally
> > disabled by various changes.  The problems we got reported the last
> > time they were enabled was interrupt storms.  With my own TIS TPM,
> > I've found that this is caused because my TPM doesn't do legacy
> > cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
> > requires any TIS TPM without legacy cycles not to act on any write to
> > an interrupt register unless the locality is enabled.  This means if
> > an interrupt fires after we relinquish the locality, the TPM_EOI in
> > the interrupt routine is ineffective meaning the same interrupt
> > triggers over and over again.  This problem also means we can have
> > trouble setting up interrupts on TIS TPMs because the current init
> > code does the setup before the locality is claimed for the first time.
> >
> > James
> >
> 
> 
> I tested initially with the following commits reverted:
> 
> aa4a63dd9816 tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's" | 2020-01-06 | (Stefan Berger)
> dda8b2af395b tpm: Revert "tpm_tis_core: Set TPM_CHIP_FLAG_IRQ before probing for interrupts" | 2020-01-06 | (Stefan Berger)
> 
> The laptop doesn't become unusable, but I lose the trackpad and get the following:
> 
> [    3.070501] irq 31: nobody cared (try booting with the "irqpoll" option)
> [    3.070504] CPU: 2 PID: 251 Comm: rngd Not tainted 5.8.13-201.local.fc32.x86_64 #1
> [    3.070504] Hardware name: LENOVO 20NYS7K90F/20NYS7K90F, BIOS N2JET83W (1.61 ) 11/22/2019
> [    3.070505] Call Trace:
> [    3.070511]  dump_stack+0x6b/0x88
> [    3.070514]  __report_bad_irq+0x35/0xa7
> [    3.070516]  note_interrupt.cold+0xb/0x6a
> [    3.070518]  handle_irq_event+0x88/0x8a
> [    3.070519]  handle_fasteoi_irq+0x78/0x1c0
> [    3.070522]  common_interrupt+0x68/0x140
> [    3.070524]  ? asm_common_interrupt+0x8/0x40
> [    3.070525]  asm_common_interrupt+0x1e/0x40
> [    3.070527] RIP: 0033:0x7f2eea3249b5
> [    3.070529] Code: e0 48 c1 e8 3c 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 37 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 1e 83 e0 01 48 31 45 f0 <48> 8b 45 e0 48 c1 e8 1b 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8
> [    3.070529] RSP: 002b:00007f2ee3ffebc0 EFLAGS: 00000202
> [    3.070530] RAX: 0000000000000001 RBX: 000000000000000a RCX: 000000000000002e
> [    3.070531] RDX: 0463400000000000 RSI: 0000000000000000 RDI: 0000000000000001
> [    3.070532] RBP: 00007f2ee3ffec10 R08: 0000000000000000 R09: 0000000000000035
> [    3.070532] R10: 00007ffde716f080 R11: 00007ffde716f080 R12: 00007f2edc004c00
> [    3.070533] R13: 00007ffde700a54f R14: 00007f2ee3ffed10 R15: 00005598a41e3680
> [    3.070534] handlers:
> [    3.070537] [<000000007b6f3232>] tis_int_handler
> [    3.070538] Disabling IRQ #31
> ...
> [   14.956342] irq 16: nobody cared (try booting with the "irqpoll" option)
> [   14.956344] CPU: 0 PID: 1013 Comm: rngd Not tainted 5.8.13-201.local.fc32.x86_64 #1
> [   14.956344] Hardware name: LENOVO 20NYS7K90F/20NYS7K90F, BIOS N2JET83W (1.61 ) 11/22/2019
> [   14.956345] Call Trace:
> [   14.956350]  dump_stack+0x6b/0x88
> [   14.956353]  __report_bad_irq+0x35/0xa7
> [   14.956354]  note_interrupt.cold+0xb/0x6a
> [   14.956355]  handle_irq_event+0x88/0x8a
> [   14.956356]  handle_fasteoi_irq+0x78/0x1c0
> [   14.956358]  common_interrupt+0x68/0x140
> [   14.956360]  ? asm_common_interrupt+0x8/0x40
> [   14.956361]  asm_common_interrupt+0x1e/0x40
> [   14.956362] RIP: 0033:0x7fcaff4399d3
> [   14.956363] Code: e0 48 c1 e8 1e 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 1b 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 16 83 e0 01 48 31 45 f0 <48> d1 65 e0 48 8b 45 f0 48 31 45 e0 83 45 d4 01 83 7d d4 40 0f 86
> [   14.956364] RSP: 002b:00007fcafe544bc0 EFLAGS: 00000246
> [   14.956364] RAX: 0000000000000000 RBX: 000000000000000a RCX: 0000000000000026
> [   14.956365] RDX: 000df20000000000 RSI: 0000000000000000 RDI: 0000000000000001
> [   14.956365] RBP: 00007fcafe544c10 R08: 0000000000000000 R09: 0000000000000035
> [   14.956366] R10: 00007ffc30bd2080 R11: 00007ffc30bd2080 R12: 00007fcaf0004c00
> [   14.956366] R13: 00007fcaf0004c00 R14: 00007fcaf0000b60 R15: 0000560216fcf0f2
> [   14.956367] handlers:
> [   14.956370] [<0000000024c0571e>] i801_isr [i2c_i801]
> [   14.956371] Disabling IRQ #16
> 
> /proc/interrupts shows:
> 
>   16:     100000          0          0          0          0          0          0          0  IR-IO-APIC   16-fasteoi   i801_smbus
>   31:          0          0     100000          0          0          0          0          0  IR-IO-APIC   31-fasteoi   tpm0
> 
> 
> I also get this behavior with your patchset applied. If I boot with
> tpm_tis.interrupts=0 it behaves.  The thought from Hans is to look at
> the dmi info and key off the vendor being Lenovo and bios date to
> decide if interrupts should be disabled. Since Dan ran also into this
> with something internal at Intel I don't know if that will be
> sufficient.
> 
> I hope to look over this patchset tomorrow.
> 
> Regards,
> Jerry

I'm sorry, I received this email only after pulling the latest with fdm.

/Jarkko

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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-13  1:17 ` Jarkko Sakkinen
@ 2020-10-13 15:15   ` Jerry Snitselaar
  2020-10-13 15:24     ` James Bottomley
  2020-10-18 21:05     ` Jarkko Sakkinen
  0 siblings, 2 replies; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-13 15:15 UTC (permalink / raw)
  To: equired, justmentioningitbecauseIthinkthatwouldbeagood
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe, Peter Huewe,
	Borislav Petkov, Nayna Jain


Jarkko Sakkinen @ 2020-10-12 18:17 MST:

> On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
>> The current state of the TIS TPM is that interrupts have been globally
>> disabled by various changes.  The problems we got reported the last
>> time they were enabled was interrupt storms.  With my own TIS TPM,
>> I've found that this is caused because my TPM doesn't do legacy
>> cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
>> requires any TIS TPM without legacy cycles not to act on any write to
>> an interrupt register unless the locality is enabled.  This means if
>> an interrupt fires after we relinquish the locality, the TPM_EOI in
>> the interrupt routine is ineffective meaning the same interrupt
>> triggers over and over again.  This problem also means we can have
>> trouble setting up interrupts on TIS TPMs because the current init
>> code does the setup before the locality is claimed for the first time.
>> 
>> James
>
> You should consider expanding the audience. Jerry, once you have some
> bandwidth (no rush, does not land before rc2), it would be great that if
> you could try this. I'm emphasizing this just because of the
> intersection. I think it would also make senset to get tested-by from
> Nayna.

I will run some tests on some other systems I have access to. As noted
in the other email I did a quick test with a t490s with an older bios
that exhibits the problem originally reported when Stefan's patch
enabled interrupts.

>
> Speaking of the changelog, I almost never have encounter a patch set
> that does not have a changelog in the cover letter. And I'm not able to
> interpret the process text in a way that it would ask to scatter
> changelogs to the patches, and not put them to the cover letter [*].
>
> Thus, I trust what I see as commodity. Not only that but it also helps a
> lot with to see quickly what has changed, especially if the patches are
> such that you have to take them in eventually.
>
> In my own patch sets, I've recently started to xref associated lore korg
> discussions in the change log entries, when it applies. I started to do
> this with the SGX series when I had missed to address a number of Boris'
> comments. It has helped a lot with my own tracking and I assume it is
> also helpful for reviewers and maintainers to get the context, when they
> need it.
>
> The last paragraph is not something I demand. I'm merely just mentioning
> it because I think it is a good practice for any patch set.
>
> [*] https://lore.kernel.org/linux-integrity/14edea1f5092c2b8442165756b2ee32e56bed1eb.camel@HansenPartnership.com/
>
> /Jarkko


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-13 15:15   ` Jerry Snitselaar
@ 2020-10-13 15:24     ` James Bottomley
  2020-10-13 16:05       ` Jerry Snitselaar
  2020-10-18 21:05     ` Jarkko Sakkinen
  1 sibling, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-10-13 15:24 UTC (permalink / raw)
  To: Jerry Snitselaar, equired, justmentioningitbecauseIthinkthatwouldbeagood
  Cc: linux-integrity, Jason Gunthorpe, Peter Huewe, Borislav Petkov,
	Nayna Jain

On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> 
> > On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
> > > The current state of the TIS TPM is that interrupts have been
> > > globally disabled by various changes.  The problems we got
> > > reported the last time they were enabled was interrupt
> > > storms.  With my own TIS TPM, I've found that this is caused
> > > because my TPM doesn't do legacy cycles, The TIS spec (chapter
> > > 6.1 "Locality Usage Per Register") requires any TIS TPM without
> > > legacy cycles not to act on any write to an interrupt register
> > > unless the locality is enabled.  This means if an interrupt fires
> > > after we relinquish the locality, the TPM_EOI in the interrupt
> > > routine is ineffective meaning the same interrupt triggers over
> > > and over again.  This problem also means we can have trouble
> > > setting up interrupts on TIS TPMs because the current init
> > > code does the setup before the locality is claimed for the first
> > > time.
> > > 
> > > James
> > 
> > You should consider expanding the audience.

Well, most people interested in testing this sort of thing are already
on the integrity list.

> >  Jerry, once you have some bandwidth (no rush, does not land before
> > rc2), it would be great that if you could try this. I'm emphasizing
> > this just because of the intersection. I think it would also make
> > senset to get tested-by from Nayna.
> 
> I will run some tests on some other systems I have access to. As
> noted in the other email I did a quick test with a t490s with an
> older bios that exhibits the problem originally reported when
> Stefan's patch enabled interrupts.

Well, it means there's still some other problem.  I was hoping that
because the rainbow pass system originally exhibited the same symptoms
(interrupt storm) fixing it would also fix the t490 and the ineffective
EOI bug looked like a great candidate for being the root cause.

How amenable are you to debugging this?  I originally figured out the
problem with the rainbow pass by putting ratelimited printks in the
interrupt routine and most of the TIS transmission ones, but it's
somewhat labour intensive doing it this way.

James



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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-13 15:24     ` James Bottomley
@ 2020-10-13 16:05       ` Jerry Snitselaar
  2020-10-14 15:03         ` Hans de Goede
  0 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-13 16:05 UTC (permalink / raw)
  To: James Bottomley
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	linux-integrity, Jason Gunthorpe, Peter Huewe, Borislav Petkov,
	Nayna Jain, Hans de Goede


James Bottomley @ 2020-10-13 08:24 MST:

> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>> 
>> > On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
>> > > The current state of the TIS TPM is that interrupts have been
>> > > globally disabled by various changes.  The problems we got
>> > > reported the last time they were enabled was interrupt
>> > > storms.  With my own TIS TPM, I've found that this is caused
>> > > because my TPM doesn't do legacy cycles, The TIS spec (chapter
>> > > 6.1 "Locality Usage Per Register") requires any TIS TPM without
>> > > legacy cycles not to act on any write to an interrupt register
>> > > unless the locality is enabled.  This means if an interrupt fires
>> > > after we relinquish the locality, the TPM_EOI in the interrupt
>> > > routine is ineffective meaning the same interrupt triggers over
>> > > and over again.  This problem also means we can have trouble
>> > > setting up interrupts on TIS TPMs because the current init
>> > > code does the setup before the locality is claimed for the first
>> > > time.
>> > > 
>> > > James
>> > 
>> > You should consider expanding the audience.
>
> Well, most people interested in testing this sort of thing are already
> on the integrity list.
>
>> >  Jerry, once you have some bandwidth (no rush, does not land before
>> > rc2), it would be great that if you could try this. I'm emphasizing
>> > this just because of the intersection. I think it would also make
>> > senset to get tested-by from Nayna.
>> 
>> I will run some tests on some other systems I have access to. As
>> noted in the other email I did a quick test with a t490s with an
>> older bios that exhibits the problem originally reported when
>> Stefan's patch enabled interrupts.
>
> Well, it means there's still some other problem.  I was hoping that
> because the rainbow pass system originally exhibited the same symptoms
> (interrupt storm) fixing it would also fix the t490 and the ineffective
> EOI bug looked like a great candidate for being the root cause.
>

Adding Hans to the list.

IIUC in the t490s case the problem lies with the hardware itself. Hans,
is that correct?

> How amenable are you to debugging this?  I originally figured out the
> problem with the rainbow pass by putting ratelimited printks in the
> interrupt routine and most of the TIS transmission ones, but it's
> somewhat labour intensive doing it this way.
>
> James


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-13 16:05       ` Jerry Snitselaar
@ 2020-10-14 15:03         ` Hans de Goede
  2020-10-14 15:23           ` James Bottomley
  0 siblings, 1 reply; 74+ messages in thread
From: Hans de Goede @ 2020-10-14 15:03 UTC (permalink / raw)
  To: Jerry Snitselaar, James Bottomley
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	linux-integrity, Jason Gunthorpe, Peter Huewe, Borislav Petkov,
	Nayna Jain, Hans de Goede

Hi,

On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
> 
> James Bottomley @ 2020-10-13 08:24 MST:
> 
>> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>>>
>>>> On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
>>>>> The current state of the TIS TPM is that interrupts have been
>>>>> globally disabled by various changes.  The problems we got
>>>>> reported the last time they were enabled was interrupt
>>>>> storms.  With my own TIS TPM, I've found that this is caused
>>>>> because my TPM doesn't do legacy cycles, The TIS spec (chapter
>>>>> 6.1 "Locality Usage Per Register") requires any TIS TPM without
>>>>> legacy cycles not to act on any write to an interrupt register
>>>>> unless the locality is enabled.  This means if an interrupt fires
>>>>> after we relinquish the locality, the TPM_EOI in the interrupt
>>>>> routine is ineffective meaning the same interrupt triggers over
>>>>> and over again.  This problem also means we can have trouble
>>>>> setting up interrupts on TIS TPMs because the current init
>>>>> code does the setup before the locality is claimed for the first
>>>>> time.
>>>>>
>>>>> James
>>>>
>>>> You should consider expanding the audience.
>>
>> Well, most people interested in testing this sort of thing are already
>> on the integrity list.
>>
>>>>   Jerry, once you have some bandwidth (no rush, does not land before
>>>> rc2), it would be great that if you could try this. I'm emphasizing
>>>> this just because of the intersection. I think it would also make
>>>> senset to get tested-by from Nayna.
>>>
>>> I will run some tests on some other systems I have access to. As
>>> noted in the other email I did a quick test with a t490s with an
>>> older bios that exhibits the problem originally reported when
>>> Stefan's patch enabled interrupts.
>>
>> Well, it means there's still some other problem.  I was hoping that
>> because the rainbow pass system originally exhibited the same symptoms
>> (interrupt storm) fixing it would also fix the t490 and the ineffective
>> EOI bug looked like a great candidate for being the root cause.
>>
> 
> Adding Hans to the list.
> 
> IIUC in the t490s case the problem lies with the hardware itself. Hans,
> is that correct?

More or less. AFAIK / have been told by Lenovo it is an issue with the
configuration of the inerrupt-type of the GPIO pin used for the IRQ,
which is a firmware issue which could be fixed by a BIOS update
(the pin is setup as a direct-irq pin for the APIC, so the OS has no
control of the IRQ type since with APIC irqs this is all supposed to
be setup properly before hand).

But it is a model specific issue, if we denylist IRQ usage on this
Lenovo model (and probably a few others) then we should be able to
restore the IRQ code to normal functionality for all other device
models which declare an IRQ in their resource tables.

Regards,

Hans


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 15:03         ` Hans de Goede
@ 2020-10-14 15:23           ` James Bottomley
  2020-10-14 16:04             ` Hans de Goede
  0 siblings, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-10-14 15:23 UTC (permalink / raw)
  To: Hans de Goede, Jerry Snitselaar
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	linux-integrity, Jason Gunthorpe, Peter Huewe, Borislav Petkov,
	Nayna Jain, Hans de Goede

On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
> On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
> > James Bottomley @ 2020-10-13 08:24 MST:
> > > On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
> > > > Jarkko Sakkinen @ 2020-10-12 18:17 MST:
[...]
> > > > >   Jerry, once you have some bandwidth (no rush, does not land
> > > > > before rc2), it would be great that if you could try this.
> > > > > I'm emphasizing this just because of the intersection. I
> > > > > think it would also make senset to get tested-by from Nayna.
> > > > 
> > > > I will run some tests on some other systems I have access to.
> > > > As noted in the other email I did a quick test with a t490s
> > > > with an older bios that exhibits the problem originally
> > > > reported when Stefan's patch enabled interrupts.
> > > 
> > > Well, it means there's still some other problem.  I was hoping
> > > that because the rainbow pass system originally exhibited the
> > > same symptoms (interrupt storm) fixing it would also fix the t490
> > > and the ineffective EOI bug looked like a great candidate for
> > > being the root cause.
> > > 
> > 
> > Adding Hans to the list.
> > 
> > IIUC in the t490s case the problem lies with the hardware itself.
> > Hans, is that correct?
> 
> More or less. AFAIK / have been told by Lenovo it is an issue with
> the configuration of the inerrupt-type of the GPIO pin used for the
> IRQ, which is a firmware issue which could be fixed by a BIOS update
> (the pin is setup as a direct-irq pin for the APIC, so the OS has no
> control of the IRQ type since with APIC irqs this is all supposed to
> be setup properly before hand).
> 
> But it is a model specific issue, if we denylist IRQ usage on this
> Lenovo model (and probably a few others) then we should be able to
> restore the IRQ code to normal functionality for all other device
> models which declare an IRQ in their resource tables.

I can do that with a quirk, but how do I identify the device?  TPM
manufacturer and version? or do I have to use something like the ACPI
bios version?

James



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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 15:23           ` James Bottomley
@ 2020-10-14 16:04             ` Hans de Goede
  2020-10-14 16:34               ` Jerry Snitselaar
  0 siblings, 1 reply; 74+ messages in thread
From: Hans de Goede @ 2020-10-14 16:04 UTC (permalink / raw)
  To: James Bottomley, Jerry Snitselaar
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	linux-integrity, Jason Gunthorpe, Peter Huewe, Borislav Petkov,
	Nayna Jain, Hans de Goede

Hi,

On 10/14/20 5:23 PM, James Bottomley wrote:
> On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>> On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>>> James Bottomley @ 2020-10-13 08:24 MST:
>>>> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>>>>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> [...]
>>>>>>    Jerry, once you have some bandwidth (no rush, does not land
>>>>>> before rc2), it would be great that if you could try this.
>>>>>> I'm emphasizing this just because of the intersection. I
>>>>>> think it would also make senset to get tested-by from Nayna.
>>>>>
>>>>> I will run some tests on some other systems I have access to.
>>>>> As noted in the other email I did a quick test with a t490s
>>>>> with an older bios that exhibits the problem originally
>>>>> reported when Stefan's patch enabled interrupts.
>>>>
>>>> Well, it means there's still some other problem.  I was hoping
>>>> that because the rainbow pass system originally exhibited the
>>>> same symptoms (interrupt storm) fixing it would also fix the t490
>>>> and the ineffective EOI bug looked like a great candidate for
>>>> being the root cause.
>>>>
>>>
>>> Adding Hans to the list.
>>>
>>> IIUC in the t490s case the problem lies with the hardware itself.
>>> Hans, is that correct?
>>
>> More or less. AFAIK / have been told by Lenovo it is an issue with
>> the configuration of the inerrupt-type of the GPIO pin used for the
>> IRQ, which is a firmware issue which could be fixed by a BIOS update
>> (the pin is setup as a direct-irq pin for the APIC, so the OS has no
>> control of the IRQ type since with APIC irqs this is all supposed to
>> be setup properly before hand).
>>
>> But it is a model specific issue, if we denylist IRQ usage on this
>> Lenovo model (and probably a few others) then we should be able to
>> restore the IRQ code to normal functionality for all other device
>> models which declare an IRQ in their resource tables.
> 
> I can do that with a quirk, but how do I identify the device?  TPM
> manufacturer and version? or do I have to use something like the ACPI
> bios version?

I'm not sure if the TPM ids are unique to one model/series of laptops.

So my idea for this was to match on DMI strings, specifically
use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
devices the string which you expect to be in DMI_PRODUCT_NAME
is actually in DMI_PRODUCT_VERSION).

You can easily get the strings for your device by doing:

cat /sys/class/dmi/id/sys_vendor
cat /sys/class/dmi/id/product_version

Regards,

Hans


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 16:04             ` Hans de Goede
@ 2020-10-14 16:34               ` Jerry Snitselaar
  2020-10-14 16:46                 ` Hans de Goede
  2020-10-14 16:49                 ` James Bottomley
  0 siblings, 2 replies; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-14 16:34 UTC (permalink / raw)
  To: Hans de Goede
  Cc: James Bottomley, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede


Hans de Goede @ 2020-10-14 09:04 MST:

> Hi,
>
> On 10/14/20 5:23 PM, James Bottomley wrote:
>> On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>>> On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>>>> James Bottomley @ 2020-10-13 08:24 MST:
>>>>> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>>>>>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>> [...]
>>>>>>>    Jerry, once you have some bandwidth (no rush, does not land
>>>>>>> before rc2), it would be great that if you could try this.
>>>>>>> I'm emphasizing this just because of the intersection. I
>>>>>>> think it would also make senset to get tested-by from Nayna.
>>>>>>
>>>>>> I will run some tests on some other systems I have access to.
>>>>>> As noted in the other email I did a quick test with a t490s
>>>>>> with an older bios that exhibits the problem originally
>>>>>> reported when Stefan's patch enabled interrupts.
>>>>>
>>>>> Well, it means there's still some other problem.  I was hoping
>>>>> that because the rainbow pass system originally exhibited the
>>>>> same symptoms (interrupt storm) fixing it would also fix the t490
>>>>> and the ineffective EOI bug looked like a great candidate for
>>>>> being the root cause.
>>>>>
>>>>
>>>> Adding Hans to the list.
>>>>
>>>> IIUC in the t490s case the problem lies with the hardware itself.
>>>> Hans, is that correct?
>>>
>>> More or less. AFAIK / have been told by Lenovo it is an issue with
>>> the configuration of the inerrupt-type of the GPIO pin used for the
>>> IRQ, which is a firmware issue which could be fixed by a BIOS update
>>> (the pin is setup as a direct-irq pin for the APIC, so the OS has no
>>> control of the IRQ type since with APIC irqs this is all supposed to
>>> be setup properly before hand).
>>>
>>> But it is a model specific issue, if we denylist IRQ usage on this
>>> Lenovo model (and probably a few others) then we should be able to
>>> restore the IRQ code to normal functionality for all other device
>>> models which declare an IRQ in their resource tables.
>> I can do that with a quirk, but how do I identify the device?  TPM
>> manufacturer and version? or do I have to use something like the ACPI
>> bios version?
>
> I'm not sure if the TPM ids are unique to one model/series of laptops.
>
> So my idea for this was to match on DMI strings, specifically
> use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
> strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
> devices the string which you expect to be in DMI_PRODUCT_NAME
> is actually in DMI_PRODUCT_VERSION).
>
> You can easily get the strings for your device by doing:
>
> cat /sys/class/dmi/id/sys_vendor
> cat /sys/class/dmi/id/product_version
>
> Regards,
>
> Hans

Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
if the bios is older than the fixed bios? Has Lenovo
released the fixed bios?


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 16:34               ` Jerry Snitselaar
@ 2020-10-14 16:46                 ` Hans de Goede
  2020-10-14 17:01                   ` Jerry Snitselaar
  2020-10-14 20:58                   ` Jerry Snitselaar
  2020-10-14 16:49                 ` James Bottomley
  1 sibling, 2 replies; 74+ messages in thread
From: Hans de Goede @ 2020-10-14 16:46 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede

Hi,

On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
> 
> Hans de Goede @ 2020-10-14 09:04 MST:
> 
>> Hi,
>>
>> On 10/14/20 5:23 PM, James Bottomley wrote:
>>> On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>>>> On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>>>>> James Bottomley @ 2020-10-13 08:24 MST:
>>>>>> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>>>>>>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>>> [...]
>>>>>>>>     Jerry, once you have some bandwidth (no rush, does not land
>>>>>>>> before rc2), it would be great that if you could try this.
>>>>>>>> I'm emphasizing this just because of the intersection. I
>>>>>>>> think it would also make senset to get tested-by from Nayna.
>>>>>>>
>>>>>>> I will run some tests on some other systems I have access to.
>>>>>>> As noted in the other email I did a quick test with a t490s
>>>>>>> with an older bios that exhibits the problem originally
>>>>>>> reported when Stefan's patch enabled interrupts.
>>>>>>
>>>>>> Well, it means there's still some other problem.  I was hoping
>>>>>> that because the rainbow pass system originally exhibited the
>>>>>> same symptoms (interrupt storm) fixing it would also fix the t490
>>>>>> and the ineffective EOI bug looked like a great candidate for
>>>>>> being the root cause.
>>>>>>
>>>>>
>>>>> Adding Hans to the list.
>>>>>
>>>>> IIUC in the t490s case the problem lies with the hardware itself.
>>>>> Hans, is that correct?
>>>>
>>>> More or less. AFAIK / have been told by Lenovo it is an issue with
>>>> the configuration of the inerrupt-type of the GPIO pin used for the
>>>> IRQ, which is a firmware issue which could be fixed by a BIOS update
>>>> (the pin is setup as a direct-irq pin for the APIC, so the OS has no
>>>> control of the IRQ type since with APIC irqs this is all supposed to
>>>> be setup properly before hand).
>>>>
>>>> But it is a model specific issue, if we denylist IRQ usage on this
>>>> Lenovo model (and probably a few others) then we should be able to
>>>> restore the IRQ code to normal functionality for all other device
>>>> models which declare an IRQ in their resource tables.
>>> I can do that with a quirk, but how do I identify the device?  TPM
>>> manufacturer and version? or do I have to use something like the ACPI
>>> bios version?
>>
>> I'm not sure if the TPM ids are unique to one model/series of laptops.
>>
>> So my idea for this was to match on DMI strings, specifically
>> use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
>> strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
>> devices the string which you expect to be in DMI_PRODUCT_NAME
>> is actually in DMI_PRODUCT_VERSION).
>>
>> You can easily get the strings for your device by doing:
>>
>> cat /sys/class/dmi/id/sys_vendor
>> cat /sys/class/dmi/id/product_version
>>
>> Regards,
>>
>> Hans
> 
> Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
> if the bios is older than the fixed bios? Has Lenovo
> released the fixed bios?

Maybe, the fixed BIOS-es which I have seen (for the X1C8,
broken BIOS was a pre-production BIOS) "fixed" this by
no longer listing an IRQ in the ACPI resources for the TPM.

Which means that the new BIOS still being on the deny list
does not matter since the IRQ support won't work anyways as
we no longer get an IRQ assigned.

So I don't think this is necessary and it will just complicate
things unnecessarily. This whole saga has already taken way
too long to fix. So IMHO the simplest fix where we just deny
list the broken models independent of BIOS versions and move
on seems best.

Regards,

Hans


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 16:34               ` Jerry Snitselaar
  2020-10-14 16:46                 ` Hans de Goede
@ 2020-10-14 16:49                 ` James Bottomley
  1 sibling, 0 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-14 16:49 UTC (permalink / raw)
  To: Jerry Snitselaar, Hans de Goede
  Cc: linux-integrity, Jason Gunthorpe, Peter Huewe, Borislav Petkov,
	Nayna Jain, Hans de Goede

On Wed, 2020-10-14 at 09:34 -0700, Jerry Snitselaar wrote:
> Hans de Goede @ 2020-10-14 09:04 MST:
> 
> > Hi,
> > 
> > On 10/14/20 5:23 PM, James Bottomley wrote:
> > > On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
> > > > On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
> > > > > James Bottomley @ 2020-10-13 08:24 MST:
> > > > > > On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
> > > > > > > Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> > > [...]
> > > > > > > >    Jerry, once you have some bandwidth (no rush, does
> > > > > > > > not land
> > > > > > > > before rc2), it would be great that if you could try
> > > > > > > > this.
> > > > > > > > I'm emphasizing this just because of the intersection.
> > > > > > > > I
> > > > > > > > think it would also make senset to get tested-by from
> > > > > > > > Nayna.
> > > > > > > 
> > > > > > > I will run some tests on some other systems I have access
> > > > > > > to.
> > > > > > > As noted in the other email I did a quick test with a
> > > > > > > t490s
> > > > > > > with an older bios that exhibits the problem originally
> > > > > > > reported when Stefan's patch enabled interrupts.
> > > > > > 
> > > > > > Well, it means there's still some other problem.  I was
> > > > > > hoping
> > > > > > that because the rainbow pass system originally exhibited
> > > > > > the
> > > > > > same symptoms (interrupt storm) fixing it would also fix
> > > > > > the t490
> > > > > > and the ineffective EOI bug looked like a great candidate
> > > > > > for
> > > > > > being the root cause.
> > > > > > 
> > > > > 
> > > > > Adding Hans to the list.
> > > > > 
> > > > > IIUC in the t490s case the problem lies with the hardware
> > > > > itself.
> > > > > Hans, is that correct?
> > > > 
> > > > More or less. AFAIK / have been told by Lenovo it is an issue
> > > > with
> > > > the configuration of the inerrupt-type of the GPIO pin used for
> > > > the
> > > > IRQ, which is a firmware issue which could be fixed by a BIOS
> > > > update
> > > > (the pin is setup as a direct-irq pin for the APIC, so the OS
> > > > has no
> > > > control of the IRQ type since with APIC irqs this is all
> > > > supposed to
> > > > be setup properly before hand).
> > > > 
> > > > But it is a model specific issue, if we denylist IRQ usage on
> > > > this
> > > > Lenovo model (and probably a few others) then we should be able
> > > > to
> > > > restore the IRQ code to normal functionality for all other
> > > > device
> > > > models which declare an IRQ in their resource tables.
> > > I can do that with a quirk, but how do I identify the
> > > device?  TPM
> > > manufacturer and version? or do I have to use something like the
> > > ACPI
> > > bios version?
> > 
> > I'm not sure if the TPM ids are unique to one model/series of
> > laptops.
> > 
> > So my idea for this was to match on DMI strings, specifically
> > use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
> > strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
> > devices the string which you expect to be in DMI_PRODUCT_NAME
> > is actually in DMI_PRODUCT_VERSION).
> > 
> > You can easily get the strings for your device by doing:
> > 
> > cat /sys/class/dmi/id/sys_vendor
> > cat /sys/class/dmi/id/product_version
> > 
> > Regards,
> > 
> > Hans
> 
> Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
> if the bios is older than the fixed bios? Has Lenovo
> released the fixed bios?

Yes, get all the DMI before and after information, but ideally also the
TIS before and after information.  That's what you get from the tpm_tis
line in dmesg:

tpm_tis MSFT0101:00: 2.0 TPM (device-id 0xFE, rev-id 2)

What I was hoping is rev-id might change.  However, if the bug is
specific to the Lenovo firmware and not the TPM firmware, that is
unlikely.

James



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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 16:46                 ` Hans de Goede
@ 2020-10-14 17:01                   ` Jerry Snitselaar
  2020-10-14 17:04                     ` Jerry Snitselaar
  2020-10-14 20:58                   ` Jerry Snitselaar
  1 sibling, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-14 17:01 UTC (permalink / raw)
  To: Hans de Goede
  Cc: James Bottomley, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede


Hans de Goede @ 2020-10-14 09:46 MST:

> Hi,
>
> On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
>> Hans de Goede @ 2020-10-14 09:04 MST:
>> 
>>> Hi,
>>>
>>> On 10/14/20 5:23 PM, James Bottomley wrote:
>>>> On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>>>>> On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>>>>>> James Bottomley @ 2020-10-13 08:24 MST:
>>>>>>> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>>>>>>>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>>>> [...]
>>>>>>>>>     Jerry, once you have some bandwidth (no rush, does not land
>>>>>>>>> before rc2), it would be great that if you could try this.
>>>>>>>>> I'm emphasizing this just because of the intersection. I
>>>>>>>>> think it would also make senset to get tested-by from Nayna.
>>>>>>>>
>>>>>>>> I will run some tests on some other systems I have access to.
>>>>>>>> As noted in the other email I did a quick test with a t490s
>>>>>>>> with an older bios that exhibits the problem originally
>>>>>>>> reported when Stefan's patch enabled interrupts.
>>>>>>>
>>>>>>> Well, it means there's still some other problem.  I was hoping
>>>>>>> that because the rainbow pass system originally exhibited the
>>>>>>> same symptoms (interrupt storm) fixing it would also fix the t490
>>>>>>> and the ineffective EOI bug looked like a great candidate for
>>>>>>> being the root cause.
>>>>>>>
>>>>>>
>>>>>> Adding Hans to the list.
>>>>>>
>>>>>> IIUC in the t490s case the problem lies with the hardware itself.
>>>>>> Hans, is that correct?
>>>>>
>>>>> More or less. AFAIK / have been told by Lenovo it is an issue with
>>>>> the configuration of the inerrupt-type of the GPIO pin used for the
>>>>> IRQ, which is a firmware issue which could be fixed by a BIOS update
>>>>> (the pin is setup as a direct-irq pin for the APIC, so the OS has no
>>>>> control of the IRQ type since with APIC irqs this is all supposed to
>>>>> be setup properly before hand).
>>>>>
>>>>> But it is a model specific issue, if we denylist IRQ usage on this
>>>>> Lenovo model (and probably a few others) then we should be able to
>>>>> restore the IRQ code to normal functionality for all other device
>>>>> models which declare an IRQ in their resource tables.
>>>> I can do that with a quirk, but how do I identify the device?  TPM
>>>> manufacturer and version? or do I have to use something like the ACPI
>>>> bios version?
>>>
>>> I'm not sure if the TPM ids are unique to one model/series of laptops.
>>>
>>> So my idea for this was to match on DMI strings, specifically
>>> use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
>>> strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
>>> devices the string which you expect to be in DMI_PRODUCT_NAME
>>> is actually in DMI_PRODUCT_VERSION).
>>>
>>> You can easily get the strings for your device by doing:
>>>
>>> cat /sys/class/dmi/id/sys_vendor
>>> cat /sys/class/dmi/id/product_version
>>>
>>> Regards,
>>>
>>> Hans
>> Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
>> if the bios is older than the fixed bios? Has Lenovo
>> released the fixed bios?
>
> Maybe, the fixed BIOS-es which I have seen (for the X1C8,
> broken BIOS was a pre-production BIOS) "fixed" this by
> no longer listing an IRQ in the ACPI resources for the TPM.
>
> Which means that the new BIOS still being on the deny list
> does not matter since the IRQ support won't work anyways as
> we no longer get an IRQ assigned.
>
> So I don't think this is necessary and it will just complicate
> things unnecessarily. This whole saga has already taken way
> too long to fix. So IMHO the simplest fix where we just deny
> list the broken models independent of BIOS versions and move
> on seems best.
>
> Regards,
>
> Hans

Yea, probably just best to disable for the model and be done
with it.

Regards,
Jerry


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 17:01                   ` Jerry Snitselaar
@ 2020-10-14 17:04                     ` Jerry Snitselaar
  0 siblings, 0 replies; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-14 17:04 UTC (permalink / raw)
  To: Hans de Goede
  Cc: James Bottomley, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede


Jerry Snitselaar @ 2020-10-14 10:01 MST:

> Hans de Goede @ 2020-10-14 09:46 MST:
>
>> Hi,
>>
>> On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
>>> Hans de Goede @ 2020-10-14 09:04 MST:
>>> 
>>>> Hi,
>>>>
>>>> On 10/14/20 5:23 PM, James Bottomley wrote:
>>>>> On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>>>>>> On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>>>>>>> James Bottomley @ 2020-10-13 08:24 MST:
>>>>>>>> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>>>>>>>>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>>>>> [...]
>>>>>>>>>>     Jerry, once you have some bandwidth (no rush, does not land
>>>>>>>>>> before rc2), it would be great that if you could try this.
>>>>>>>>>> I'm emphasizing this just because of the intersection. I
>>>>>>>>>> think it would also make senset to get tested-by from Nayna.
>>>>>>>>>
>>>>>>>>> I will run some tests on some other systems I have access to.
>>>>>>>>> As noted in the other email I did a quick test with a t490s
>>>>>>>>> with an older bios that exhibits the problem originally
>>>>>>>>> reported when Stefan's patch enabled interrupts.
>>>>>>>>
>>>>>>>> Well, it means there's still some other problem.  I was hoping
>>>>>>>> that because the rainbow pass system originally exhibited the
>>>>>>>> same symptoms (interrupt storm) fixing it would also fix the t490
>>>>>>>> and the ineffective EOI bug looked like a great candidate for
>>>>>>>> being the root cause.
>>>>>>>>
>>>>>>>
>>>>>>> Adding Hans to the list.
>>>>>>>
>>>>>>> IIUC in the t490s case the problem lies with the hardware itself.
>>>>>>> Hans, is that correct?
>>>>>>
>>>>>> More or less. AFAIK / have been told by Lenovo it is an issue with
>>>>>> the configuration of the inerrupt-type of the GPIO pin used for the
>>>>>> IRQ, which is a firmware issue which could be fixed by a BIOS update
>>>>>> (the pin is setup as a direct-irq pin for the APIC, so the OS has no
>>>>>> control of the IRQ type since with APIC irqs this is all supposed to
>>>>>> be setup properly before hand).
>>>>>>
>>>>>> But it is a model specific issue, if we denylist IRQ usage on this
>>>>>> Lenovo model (and probably a few others) then we should be able to
>>>>>> restore the IRQ code to normal functionality for all other device
>>>>>> models which declare an IRQ in their resource tables.
>>>>> I can do that with a quirk, but how do I identify the device?  TPM
>>>>> manufacturer and version? or do I have to use something like the ACPI
>>>>> bios version?
>>>>
>>>> I'm not sure if the TPM ids are unique to one model/series of laptops.
>>>>
>>>> So my idea for this was to match on DMI strings, specifically
>>>> use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
>>>> strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
>>>> devices the string which you expect to be in DMI_PRODUCT_NAME
>>>> is actually in DMI_PRODUCT_VERSION).
>>>>
>>>> You can easily get the strings for your device by doing:
>>>>
>>>> cat /sys/class/dmi/id/sys_vendor
>>>> cat /sys/class/dmi/id/product_version
>>>>
>>>> Regards,
>>>>
>>>> Hans
>>> Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
>>> if the bios is older than the fixed bios? Has Lenovo
>>> released the fixed bios?
>>
>> Maybe, the fixed BIOS-es which I have seen (for the X1C8,
>> broken BIOS was a pre-production BIOS) "fixed" this by
>> no longer listing an IRQ in the ACPI resources for the TPM.
>>
>> Which means that the new BIOS still being on the deny list
>> does not matter since the IRQ support won't work anyways as
>> we no longer get an IRQ assigned.
>>
>> So I don't think this is necessary and it will just complicate
>> things unnecessarily. This whole saga has already taken way
>> too long to fix. So IMHO the simplest fix where we just deny
>> list the broken models independent of BIOS versions and move
>> on seems best.
>>
>> Regards,
>>
>> Hans
>
> Yea, probably just best to disable for the model and be done
> with it.
>
> Regards,
> Jerry

# cat /sys/class/dmi/id/sys_vendor
LENOVO
# cat /sys/class/dmi/id/product_version
ThinkPad T490s


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 16:46                 ` Hans de Goede
  2020-10-14 17:01                   ` Jerry Snitselaar
@ 2020-10-14 20:58                   ` Jerry Snitselaar
  2020-10-15  7:38                     ` Hans de Goede
  2020-10-15 15:36                     ` James Bottomley
  1 sibling, 2 replies; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-14 20:58 UTC (permalink / raw)
  To: Hans de Goede
  Cc: James Bottomley, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede


Hans de Goede @ 2020-10-14 09:46 MST:

> Hi,
>
> On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
>> Hans de Goede @ 2020-10-14 09:04 MST:
>> 
>>> Hi,
>>>
>>> On 10/14/20 5:23 PM, James Bottomley wrote:
>>>> On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>>>>> On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>>>>>> James Bottomley @ 2020-10-13 08:24 MST:
>>>>>>> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>>>>>>>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>>>> [...]
>>>>>>>>>     Jerry, once you have some bandwidth (no rush, does not land
>>>>>>>>> before rc2), it would be great that if you could try this.
>>>>>>>>> I'm emphasizing this just because of the intersection. I
>>>>>>>>> think it would also make senset to get tested-by from Nayna.
>>>>>>>>
>>>>>>>> I will run some tests on some other systems I have access to.
>>>>>>>> As noted in the other email I did a quick test with a t490s
>>>>>>>> with an older bios that exhibits the problem originally
>>>>>>>> reported when Stefan's patch enabled interrupts.
>>>>>>>
>>>>>>> Well, it means there's still some other problem.  I was hoping
>>>>>>> that because the rainbow pass system originally exhibited the
>>>>>>> same symptoms (interrupt storm) fixing it would also fix the t490
>>>>>>> and the ineffective EOI bug looked like a great candidate for
>>>>>>> being the root cause.
>>>>>>>
>>>>>>
>>>>>> Adding Hans to the list.
>>>>>>
>>>>>> IIUC in the t490s case the problem lies with the hardware itself.
>>>>>> Hans, is that correct?
>>>>>
>>>>> More or less. AFAIK / have been told by Lenovo it is an issue with
>>>>> the configuration of the inerrupt-type of the GPIO pin used for the
>>>>> IRQ, which is a firmware issue which could be fixed by a BIOS update
>>>>> (the pin is setup as a direct-irq pin for the APIC, so the OS has no
>>>>> control of the IRQ type since with APIC irqs this is all supposed to
>>>>> be setup properly before hand).
>>>>>
>>>>> But it is a model specific issue, if we denylist IRQ usage on this
>>>>> Lenovo model (and probably a few others) then we should be able to
>>>>> restore the IRQ code to normal functionality for all other device
>>>>> models which declare an IRQ in their resource tables.
>>>> I can do that with a quirk, but how do I identify the device?  TPM
>>>> manufacturer and version? or do I have to use something like the ACPI
>>>> bios version?
>>>
>>> I'm not sure if the TPM ids are unique to one model/series of laptops.
>>>
>>> So my idea for this was to match on DMI strings, specifically
>>> use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
>>> strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
>>> devices the string which you expect to be in DMI_PRODUCT_NAME
>>> is actually in DMI_PRODUCT_VERSION).
>>>
>>> You can easily get the strings for your device by doing:
>>>
>>> cat /sys/class/dmi/id/sys_vendor
>>> cat /sys/class/dmi/id/product_version
>>>
>>> Regards,
>>>
>>> Hans
>> Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
>> if the bios is older than the fixed bios? Has Lenovo
>> released the fixed bios?
>
> Maybe, the fixed BIOS-es which I have seen (for the X1C8,
> broken BIOS was a pre-production BIOS) "fixed" this by
> no longer listing an IRQ in the ACPI resources for the TPM.
>
> Which means that the new BIOS still being on the deny list
> does not matter since the IRQ support won't work anyways as
> we no longer get an IRQ assigned.
>
> So I don't think this is necessary and it will just complicate
> things unnecessarily. This whole saga has already taken way
> too long to fix. So IMHO the simplest fix where we just deny
> list the broken models independent of BIOS versions and move
> on seems best.
>
> Regards,
>
> Hans

This worked for me:

diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 0b214963539d..abe674d1de6d 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -27,6 +27,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/kernel.h>
+#include <linux/dmi.h>
 #include "tpm.h"
 #include "tpm_tis_core.h"

@@ -63,6 +64,26 @@ module_param(force, bool, 0444);
 MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
 #endif

+static int tpm_tis_disable_irq(const struct dmi_system_id *d)
+{
+       pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d->ident);
+       interrupts = false;
+
+       return 0;
+}
+
+static const struct dmi_system_id tpm_tis_dmi_table[] = {
+       {
+               .callback = tpm_tis_disable_irq,
+               .ident = "ThinkPad T490s",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"),
+               },
+       },
+       {}
+};
+
 #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
 static int has_hid(struct acpi_device *dev, const char *hid)
 {
@@ -192,6 +213,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info)
        int irq = -1;
        int rc;

+       dmi_check_system(tpm_tis_dmi_table);
+
        rc = check_acpi_tpm2(dev);
        if (rc)
                return rc;


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 20:58                   ` Jerry Snitselaar
@ 2020-10-15  7:38                     ` Hans de Goede
  2020-10-18 21:09                       ` Jarkko Sakkinen
  2020-10-15 15:36                     ` James Bottomley
  1 sibling, 1 reply; 74+ messages in thread
From: Hans de Goede @ 2020-10-15  7:38 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede

Hi,

On 10/14/20 10:58 PM, Jerry Snitselaar wrote:
> 
> Hans de Goede @ 2020-10-14 09:46 MST:
> 
>> Hi,
>>
>> On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
>>> Hans de Goede @ 2020-10-14 09:04 MST:
>>>
>>>> Hi,
>>>>
>>>> On 10/14/20 5:23 PM, James Bottomley wrote:
>>>>> On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>>>>>> On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>>>>>>> James Bottomley @ 2020-10-13 08:24 MST:
>>>>>>>> On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
>>>>>>>>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>>>>> [...]
>>>>>>>>>>      Jerry, once you have some bandwidth (no rush, does not land
>>>>>>>>>> before rc2), it would be great that if you could try this.
>>>>>>>>>> I'm emphasizing this just because of the intersection. I
>>>>>>>>>> think it would also make senset to get tested-by from Nayna.
>>>>>>>>>
>>>>>>>>> I will run some tests on some other systems I have access to.
>>>>>>>>> As noted in the other email I did a quick test with a t490s
>>>>>>>>> with an older bios that exhibits the problem originally
>>>>>>>>> reported when Stefan's patch enabled interrupts.
>>>>>>>>
>>>>>>>> Well, it means there's still some other problem.  I was hoping
>>>>>>>> that because the rainbow pass system originally exhibited the
>>>>>>>> same symptoms (interrupt storm) fixing it would also fix the t490
>>>>>>>> and the ineffective EOI bug looked like a great candidate for
>>>>>>>> being the root cause.
>>>>>>>>
>>>>>>>
>>>>>>> Adding Hans to the list.
>>>>>>>
>>>>>>> IIUC in the t490s case the problem lies with the hardware itself.
>>>>>>> Hans, is that correct?
>>>>>>
>>>>>> More or less. AFAIK / have been told by Lenovo it is an issue with
>>>>>> the configuration of the inerrupt-type of the GPIO pin used for the
>>>>>> IRQ, which is a firmware issue which could be fixed by a BIOS update
>>>>>> (the pin is setup as a direct-irq pin for the APIC, so the OS has no
>>>>>> control of the IRQ type since with APIC irqs this is all supposed to
>>>>>> be setup properly before hand).
>>>>>>
>>>>>> But it is a model specific issue, if we denylist IRQ usage on this
>>>>>> Lenovo model (and probably a few others) then we should be able to
>>>>>> restore the IRQ code to normal functionality for all other device
>>>>>> models which declare an IRQ in their resource tables.
>>>>> I can do that with a quirk, but how do I identify the device?  TPM
>>>>> manufacturer and version? or do I have to use something like the ACPI
>>>>> bios version?
>>>>
>>>> I'm not sure if the TPM ids are unique to one model/series of laptops.
>>>>
>>>> So my idea for this was to match on DMI strings, specifically
>>>> use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
>>>> strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
>>>> devices the string which you expect to be in DMI_PRODUCT_NAME
>>>> is actually in DMI_PRODUCT_VERSION).
>>>>
>>>> You can easily get the strings for your device by doing:
>>>>
>>>> cat /sys/class/dmi/id/sys_vendor
>>>> cat /sys/class/dmi/id/product_version
>>>>
>>>> Regards,
>>>>
>>>> Hans
>>> Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
>>> if the bios is older than the fixed bios? Has Lenovo
>>> released the fixed bios?
>>
>> Maybe, the fixed BIOS-es which I have seen (for the X1C8,
>> broken BIOS was a pre-production BIOS) "fixed" this by
>> no longer listing an IRQ in the ACPI resources for the TPM.
>>
>> Which means that the new BIOS still being on the deny list
>> does not matter since the IRQ support won't work anyways as
>> we no longer get an IRQ assigned.
>>
>> So I don't think this is necessary and it will just complicate
>> things unnecessarily. This whole saga has already taken way
>> too long to fix. So IMHO the simplest fix where we just deny
>> list the broken models independent of BIOS versions and move
>> on seems best.
>>
>> Regards,
>>
>> Hans
> 
> This worked for me:

That looks good to me, can you submit this upstream please ?

If you Cc me I'll give it my Reviewed-by.

Regards,

Hans


> 
> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index 0b214963539d..abe674d1de6d 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -27,6 +27,7 @@
>   #include <linux/of.h>
>   #include <linux/of_device.h>
>   #include <linux/kernel.h>
> +#include <linux/dmi.h>
>   #include "tpm.h"
>   #include "tpm_tis_core.h"
> 
> @@ -63,6 +64,26 @@ module_param(force, bool, 0444);
>   MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
>   #endif
> 
> +static int tpm_tis_disable_irq(const struct dmi_system_id *d)
> +{
> +       pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d->ident);
> +       interrupts = false;
> +
> +       return 0;
> +}
> +
> +static const struct dmi_system_id tpm_tis_dmi_table[] = {
> +       {
> +               .callback = tpm_tis_disable_irq,
> +               .ident = "ThinkPad T490s",
> +               .matches = {
> +                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> +                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"),
> +               },
> +       },
> +       {}
> +};
> +
>   #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
>   static int has_hid(struct acpi_device *dev, const char *hid)
>   {
> @@ -192,6 +213,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info)
>          int irq = -1;
>          int rc;
> 
> +       dmi_check_system(tpm_tis_dmi_table);
> +
>          rc = check_acpi_tpm2(dev);
>          if (rc)
>                  return rc;
> 


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-14 20:58                   ` Jerry Snitselaar
  2020-10-15  7:38                     ` Hans de Goede
@ 2020-10-15 15:36                     ` James Bottomley
  2020-10-15 18:48                       ` Jerry Snitselaar
  1 sibling, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-10-15 15:36 UTC (permalink / raw)
  To: Jerry Snitselaar, Hans de Goede
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	linux-integrity, Jason Gunthorpe, Peter Huewe, Borislav Petkov,
	Nayna Jain, Hans de Goede

On Wed, 2020-10-14 at 13:58 -0700, Jerry Snitselaar wrote:
> Hans de Goede @ 2020-10-14 09:46 MST:
> 
> > Hi,
> > 
> > On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
> > > Hans de Goede @ 2020-10-14 09:04 MST:
> > > 
> > > > Hi,
> > > > 
> > > > On 10/14/20 5:23 PM, James Bottomley wrote:
> > > > > On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
> > > > > > On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
> > > > > > > James Bottomley @ 2020-10-13 08:24 MST:
> > > > > > > > On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar
> > > > > > > > wrote:
> > > > > > > > > Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> > > > > [...]
> > > > > > > > > >     Jerry, once you have some bandwidth (no rush,
> > > > > > > > > > does not land
> > > > > > > > > > before rc2), it would be great that if you could
> > > > > > > > > > try this.
> > > > > > > > > > I'm emphasizing this just because of the
> > > > > > > > > > intersection. I
> > > > > > > > > > think it would also make senset to get tested-by
> > > > > > > > > > from Nayna.
> > > > > > > > > 
> > > > > > > > > I will run some tests on some other systems I have
> > > > > > > > > access to.
> > > > > > > > > As noted in the other email I did a quick test with a
> > > > > > > > > t490s
> > > > > > > > > with an older bios that exhibits the problem
> > > > > > > > > originally
> > > > > > > > > reported when Stefan's patch enabled interrupts.
> > > > > > > > 
> > > > > > > > Well, it means there's still some other problem.  I was
> > > > > > > > hoping
> > > > > > > > that because the rainbow pass system originally
> > > > > > > > exhibited the
> > > > > > > > same symptoms (interrupt storm) fixing it would also
> > > > > > > > fix the t490
> > > > > > > > and the ineffective EOI bug looked like a great
> > > > > > > > candidate for
> > > > > > > > being the root cause.
> > > > > > > > 
> > > > > > > 
> > > > > > > Adding Hans to the list.
> > > > > > > 
> > > > > > > IIUC in the t490s case the problem lies with the hardware
> > > > > > > itself.
> > > > > > > Hans, is that correct?
> > > > > > 
> > > > > > More or less. AFAIK / have been told by Lenovo it is an
> > > > > > issue with
> > > > > > the configuration of the inerrupt-type of the GPIO pin used
> > > > > > for the
> > > > > > IRQ, which is a firmware issue which could be fixed by a
> > > > > > BIOS update
> > > > > > (the pin is setup as a direct-irq pin for the APIC, so the
> > > > > > OS has no
> > > > > > control of the IRQ type since with APIC irqs this is all
> > > > > > supposed to
> > > > > > be setup properly before hand).
> > > > > > 
> > > > > > But it is a model specific issue, if we denylist IRQ usage
> > > > > > on this
> > > > > > Lenovo model (and probably a few others) then we should be
> > > > > > able to
> > > > > > restore the IRQ code to normal functionality for all other
> > > > > > device
> > > > > > models which declare an IRQ in their resource tables.
> > > > > I can do that with a quirk, but how do I identify the
> > > > > device?  TPM
> > > > > manufacturer and version? or do I have to use something like
> > > > > the ACPI
> > > > > bios version?
> > > > 
> > > > I'm not sure if the TPM ids are unique to one model/series of
> > > > laptops.
> > > > 
> > > > So my idea for this was to match on DMI strings, specifically
> > > > use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
> > > > strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
> > > > devices the string which you expect to be in DMI_PRODUCT_NAME
> > > > is actually in DMI_PRODUCT_VERSION).
> > > > 
> > > > You can easily get the strings for your device by doing:
> > > > 
> > > > cat /sys/class/dmi/id/sys_vendor
> > > > cat /sys/class/dmi/id/product_version
> > > > 
> > > > Regards,
> > > > 
> > > > Hans
> > > Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
> > > if the bios is older than the fixed bios? Has Lenovo
> > > released the fixed bios?
> > 
> > Maybe, the fixed BIOS-es which I have seen (for the X1C8,
> > broken BIOS was a pre-production BIOS) "fixed" this by
> > no longer listing an IRQ in the ACPI resources for the TPM.
> > 
> > Which means that the new BIOS still being on the deny list
> > does not matter since the IRQ support won't work anyways as
> > we no longer get an IRQ assigned.
> > 
> > So I don't think this is necessary and it will just complicate
> > things unnecessarily. This whole saga has already taken way
> > too long to fix. So IMHO the simplest fix where we just deny
> > list the broken models independent of BIOS versions and move
> > on seems best.
> > 
> > Regards,
> > 
> > Hans
> 
> This worked for me:
> 
> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index 0b214963539d..abe674d1de6d 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -27,6 +27,7 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/kernel.h>
> +#include <linux/dmi.h>
>  #include "tpm.h"
>  #include "tpm_tis_core.h"
> 
> @@ -63,6 +64,26 @@ module_param(force, bool, 0444);
>  MODULE_PARM_DESC(force, "Force device probe rather than using ACPI
> entry");
>  #endif
> 
> +static int tpm_tis_disable_irq(const struct dmi_system_id *d)
> +{
> +       pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d-
> >ident);
> +       interrupts = false;
> +
> +       return 0;
> +}
> +
> +static const struct dmi_system_id tpm_tis_dmi_table[] = {
> +       {
> +               .callback = tpm_tis_disable_irq,
> +               .ident = "ThinkPad T490s",
> +               .matches = {
> +                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> +                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad
> T490s"),
> +               },
> +       },
> +       {}
> +};
> +
>  #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
>  static int has_hid(struct acpi_device *dev, const char *hid)
>  {
> @@ -192,6 +213,8 @@ static int tpm_tis_init(struct device *dev,
> struct tpm_info *tpm_info)
>         int irq = -1;
>         int rc;
> 
> +       dmi_check_system(tpm_tis_dmi_table);
> +
>         rc = check_acpi_tpm2(dev);
>         if (rc)
>                 return rc;

This looks OK to me with the caveat that anyone on one of these systems
has no way to enable interrupts again if they think they have a fixed
bios.  What about making interrupts a tristate with the default value
-1?  Then in the dmi check, if we see -1 we set it to 0 but if we see 1
(the user has specified interrupts=1 on the module insert line) we
leave it?

James



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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-15 15:36                     ` James Bottomley
@ 2020-10-15 18:48                       ` Jerry Snitselaar
  2020-10-15 18:57                         ` James Bottomley
  0 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-15 18:48 UTC (permalink / raw)
  To: James Bottomley
  Cc: Hans de Goede, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede


James Bottomley @ 2020-10-15 08:36 MST:

> On Wed, 2020-10-14 at 13:58 -0700, Jerry Snitselaar wrote:
>> Hans de Goede @ 2020-10-14 09:46 MST:
>> 
>> > Hi,
>> > 
>> > On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
>> > > Hans de Goede @ 2020-10-14 09:04 MST:
>> > > 
>> > > > Hi,
>> > > > 
>> > > > On 10/14/20 5:23 PM, James Bottomley wrote:
>> > > > > On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>> > > > > > On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>> > > > > > > James Bottomley @ 2020-10-13 08:24 MST:
>> > > > > > > > On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar
>> > > > > > > > wrote:
>> > > > > > > > > Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>> > > > > [...]
>> > > > > > > > > >     Jerry, once you have some bandwidth (no rush,
>> > > > > > > > > > does not land
>> > > > > > > > > > before rc2), it would be great that if you could
>> > > > > > > > > > try this.
>> > > > > > > > > > I'm emphasizing this just because of the
>> > > > > > > > > > intersection. I
>> > > > > > > > > > think it would also make senset to get tested-by
>> > > > > > > > > > from Nayna.
>> > > > > > > > > 
>> > > > > > > > > I will run some tests on some other systems I have
>> > > > > > > > > access to.
>> > > > > > > > > As noted in the other email I did a quick test with a
>> > > > > > > > > t490s
>> > > > > > > > > with an older bios that exhibits the problem
>> > > > > > > > > originally
>> > > > > > > > > reported when Stefan's patch enabled interrupts.
>> > > > > > > > 
>> > > > > > > > Well, it means there's still some other problem.  I was
>> > > > > > > > hoping
>> > > > > > > > that because the rainbow pass system originally
>> > > > > > > > exhibited the
>> > > > > > > > same symptoms (interrupt storm) fixing it would also
>> > > > > > > > fix the t490
>> > > > > > > > and the ineffective EOI bug looked like a great
>> > > > > > > > candidate for
>> > > > > > > > being the root cause.
>> > > > > > > > 
>> > > > > > > 
>> > > > > > > Adding Hans to the list.
>> > > > > > > 
>> > > > > > > IIUC in the t490s case the problem lies with the hardware
>> > > > > > > itself.
>> > > > > > > Hans, is that correct?
>> > > > > > 
>> > > > > > More or less. AFAIK / have been told by Lenovo it is an
>> > > > > > issue with
>> > > > > > the configuration of the inerrupt-type of the GPIO pin used
>> > > > > > for the
>> > > > > > IRQ, which is a firmware issue which could be fixed by a
>> > > > > > BIOS update
>> > > > > > (the pin is setup as a direct-irq pin for the APIC, so the
>> > > > > > OS has no
>> > > > > > control of the IRQ type since with APIC irqs this is all
>> > > > > > supposed to
>> > > > > > be setup properly before hand).
>> > > > > > 
>> > > > > > But it is a model specific issue, if we denylist IRQ usage
>> > > > > > on this
>> > > > > > Lenovo model (and probably a few others) then we should be
>> > > > > > able to
>> > > > > > restore the IRQ code to normal functionality for all other
>> > > > > > device
>> > > > > > models which declare an IRQ in their resource tables.
>> > > > > I can do that with a quirk, but how do I identify the
>> > > > > device?  TPM
>> > > > > manufacturer and version? or do I have to use something like
>> > > > > the ACPI
>> > > > > bios version?
>> > > > 
>> > > > I'm not sure if the TPM ids are unique to one model/series of
>> > > > laptops.
>> > > > 
>> > > > So my idea for this was to match on DMI strings, specifically
>> > > > use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
>> > > > strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
>> > > > devices the string which you expect to be in DMI_PRODUCT_NAME
>> > > > is actually in DMI_PRODUCT_VERSION).
>> > > > 
>> > > > You can easily get the strings for your device by doing:
>> > > > 
>> > > > cat /sys/class/dmi/id/sys_vendor
>> > > > cat /sys/class/dmi/id/product_version
>> > > > 
>> > > > Regards,
>> > > > 
>> > > > Hans
>> > > Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
>> > > if the bios is older than the fixed bios? Has Lenovo
>> > > released the fixed bios?
>> > 
>> > Maybe, the fixed BIOS-es which I have seen (for the X1C8,
>> > broken BIOS was a pre-production BIOS) "fixed" this by
>> > no longer listing an IRQ in the ACPI resources for the TPM.
>> > 
>> > Which means that the new BIOS still being on the deny list
>> > does not matter since the IRQ support won't work anyways as
>> > we no longer get an IRQ assigned.
>> > 
>> > So I don't think this is necessary and it will just complicate
>> > things unnecessarily. This whole saga has already taken way
>> > too long to fix. So IMHO the simplest fix where we just deny
>> > list the broken models independent of BIOS versions and move
>> > on seems best.
>> > 
>> > Regards,
>> > 
>> > Hans
>> 
>> This worked for me:
>> 
>> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
>> index 0b214963539d..abe674d1de6d 100644
>> --- a/drivers/char/tpm/tpm_tis.c
>> +++ b/drivers/char/tpm/tpm_tis.c
>> @@ -27,6 +27,7 @@
>>  #include <linux/of.h>
>>  #include <linux/of_device.h>
>>  #include <linux/kernel.h>
>> +#include <linux/dmi.h>
>>  #include "tpm.h"
>>  #include "tpm_tis_core.h"
>> 
>> @@ -63,6 +64,26 @@ module_param(force, bool, 0444);
>>  MODULE_PARM_DESC(force, "Force device probe rather than using ACPI
>> entry");
>>  #endif
>> 
>> +static int tpm_tis_disable_irq(const struct dmi_system_id *d)
>> +{
>> +       pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d-
>> >ident);
>> +       interrupts = false;
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct dmi_system_id tpm_tis_dmi_table[] = {
>> +       {
>> +               .callback = tpm_tis_disable_irq,
>> +               .ident = "ThinkPad T490s",
>> +               .matches = {
>> +                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> +                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad
>> T490s"),
>> +               },
>> +       },
>> +       {}
>> +};
>> +
>>  #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
>>  static int has_hid(struct acpi_device *dev, const char *hid)
>>  {
>> @@ -192,6 +213,8 @@ static int tpm_tis_init(struct device *dev,
>> struct tpm_info *tpm_info)
>>         int irq = -1;
>>         int rc;
>> 
>> +       dmi_check_system(tpm_tis_dmi_table);
>> +
>>         rc = check_acpi_tpm2(dev);
>>         if (rc)
>>                 return rc;
>
> This looks OK to me with the caveat that anyone on one of these systems
> has no way to enable interrupts again if they think they have a fixed
> bios.  What about making interrupts a tristate with the default value
> -1?  Then in the dmi check, if we see -1 we set it to 0 but if we see 1
> (the user has specified interrupts=1 on the module insert line) we
> leave it?
>
> James

like this?

diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 0b214963539d..10c46cb26c5a 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -27,6 +27,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/kernel.h>
+#include <linux/dmi.h>
 #include "tpm.h"
 #include "tpm_tis_core.h"

@@ -49,8 +50,8 @@ static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *da
        return container_of(data, struct tpm_tis_tcg_phy, priv);
 }

-static bool interrupts = true;
-module_param(interrupts, bool, 0444);
+static int interrupts = -1;
+module_param(interrupts, int, 0444);
 MODULE_PARM_DESC(interrupts, "Enable interrupts");

 static bool itpm;
@@ -63,6 +64,27 @@ module_param(force, bool, 0444);
 MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
 #endif

+static int tpm_tis_disable_irq(const struct dmi_system_id *d)
+{
+       pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d->ident);
+       if (interrupts == -1)
+               interrupts = 0;
+
+       return 0;
+}
+
+static const struct dmi_system_id tpm_tis_dmi_table[] = {
+       {
+               .callback = tpm_tis_disable_irq,
+               .ident = "ThinkPad T490s",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"),
+               },
+       },
+       {}
+};
+
 #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
 static int has_hid(struct acpi_device *dev, const char *hid)
 {
@@ -192,6 +214,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info)
        int irq = -1;
        int rc;

+       dmi_check_system(tpm_tis_dmi_table);
+
        rc = check_acpi_tpm2(dev);
        if (rc)
                return rc;


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-15 18:48                       ` Jerry Snitselaar
@ 2020-10-15 18:57                         ` James Bottomley
  2020-10-15 19:16                           ` Jerry Snitselaar
  0 siblings, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-10-15 18:57 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: Hans de Goede, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede

On Thu, 2020-10-15 at 11:48 -0700, Jerry Snitselaar wrote:
> James Bottomley @ 2020-10-15 08:36 MST:
> 
> > On Wed, 2020-10-14 at 13:58 -0700, Jerry Snitselaar wrote:
> > > Hans de Goede @ 2020-10-14 09:46 MST:
> > > 
> > > > Hi,
> > > > 
> > > > On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
> > > > > Hans de Goede @ 2020-10-14 09:04 MST:
> > > > > 
> > > > > > Hi,
> > > > > > 
> > > > > > On 10/14/20 5:23 PM, James Bottomley wrote:
> > > > > > > On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
> > > > > > > > On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
> > > > > > > > > James Bottomley @ 2020-10-13 08:24 MST:
> > > > > > > > > > On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar
> > > > > > > > > > wrote:
> > > > > > > > > > > Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> > > > > > > [...]
> > > > > > > > > > > >     Jerry, once you have some bandwidth (no
> > > > > > > > > > > > rush,
> > > > > > > > > > > > does not land
> > > > > > > > > > > > before rc2), it would be great that if you
> > > > > > > > > > > > could
> > > > > > > > > > > > try this.
> > > > > > > > > > > > I'm emphasizing this just because of the
> > > > > > > > > > > > intersection. I
> > > > > > > > > > > > think it would also make senset to get tested-
> > > > > > > > > > > > by
> > > > > > > > > > > > from Nayna.
> > > > > > > > > > > 
> > > > > > > > > > > I will run some tests on some other systems I
> > > > > > > > > > > have
> > > > > > > > > > > access to.
> > > > > > > > > > > As noted in the other email I did a quick test
> > > > > > > > > > > with a
> > > > > > > > > > > t490s
> > > > > > > > > > > with an older bios that exhibits the problem
> > > > > > > > > > > originally
> > > > > > > > > > > reported when Stefan's patch enabled interrupts.
> > > > > > > > > > 
> > > > > > > > > > Well, it means there's still some other problem.  I
> > > > > > > > > > was
> > > > > > > > > > hoping
> > > > > > > > > > that because the rainbow pass system originally
> > > > > > > > > > exhibited the
> > > > > > > > > > same symptoms (interrupt storm) fixing it would
> > > > > > > > > > also
> > > > > > > > > > fix the t490
> > > > > > > > > > and the ineffective EOI bug looked like a great
> > > > > > > > > > candidate for
> > > > > > > > > > being the root cause.
> > > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > Adding Hans to the list.
> > > > > > > > > 
> > > > > > > > > IIUC in the t490s case the problem lies with the
> > > > > > > > > hardware
> > > > > > > > > itself.
> > > > > > > > > Hans, is that correct?
> > > > > > > > 
> > > > > > > > More or less. AFAIK / have been told by Lenovo it is an
> > > > > > > > issue with
> > > > > > > > the configuration of the inerrupt-type of the GPIO pin
> > > > > > > > used
> > > > > > > > for the
> > > > > > > > IRQ, which is a firmware issue which could be fixed by
> > > > > > > > a
> > > > > > > > BIOS update
> > > > > > > > (the pin is setup as a direct-irq pin for the APIC, so
> > > > > > > > the
> > > > > > > > OS has no
> > > > > > > > control of the IRQ type since with APIC irqs this is
> > > > > > > > all
> > > > > > > > supposed to
> > > > > > > > be setup properly before hand).
> > > > > > > > 
> > > > > > > > But it is a model specific issue, if we denylist IRQ
> > > > > > > > usage
> > > > > > > > on this
> > > > > > > > Lenovo model (and probably a few others) then we should
> > > > > > > > be
> > > > > > > > able to
> > > > > > > > restore the IRQ code to normal functionality for all
> > > > > > > > other
> > > > > > > > device
> > > > > > > > models which declare an IRQ in their resource tables.
> > > > > > > I can do that with a quirk, but how do I identify the
> > > > > > > device?  TPM
> > > > > > > manufacturer and version? or do I have to use something
> > > > > > > like
> > > > > > > the ACPI
> > > > > > > bios version?
> > > > > > 
> > > > > > I'm not sure if the TPM ids are unique to one model/series
> > > > > > of
> > > > > > laptops.
> > > > > > 
> > > > > > So my idea for this was to match on DMI strings,
> > > > > > specifically
> > > > > > use a DMI match on the DMI_SYS_VENDOR and
> > > > > > DMI_PRODUCT_VERSION
> > > > > > strings (normally one would use DMI_PRODUCT_NAME but for
> > > > > > Lenovo
> > > > > > devices the string which you expect to be in
> > > > > > DMI_PRODUCT_NAME
> > > > > > is actually in DMI_PRODUCT_VERSION).
> > > > > > 
> > > > > > You can easily get the strings for your device by doing:
> > > > > > 
> > > > > > cat /sys/class/dmi/id/sys_vendor
> > > > > > cat /sys/class/dmi/id/product_version
> > > > > > 
> > > > > > Regards,
> > > > > > 
> > > > > > Hans
> > > > > Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
> > > > > if the bios is older than the fixed bios? Has Lenovo
> > > > > released the fixed bios?
> > > > 
> > > > Maybe, the fixed BIOS-es which I have seen (for the X1C8,
> > > > broken BIOS was a pre-production BIOS) "fixed" this by
> > > > no longer listing an IRQ in the ACPI resources for the TPM.
> > > > 
> > > > Which means that the new BIOS still being on the deny list
> > > > does not matter since the IRQ support won't work anyways as
> > > > we no longer get an IRQ assigned.
> > > > 
> > > > So I don't think this is necessary and it will just complicate
> > > > things unnecessarily. This whole saga has already taken way
> > > > too long to fix. So IMHO the simplest fix where we just deny
> > > > list the broken models independent of BIOS versions and move
> > > > on seems best.
> > > > 
> > > > Regards,
> > > > 
> > > > Hans
> > > 
> > > This worked for me:
> > > 
> > > diff --git a/drivers/char/tpm/tpm_tis.c
> > > b/drivers/char/tpm/tpm_tis.c
> > > index 0b214963539d..abe674d1de6d 100644
> > > --- a/drivers/char/tpm/tpm_tis.c
> > > +++ b/drivers/char/tpm/tpm_tis.c
> > > @@ -27,6 +27,7 @@
> > >  #include <linux/of.h>
> > >  #include <linux/of_device.h>
> > >  #include <linux/kernel.h>
> > > +#include <linux/dmi.h>
> > >  #include "tpm.h"
> > >  #include "tpm_tis_core.h"
> > > 
> > > @@ -63,6 +64,26 @@ module_param(force, bool, 0444);
> > >  MODULE_PARM_DESC(force, "Force device probe rather than using
> > > ACPI
> > > entry");
> > >  #endif
> > > 
> > > +static int tpm_tis_disable_irq(const struct dmi_system_id *d)
> > > +{
> > > +       pr_notice("tpm_tis: %s detected: disabling
> > > interrupts.\n", d-
> > > > ident);
> > > +       interrupts = false;
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static const struct dmi_system_id tpm_tis_dmi_table[] = {
> > > +       {
> > > +               .callback = tpm_tis_disable_irq,
> > > +               .ident = "ThinkPad T490s",
> > > +               .matches = {
> > > +                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> > > +                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad
> > > T490s"),
> > > +               },
> > > +       },
> > > +       {}
> > > +};
> > > +
> > >  #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
> > >  static int has_hid(struct acpi_device *dev, const char *hid)
> > >  {
> > > @@ -192,6 +213,8 @@ static int tpm_tis_init(struct device *dev,
> > > struct tpm_info *tpm_info)
> > >         int irq = -1;
> > >         int rc;
> > > 
> > > +       dmi_check_system(tpm_tis_dmi_table);
> > > +
> > >         rc = check_acpi_tpm2(dev);
> > >         if (rc)
> > >                 return rc;
> > 
> > This looks OK to me with the caveat that anyone on one of these
> > systems
> > has no way to enable interrupts again if they think they have a
> > fixed
> > bios.  What about making interrupts a tristate with the default
> > value
> > -1?  Then in the dmi check, if we see -1 we set it to 0 but if we
> > see 1
> > (the user has specified interrupts=1 on the module insert line) we
> > leave it?
> > 
> > James
> 
> like this?

Yes, that works, I think.

Reviewed-by: James Bottomley <James.Bottomley@HansenPartnership.com>

James


> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
> index 0b214963539d..10c46cb26c5a 100644
> --- a/drivers/char/tpm/tpm_tis.c
> +++ b/drivers/char/tpm/tpm_tis.c
> @@ -27,6 +27,7 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/kernel.h>
> +#include <linux/dmi.h>
>  #include "tpm.h"
>  #include "tpm_tis_core.h"
> 
> @@ -49,8 +50,8 @@ static inline struct tpm_tis_tcg_phy
> *to_tpm_tis_tcg_phy(struct tpm_tis_data *da
>         return container_of(data, struct tpm_tis_tcg_phy, priv);
>  }
> 
> -static bool interrupts = true;
> -module_param(interrupts, bool, 0444);
> +static int interrupts = -1;
> +module_param(interrupts, int, 0444);
>  MODULE_PARM_DESC(interrupts, "Enable interrupts");
> 
>  static bool itpm;
> @@ -63,6 +64,27 @@ module_param(force, bool, 0444);
>  MODULE_PARM_DESC(force, "Force device probe rather than using ACPI
> entry");
>  #endif
> 
> +static int tpm_tis_disable_irq(const struct dmi_system_id *d)
> +{
> +       pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d-
> >ident);
> +       if (interrupts == -1)
> +               interrupts = 0;
> +
> +       return 0;
> +}
> +
> +static const struct dmi_system_id tpm_tis_dmi_table[] = {
> +       {
> +               .callback = tpm_tis_disable_irq,
> +               .ident = "ThinkPad T490s",
> +               .matches = {
> +                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
> +                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad
> T490s"),
> +               },
> +       },
> +       {}
> +};
> +
>  #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
>  static int has_hid(struct acpi_device *dev, const char *hid)
>  {
> @@ -192,6 +214,8 @@ static int tpm_tis_init(struct device *dev,
> struct tpm_info *tpm_info)
>         int irq = -1;
>         int rc;
> 
> +       dmi_check_system(tpm_tis_dmi_table);
> +
>         rc = check_acpi_tpm2(dev);
>         if (rc)
>                 return rc;
> 



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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-15 18:57                         ` James Bottomley
@ 2020-10-15 19:16                           ` Jerry Snitselaar
  0 siblings, 0 replies; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-15 19:16 UTC (permalink / raw)
  To: James Bottomley
  Cc: Hans de Goede, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede


James Bottomley @ 2020-10-15 11:57 MST:

> On Thu, 2020-10-15 at 11:48 -0700, Jerry Snitselaar wrote:
>> James Bottomley @ 2020-10-15 08:36 MST:
>> 
>> > On Wed, 2020-10-14 at 13:58 -0700, Jerry Snitselaar wrote:
>> > > Hans de Goede @ 2020-10-14 09:46 MST:
>> > > 
>> > > > Hi,
>> > > > 
>> > > > On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
>> > > > > Hans de Goede @ 2020-10-14 09:04 MST:
>> > > > > 
>> > > > > > Hi,
>> > > > > > 
>> > > > > > On 10/14/20 5:23 PM, James Bottomley wrote:
>> > > > > > > On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
>> > > > > > > > On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
>> > > > > > > > > James Bottomley @ 2020-10-13 08:24 MST:
>> > > > > > > > > > On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar
>> > > > > > > > > > wrote:
>> > > > > > > > > > > Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>> > > > > > > [...]
>> > > > > > > > > > > >     Jerry, once you have some bandwidth (no
>> > > > > > > > > > > > rush,
>> > > > > > > > > > > > does not land
>> > > > > > > > > > > > before rc2), it would be great that if you
>> > > > > > > > > > > > could
>> > > > > > > > > > > > try this.
>> > > > > > > > > > > > I'm emphasizing this just because of the
>> > > > > > > > > > > > intersection. I
>> > > > > > > > > > > > think it would also make senset to get tested-
>> > > > > > > > > > > > by
>> > > > > > > > > > > > from Nayna.
>> > > > > > > > > > > 
>> > > > > > > > > > > I will run some tests on some other systems I
>> > > > > > > > > > > have
>> > > > > > > > > > > access to.
>> > > > > > > > > > > As noted in the other email I did a quick test
>> > > > > > > > > > > with a
>> > > > > > > > > > > t490s
>> > > > > > > > > > > with an older bios that exhibits the problem
>> > > > > > > > > > > originally
>> > > > > > > > > > > reported when Stefan's patch enabled interrupts.
>> > > > > > > > > > 
>> > > > > > > > > > Well, it means there's still some other problem.  I
>> > > > > > > > > > was
>> > > > > > > > > > hoping
>> > > > > > > > > > that because the rainbow pass system originally
>> > > > > > > > > > exhibited the
>> > > > > > > > > > same symptoms (interrupt storm) fixing it would
>> > > > > > > > > > also
>> > > > > > > > > > fix the t490
>> > > > > > > > > > and the ineffective EOI bug looked like a great
>> > > > > > > > > > candidate for
>> > > > > > > > > > being the root cause.
>> > > > > > > > > > 
>> > > > > > > > > 
>> > > > > > > > > Adding Hans to the list.
>> > > > > > > > > 
>> > > > > > > > > IIUC in the t490s case the problem lies with the
>> > > > > > > > > hardware
>> > > > > > > > > itself.
>> > > > > > > > > Hans, is that correct?
>> > > > > > > > 
>> > > > > > > > More or less. AFAIK / have been told by Lenovo it is an
>> > > > > > > > issue with
>> > > > > > > > the configuration of the inerrupt-type of the GPIO pin
>> > > > > > > > used
>> > > > > > > > for the
>> > > > > > > > IRQ, which is a firmware issue which could be fixed by
>> > > > > > > > a
>> > > > > > > > BIOS update
>> > > > > > > > (the pin is setup as a direct-irq pin for the APIC, so
>> > > > > > > > the
>> > > > > > > > OS has no
>> > > > > > > > control of the IRQ type since with APIC irqs this is
>> > > > > > > > all
>> > > > > > > > supposed to
>> > > > > > > > be setup properly before hand).
>> > > > > > > > 
>> > > > > > > > But it is a model specific issue, if we denylist IRQ
>> > > > > > > > usage
>> > > > > > > > on this
>> > > > > > > > Lenovo model (and probably a few others) then we should
>> > > > > > > > be
>> > > > > > > > able to
>> > > > > > > > restore the IRQ code to normal functionality for all
>> > > > > > > > other
>> > > > > > > > device
>> > > > > > > > models which declare an IRQ in their resource tables.
>> > > > > > > I can do that with a quirk, but how do I identify the
>> > > > > > > device?  TPM
>> > > > > > > manufacturer and version? or do I have to use something
>> > > > > > > like
>> > > > > > > the ACPI
>> > > > > > > bios version?
>> > > > > > 
>> > > > > > I'm not sure if the TPM ids are unique to one model/series
>> > > > > > of
>> > > > > > laptops.
>> > > > > > 
>> > > > > > So my idea for this was to match on DMI strings,
>> > > > > > specifically
>> > > > > > use a DMI match on the DMI_SYS_VENDOR and
>> > > > > > DMI_PRODUCT_VERSION
>> > > > > > strings (normally one would use DMI_PRODUCT_NAME but for
>> > > > > > Lenovo
>> > > > > > devices the string which you expect to be in
>> > > > > > DMI_PRODUCT_NAME
>> > > > > > is actually in DMI_PRODUCT_VERSION).
>> > > > > > 
>> > > > > > You can easily get the strings for your device by doing:
>> > > > > > 
>> > > > > > cat /sys/class/dmi/id/sys_vendor
>> > > > > > cat /sys/class/dmi/id/product_version
>> > > > > > 
>> > > > > > Regards,
>> > > > > > 
>> > > > > > Hans
>> > > > > Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
>> > > > > if the bios is older than the fixed bios? Has Lenovo
>> > > > > released the fixed bios?
>> > > > 
>> > > > Maybe, the fixed BIOS-es which I have seen (for the X1C8,
>> > > > broken BIOS was a pre-production BIOS) "fixed" this by
>> > > > no longer listing an IRQ in the ACPI resources for the TPM.
>> > > > 
>> > > > Which means that the new BIOS still being on the deny list
>> > > > does not matter since the IRQ support won't work anyways as
>> > > > we no longer get an IRQ assigned.
>> > > > 
>> > > > So I don't think this is necessary and it will just complicate
>> > > > things unnecessarily. This whole saga has already taken way
>> > > > too long to fix. So IMHO the simplest fix where we just deny
>> > > > list the broken models independent of BIOS versions and move
>> > > > on seems best.
>> > > > 
>> > > > Regards,
>> > > > 
>> > > > Hans
>> > > 
>> > > This worked for me:
>> > > 
>> > > diff --git a/drivers/char/tpm/tpm_tis.c
>> > > b/drivers/char/tpm/tpm_tis.c
>> > > index 0b214963539d..abe674d1de6d 100644
>> > > --- a/drivers/char/tpm/tpm_tis.c
>> > > +++ b/drivers/char/tpm/tpm_tis.c
>> > > @@ -27,6 +27,7 @@
>> > >  #include <linux/of.h>
>> > >  #include <linux/of_device.h>
>> > >  #include <linux/kernel.h>
>> > > +#include <linux/dmi.h>
>> > >  #include "tpm.h"
>> > >  #include "tpm_tis_core.h"
>> > > 
>> > > @@ -63,6 +64,26 @@ module_param(force, bool, 0444);
>> > >  MODULE_PARM_DESC(force, "Force device probe rather than using
>> > > ACPI
>> > > entry");
>> > >  #endif
>> > > 
>> > > +static int tpm_tis_disable_irq(const struct dmi_system_id *d)
>> > > +{
>> > > +       pr_notice("tpm_tis: %s detected: disabling
>> > > interrupts.\n", d-
>> > > > ident);
>> > > +       interrupts = false;
>> > > +
>> > > +       return 0;
>> > > +}
>> > > +
>> > > +static const struct dmi_system_id tpm_tis_dmi_table[] = {
>> > > +       {
>> > > +               .callback = tpm_tis_disable_irq,
>> > > +               .ident = "ThinkPad T490s",
>> > > +               .matches = {
>> > > +                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> > > +                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad
>> > > T490s"),
>> > > +               },
>> > > +       },
>> > > +       {}
>> > > +};
>> > > +
>> > >  #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
>> > >  static int has_hid(struct acpi_device *dev, const char *hid)
>> > >  {
>> > > @@ -192,6 +213,8 @@ static int tpm_tis_init(struct device *dev,
>> > > struct tpm_info *tpm_info)
>> > >         int irq = -1;
>> > >         int rc;
>> > > 
>> > > +       dmi_check_system(tpm_tis_dmi_table);
>> > > +
>> > >         rc = check_acpi_tpm2(dev);
>> > >         if (rc)
>> > >                 return rc;
>> > 
>> > This looks OK to me with the caveat that anyone on one of these
>> > systems
>> > has no way to enable interrupts again if they think they have a
>> > fixed
>> > bios.  What about making interrupts a tristate with the default
>> > value
>> > -1?  Then in the dmi check, if we see -1 we set it to 0 but if we
>> > see 1
>> > (the user has specified interrupts=1 on the module insert line) we
>> > leave it?
>> > 
>> > James
>> 
>> like this?
>
> Yes, that works, I think.
>
> Reviewed-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> James
>

I'll send a real patch in a just a bit. The pr_notice needs to move into the
if block, otherwise it will log that it is disabling interrupts when the
user has forced enabling.

Regards,
Jerry

>
>> diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
>> index 0b214963539d..10c46cb26c5a 100644
>> --- a/drivers/char/tpm/tpm_tis.c
>> +++ b/drivers/char/tpm/tpm_tis.c
>> @@ -27,6 +27,7 @@
>>  #include <linux/of.h>
>>  #include <linux/of_device.h>
>>  #include <linux/kernel.h>
>> +#include <linux/dmi.h>
>>  #include "tpm.h"
>>  #include "tpm_tis_core.h"
>> 
>> @@ -49,8 +50,8 @@ static inline struct tpm_tis_tcg_phy
>> *to_tpm_tis_tcg_phy(struct tpm_tis_data *da
>>         return container_of(data, struct tpm_tis_tcg_phy, priv);
>>  }
>> 
>> -static bool interrupts = true;
>> -module_param(interrupts, bool, 0444);
>> +static int interrupts = -1;
>> +module_param(interrupts, int, 0444);
>>  MODULE_PARM_DESC(interrupts, "Enable interrupts");
>> 
>>  static bool itpm;
>> @@ -63,6 +64,27 @@ module_param(force, bool, 0444);
>>  MODULE_PARM_DESC(force, "Force device probe rather than using ACPI
>> entry");
>>  #endif
>> 
>> +static int tpm_tis_disable_irq(const struct dmi_system_id *d)
>> +{
>> +       pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d-
>> >ident);
>> +       if (interrupts == -1)
>> +               interrupts = 0;
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct dmi_system_id tpm_tis_dmi_table[] = {
>> +       {
>> +               .callback = tpm_tis_disable_irq,
>> +               .ident = "ThinkPad T490s",
>> +               .matches = {
>> +                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> +                       DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad
>> T490s"),
>> +               },
>> +       },
>> +       {}
>> +};
>> +
>>  #if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
>>  static int has_hid(struct acpi_device *dev, const char *hid)
>>  {
>> @@ -192,6 +214,8 @@ static int tpm_tis_init(struct device *dev,
>> struct tpm_info *tpm_info)
>>         int irq = -1;
>>         int rc;
>> 
>> +       dmi_check_system(tpm_tis_dmi_table);
>> +
>>         rc = check_acpi_tpm2(dev);
>>         if (rc)
>>                 return rc;
>> 


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-13  1:23   ` Jarkko Sakkinen
@ 2020-10-18  5:34     ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-18  5:34 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe, Peter Huewe

On Tue, Oct 13, 2020 at 04:23:54AM +0300, Jarkko Sakkinen wrote:
> On Sun, Oct 11, 2020 at 10:39:07PM -0700, Jerry Snitselaar wrote:
> > 
> > James Bottomley @ 2020-10-01 11:09 MST:
> > 
> > > The current state of the TIS TPM is that interrupts have been globally
> > > disabled by various changes.  The problems we got reported the last
> > > time they were enabled was interrupt storms.  With my own TIS TPM,
> > > I've found that this is caused because my TPM doesn't do legacy
> > > cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
> > > requires any TIS TPM without legacy cycles not to act on any write to
> > > an interrupt register unless the locality is enabled.  This means if
> > > an interrupt fires after we relinquish the locality, the TPM_EOI in
> > > the interrupt routine is ineffective meaning the same interrupt
> > > triggers over and over again.  This problem also means we can have
> > > trouble setting up interrupts on TIS TPMs because the current init
> > > code does the setup before the locality is claimed for the first time.
> > >
> > > James
> > >
> > 
> > 
> > I tested initially with the following commits reverted:
> > 
> > aa4a63dd9816 tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's" | 2020-01-06 | (Stefan Berger)
> > dda8b2af395b tpm: Revert "tpm_tis_core: Set TPM_CHIP_FLAG_IRQ before probing for interrupts" | 2020-01-06 | (Stefan Berger)
> > 
> > The laptop doesn't become unusable, but I lose the trackpad and get the following:
> > 
> > [    3.070501] irq 31: nobody cared (try booting with the "irqpoll" option)
> > [    3.070504] CPU: 2 PID: 251 Comm: rngd Not tainted 5.8.13-201.local.fc32.x86_64 #1
> > [    3.070504] Hardware name: LENOVO 20NYS7K90F/20NYS7K90F, BIOS N2JET83W (1.61 ) 11/22/2019
> > [    3.070505] Call Trace:
> > [    3.070511]  dump_stack+0x6b/0x88
> > [    3.070514]  __report_bad_irq+0x35/0xa7
> > [    3.070516]  note_interrupt.cold+0xb/0x6a
> > [    3.070518]  handle_irq_event+0x88/0x8a
> > [    3.070519]  handle_fasteoi_irq+0x78/0x1c0
> > [    3.070522]  common_interrupt+0x68/0x140
> > [    3.070524]  ? asm_common_interrupt+0x8/0x40
> > [    3.070525]  asm_common_interrupt+0x1e/0x40
> > [    3.070527] RIP: 0033:0x7f2eea3249b5
> > [    3.070529] Code: e0 48 c1 e8 3c 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 37 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 1e 83 e0 01 48 31 45 f0 <48> 8b 45 e0 48 c1 e8 1b 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8
> > [    3.070529] RSP: 002b:00007f2ee3ffebc0 EFLAGS: 00000202
> > [    3.070530] RAX: 0000000000000001 RBX: 000000000000000a RCX: 000000000000002e
> > [    3.070531] RDX: 0463400000000000 RSI: 0000000000000000 RDI: 0000000000000001
> > [    3.070532] RBP: 00007f2ee3ffec10 R08: 0000000000000000 R09: 0000000000000035
> > [    3.070532] R10: 00007ffde716f080 R11: 00007ffde716f080 R12: 00007f2edc004c00
> > [    3.070533] R13: 00007ffde700a54f R14: 00007f2ee3ffed10 R15: 00005598a41e3680
> > [    3.070534] handlers:
> > [    3.070537] [<000000007b6f3232>] tis_int_handler
> > [    3.070538] Disabling IRQ #31
> > ...
> > [   14.956342] irq 16: nobody cared (try booting with the "irqpoll" option)
> > [   14.956344] CPU: 0 PID: 1013 Comm: rngd Not tainted 5.8.13-201.local.fc32.x86_64 #1
> > [   14.956344] Hardware name: LENOVO 20NYS7K90F/20NYS7K90F, BIOS N2JET83W (1.61 ) 11/22/2019
> > [   14.956345] Call Trace:
> > [   14.956350]  dump_stack+0x6b/0x88
> > [   14.956353]  __report_bad_irq+0x35/0xa7
> > [   14.956354]  note_interrupt.cold+0xb/0x6a
> > [   14.956355]  handle_irq_event+0x88/0x8a
> > [   14.956356]  handle_fasteoi_irq+0x78/0x1c0
> > [   14.956358]  common_interrupt+0x68/0x140
> > [   14.956360]  ? asm_common_interrupt+0x8/0x40
> > [   14.956361]  asm_common_interrupt+0x1e/0x40
> > [   14.956362] RIP: 0033:0x7fcaff4399d3
> > [   14.956363] Code: e0 48 c1 e8 1e 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 1b 83 e0 01 48 31 45 f0 48 8b 45 e0 48 c1 e8 16 83 e0 01 48 31 45 f0 <48> d1 65 e0 48 8b 45 f0 48 31 45 e0 83 45 d4 01 83 7d d4 40 0f 86
> > [   14.956364] RSP: 002b:00007fcafe544bc0 EFLAGS: 00000246
> > [   14.956364] RAX: 0000000000000000 RBX: 000000000000000a RCX: 0000000000000026
> > [   14.956365] RDX: 000df20000000000 RSI: 0000000000000000 RDI: 0000000000000001
> > [   14.956365] RBP: 00007fcafe544c10 R08: 0000000000000000 R09: 0000000000000035
> > [   14.956366] R10: 00007ffc30bd2080 R11: 00007ffc30bd2080 R12: 00007fcaf0004c00
> > [   14.956366] R13: 00007fcaf0004c00 R14: 00007fcaf0000b60 R15: 0000560216fcf0f2
> > [   14.956367] handlers:
> > [   14.956370] [<0000000024c0571e>] i801_isr [i2c_i801]
> > [   14.956371] Disabling IRQ #16
> > 
> > /proc/interrupts shows:
> > 
> >   16:     100000          0          0          0          0          0          0          0  IR-IO-APIC   16-fasteoi   i801_smbus
> >   31:          0          0     100000          0          0          0          0          0  IR-IO-APIC   31-fasteoi   tpm0
> > 
> > 
> > I also get this behavior with your patchset applied. If I boot with
> > tpm_tis.interrupts=0 it behaves.  The thought from Hans is to look at
> > the dmi info and key off the vendor being Lenovo and bios date to
> > decide if interrupts should be disabled. Since Dan ran also into this
> > with something internal at Intel I don't know if that will be
> > sufficient.
> > 
> > I hope to look over this patchset tomorrow.
> > 
> > Regards,
> > Jerry
> 
> I'm sorry, I received this email only after pulling the latest with fdm.

So, this is the main blocker to take these patches.

/Jarkko

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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-13 15:15   ` Jerry Snitselaar
  2020-10-13 15:24     ` James Bottomley
@ 2020-10-18 21:05     ` Jarkko Sakkinen
  2020-10-20 23:10       ` Jerry Snitselaar
  1 sibling, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-18 21:05 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	James Bottomley, linux-integrity, Jason Gunthorpe, Peter Huewe,
	Borislav Petkov, Nayna Jain

On Tue, Oct 13, 2020 at 08:15:36AM -0700, Jerry Snitselaar wrote:
> 
> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> 
> > On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
> >> The current state of the TIS TPM is that interrupts have been globally
> >> disabled by various changes.  The problems we got reported the last
> >> time they were enabled was interrupt storms.  With my own TIS TPM,
> >> I've found that this is caused because my TPM doesn't do legacy
> >> cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
> >> requires any TIS TPM without legacy cycles not to act on any write to
> >> an interrupt register unless the locality is enabled.  This means if
> >> an interrupt fires after we relinquish the locality, the TPM_EOI in
> >> the interrupt routine is ineffective meaning the same interrupt
> >> triggers over and over again.  This problem also means we can have
> >> trouble setting up interrupts on TIS TPMs because the current init
> >> code does the setup before the locality is claimed for the first time.
> >> 
> >> James
> >
> > You should consider expanding the audience. Jerry, once you have some
> > bandwidth (no rush, does not land before rc2), it would be great that if
> > you could try this. I'm emphasizing this just because of the
> > intersection. I think it would also make senset to get tested-by from
> > Nayna.
> 
> I will run some tests on some other systems I have access to. As noted
> in the other email I did a quick test with a t490s with an older bios
> that exhibits the problem originally reported when Stefan's patch
> enabled interrupts.

Thank you. As said, I can make a pull request to rc2 or even rc3, if
needed.

/Jarkko

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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-15  7:38                     ` Hans de Goede
@ 2020-10-18 21:09                       ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-18 21:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jerry Snitselaar, James Bottomley, equired,
	justmentioningitbecauseIthinkthatwouldbeagood, linux-integrity,
	Jason Gunthorpe, Peter Huewe, Borislav Petkov, Nayna Jain,
	Hans de Goede

On Thu, Oct 15, 2020 at 09:38:24AM +0200, Hans de Goede wrote:
> Hi,
> 
> On 10/14/20 10:58 PM, Jerry Snitselaar wrote:
> > 
> > Hans de Goede @ 2020-10-14 09:46 MST:
> > 
> > > Hi,
> > > 
> > > On 10/14/20 6:34 PM, Jerry Snitselaar wrote:
> > > > Hans de Goede @ 2020-10-14 09:04 MST:
> > > > 
> > > > > Hi,
> > > > > 
> > > > > On 10/14/20 5:23 PM, James Bottomley wrote:
> > > > > > On Wed, 2020-10-14 at 17:03 +0200, Hans de Goede wrote:
> > > > > > > On 10/13/20 6:05 PM, Jerry Snitselaar wrote:
> > > > > > > > James Bottomley @ 2020-10-13 08:24 MST:
> > > > > > > > > On Tue, 2020-10-13 at 08:15 -0700, Jerry Snitselaar wrote:
> > > > > > > > > > Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> > > > > > [...]
> > > > > > > > > > >      Jerry, once you have some bandwidth (no rush, does not land
> > > > > > > > > > > before rc2), it would be great that if you could try this.
> > > > > > > > > > > I'm emphasizing this just because of the intersection. I
> > > > > > > > > > > think it would also make senset to get tested-by from Nayna.
> > > > > > > > > > 
> > > > > > > > > > I will run some tests on some other systems I have access to.
> > > > > > > > > > As noted in the other email I did a quick test with a t490s
> > > > > > > > > > with an older bios that exhibits the problem originally
> > > > > > > > > > reported when Stefan's patch enabled interrupts.
> > > > > > > > > 
> > > > > > > > > Well, it means there's still some other problem.  I was hoping
> > > > > > > > > that because the rainbow pass system originally exhibited the
> > > > > > > > > same symptoms (interrupt storm) fixing it would also fix the t490
> > > > > > > > > and the ineffective EOI bug looked like a great candidate for
> > > > > > > > > being the root cause.
> > > > > > > > > 
> > > > > > > > 
> > > > > > > > Adding Hans to the list.
> > > > > > > > 
> > > > > > > > IIUC in the t490s case the problem lies with the hardware itself.
> > > > > > > > Hans, is that correct?
> > > > > > > 
> > > > > > > More or less. AFAIK / have been told by Lenovo it is an issue with
> > > > > > > the configuration of the inerrupt-type of the GPIO pin used for the
> > > > > > > IRQ, which is a firmware issue which could be fixed by a BIOS update
> > > > > > > (the pin is setup as a direct-irq pin for the APIC, so the OS has no
> > > > > > > control of the IRQ type since with APIC irqs this is all supposed to
> > > > > > > be setup properly before hand).
> > > > > > > 
> > > > > > > But it is a model specific issue, if we denylist IRQ usage on this
> > > > > > > Lenovo model (and probably a few others) then we should be able to
> > > > > > > restore the IRQ code to normal functionality for all other device
> > > > > > > models which declare an IRQ in their resource tables.
> > > > > > I can do that with a quirk, but how do I identify the device?  TPM
> > > > > > manufacturer and version? or do I have to use something like the ACPI
> > > > > > bios version?
> > > > > 
> > > > > I'm not sure if the TPM ids are unique to one model/series of laptops.
> > > > > 
> > > > > So my idea for this was to match on DMI strings, specifically
> > > > > use a DMI match on the DMI_SYS_VENDOR and DMI_PRODUCT_VERSION
> > > > > strings (normally one would use DMI_PRODUCT_NAME but for Lenovo
> > > > > devices the string which you expect to be in DMI_PRODUCT_NAME
> > > > > is actually in DMI_PRODUCT_VERSION).
> > > > > 
> > > > > You can easily get the strings for your device by doing:
> > > > > 
> > > > > cat /sys/class/dmi/id/sys_vendor
> > > > > cat /sys/class/dmi/id/product_version
> > > > > 
> > > > > Regards,
> > > > > 
> > > > > Hans
> > > > Plus use dmi_get_date(DMI_BIOS_DATE,...) to check
> > > > if the bios is older than the fixed bios? Has Lenovo
> > > > released the fixed bios?
> > > 
> > > Maybe, the fixed BIOS-es which I have seen (for the X1C8,
> > > broken BIOS was a pre-production BIOS) "fixed" this by
> > > no longer listing an IRQ in the ACPI resources for the TPM.
> > > 
> > > Which means that the new BIOS still being on the deny list
> > > does not matter since the IRQ support won't work anyways as
> > > we no longer get an IRQ assigned.
> > > 
> > > So I don't think this is necessary and it will just complicate
> > > things unnecessarily. This whole saga has already taken way
> > > too long to fix. So IMHO the simplest fix where we just deny
> > > list the broken models independent of BIOS versions and move
> > > on seems best.
> > > 
> > > Regards,
> > > 
> > > Hans
> > 
> > This worked for me:
> 
> That looks good to me, can you submit this upstream please ?
> 
> If you Cc me I'll give it my Reviewed-by.
> 
> Regards,
> 
> Hans

Yes, this does look like sustainable patch.

PS. Email has been migration ongoing. That's the reason for inconsistent
responses.

/Jarkko

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

* Re: [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's""
  2020-10-01 18:09 ` [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's"" James Bottomley
@ 2020-10-19 20:23   ` Jerry Snitselaar
  2020-10-19 22:54     ` James Bottomley
  2020-10-19 23:40   ` Jerry Snitselaar
  1 sibling, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-19 20:23 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-01 11:09 MST:

> Revert the patch aa4a63dd9816 which stops interrupt probing from
> working, now that it should be safe to allow interrupt probing on all
> systems without incurring interrupt storms.
>
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> ---
>  drivers/char/tpm/tpm_tis_core.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 12b657ed3a39..23b60583928b 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -1117,6 +1117,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>  			goto out_err;
>  		}
>  
> +		tpm_chip_start(chip);
>  		if (irq) {
>  			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
>  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
> @@ -1128,6 +1129,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>  		} else {
>  			tpm_tis_probe_irq(chip);
>  		}
> +		tpm_chip_stop(chip);
>  	}
>  
>  	rc = tpm_chip_register(chip);

I know this is a revert, but should there be a commit on top of this to
move the tpm_chip_start above the tpm_get_timeouts right before this?

Regards,
Jerry


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

* Re: [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's""
  2020-10-19 20:23   ` Jerry Snitselaar
@ 2020-10-19 22:54     ` James Bottomley
  0 siblings, 0 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-19 22:54 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe

On Mon, 2020-10-19 at 13:23 -0700, Jerry Snitselaar wrote:
> James Bottomley @ 2020-10-01 11:09 MST:
> 
> > Revert the patch aa4a63dd9816 which stops interrupt probing from
> > working, now that it should be safe to allow interrupt probing on
> > all
> > systems without incurring interrupt storms.
> > 
> > Signed-off-by: James Bottomley <
> > James.Bottomley@HansenPartnership.com>
> > ---
> >  drivers/char/tpm/tpm_tis_core.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/char/tpm/tpm_tis_core.c
> > b/drivers/char/tpm/tpm_tis_core.c
> > index 12b657ed3a39..23b60583928b 100644
> > --- a/drivers/char/tpm/tpm_tis_core.c
> > +++ b/drivers/char/tpm/tpm_tis_core.c
> > @@ -1117,6 +1117,7 @@ int tpm_tis_core_init(struct device *dev,
> > struct tpm_tis_data *priv, int irq,
> >  			goto out_err;
> >  		}
> >  
> > +		tpm_chip_start(chip);
> >  		if (irq) {
> >  			tpm_tis_probe_irq_single(chip, IRQF_SHARED,
> > irq);
> >  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
> > @@ -1128,6 +1129,7 @@ int tpm_tis_core_init(struct device *dev,
> > struct tpm_tis_data *priv, int irq,
> >  		} else {
> >  			tpm_tis_probe_irq(chip);
> >  		}
> > +		tpm_chip_stop(chip);
> >  	}
> >  
> >  	rc = tpm_chip_register(chip);
> 
> I know this is a revert, but should there be a commit on top of this
> to move the tpm_chip_start above the tpm_get_timeouts right before
> this?

Not for tpm 2: tpm2_get_timeouts doesn't actually query the device.  I
think this may be required for TPM 1.2 since it does send a
capabilities, but I don't actually know if any TPM 1.2 systems have the
ineffective locality problem this fix addresses (I don't have one to
check) ... I'm guessing not otherwise we'd have had bug reports about
TPM 1.2 failing to get the timeouts (it dumps an error message to the
logs).

James



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

* Re: [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition
  2020-10-01 18:09 ` [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition James Bottomley
  2020-10-05 15:34   ` Jarkko Sakkinen
@ 2020-10-19 23:16   ` Jerry Snitselaar
  2020-10-24 12:07     ` Jarkko Sakkinen
  1 sibling, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-19 23:16 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-01 11:09 MST:

> The TPM TIS specification says the TPM signals the acquisition of
> locality when the TMP_ACCESS_REQUEST_USE bit goes to one *and* the
> TPM_ACCESS_REQUEST_USE bit goes to zero.  Currently we only check the
> former not the latter, so check both.  Adding the check on
> TPM_ACCESS_REQUEST_USE should fix the case where the locality is
> re-requested before the TPM has released it.  In this case the
> locality may get released briefly before it is reacquired, which
> causes all sorts of problems. However, with the added check,
> TPM_ACCESS_REQUEST_USE should remain 1 until the second request for
> the locality is granted.
>
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> ---
>
> v2: added this patch
> ---
>  drivers/char/tpm/tpm_tis_core.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 92c51c6cfd1b..f3ecde8df47d 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -125,7 +125,8 @@ static bool check_locality(struct tpm_chip *chip, int l)
>  	if (rc < 0)
>  		return false;
>  
> -	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
> +	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID
> +		       | TPM_ACCESS_REQUEST_USE)) ==
>  	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
>  		priv->locality = l;
>  		return true;

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-01 18:09 ` [PATCH v2 2/5] tpm_tis: Clean up locality release James Bottomley
  2020-10-05 17:02   ` Jarkko Sakkinen
  2020-10-05 17:03   ` Jarkko Sakkinen
@ 2020-10-19 23:17   ` Jerry Snitselaar
  2020-10-24 12:10     ` Jarkko Sakkinen
  2 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-19 23:17 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-01 11:09 MST:

> The current release locality code seems to be based on the
> misunderstanding that the TPM interrupts when a locality is released:
> it doesn't, only when the locality is acquired.
>
> Furthermore, there seems to be no point in waiting for the locality to
> be released.  All it does is penalize the last TPM user.  However, if
> there's no next TPM user, this is a pointless wait and if there is a
> next TPM user, they'll pay the penalty waiting for the new locality
> (or possibly not if it's the same as the old locality).
>
> Fix the code by making release_locality as simple write to release
> with no waiting for completion.
>
> Fixes: 33bafe90824b ("tpm_tis: verify locality released before returning from release_locality")
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> ---
>
> v2: added fixes
> ---
>  drivers/char/tpm/tpm_tis_core.c | 47 +--------------------------------
>  1 file changed, 1 insertion(+), 46 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index f3ecde8df47d..431919d5f48a 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -135,58 +135,13 @@ static bool check_locality(struct tpm_chip *chip, int l)
>  	return false;
>  }
>  
> -static bool locality_inactive(struct tpm_chip *chip, int l)
> -{
> -	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> -	int rc;
> -	u8 access;
> -
> -	rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
> -	if (rc < 0)
> -		return false;
> -
> -	if ((access & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
> -	    == TPM_ACCESS_VALID)
> -		return true;
> -
> -	return false;
> -}
> -
>  static int release_locality(struct tpm_chip *chip, int l)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> -	unsigned long stop, timeout;
> -	long rc;
>  
>  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
>  
> -	stop = jiffies + chip->timeout_a;
> -
> -	if (chip->flags & TPM_CHIP_FLAG_IRQ) {
> -again:
> -		timeout = stop - jiffies;
> -		if ((long)timeout <= 0)
> -			return -1;
> -
> -		rc = wait_event_interruptible_timeout(priv->int_queue,
> -						      (locality_inactive(chip, l)),
> -						      timeout);
> -
> -		if (rc > 0)
> -			return 0;
> -
> -		if (rc == -ERESTARTSYS && freezing(current)) {
> -			clear_thread_flag(TIF_SIGPENDING);
> -			goto again;
> -		}
> -	} else {
> -		do {
> -			if (locality_inactive(chip, l))
> -				return 0;
> -			tpm_msleep(TPM_TIMEOUT);
> -		} while (time_before(jiffies, stop));
> -	}
> -	return -1;
> +	return 0;
>  }
>  
>  static int request_locality(struct tpm_chip *chip, int l)

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


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

* Re: [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's""
  2020-10-01 18:09 ` [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's"" James Bottomley
  2020-10-19 20:23   ` Jerry Snitselaar
@ 2020-10-19 23:40   ` Jerry Snitselaar
  1 sibling, 0 replies; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-19 23:40 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-01 11:09 MST:

> Revert the patch aa4a63dd9816 which stops interrupt probing from
> working, now that it should be safe to allow interrupt probing on all
> systems without incurring interrupt storms.
>
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> ---
>  drivers/char/tpm/tpm_tis_core.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 12b657ed3a39..23b60583928b 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -1117,6 +1117,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>  			goto out_err;
>  		}
>  
> +		tpm_chip_start(chip);
>  		if (irq) {
>  			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
>  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
> @@ -1128,6 +1129,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>  		} else {
>  			tpm_tis_probe_irq(chip);
>  		}
> +		tpm_chip_stop(chip);
>  	}
>  
>  	rc = tpm_chip_register(chip);


Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-01 18:09 ` [PATCH v2 4/5] tpm_tis: fix IRQ probing James Bottomley
  2020-10-05 17:05   ` Jarkko Sakkinen
@ 2020-10-19 23:41   ` Jerry Snitselaar
  2020-10-24 12:17     ` Jarkko Sakkinen
  1 sibling, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-19 23:41 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-01 11:09 MST:

> There are two problems with our current interrupt probing: firstly the
> TPM_CHIP_FLAG_IRQ never gets set initially, so a check for interrupts
> is never done.  Fix this by setting the flag before we generate and
> interrupt for probing.  Secondly our IRQ setup may be ineffective on a
> TPM without legacy access cycles becuase according to the TPM
> Interface Specification the interrupt registers are only writeable in
> the current locality, so issue a request_locality before setting up
> the interrupts.
>
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> ---
>
> v2: improved description
> ---
>  drivers/char/tpm/tpm_tis_core.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 0c07da8cd680..12b657ed3a39 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -809,6 +809,19 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
>  	}
>  	priv->irq = irq;
>  
> +	/*
> +	 * note writes to the interrupt registers are only effective
> +	 * when the TPM is in the active locality, so we have to
> +	 * request the locality here to get the interrupt set up.
> +	 * This request has no corresponding release, because the
> +	 * locality will be relinquished at the end of the tpm command
> +	 * that probes the interrupts
> +	 */
> +	if (request_locality(chip, 0) != 0) {
> +		dev_err(&chip->dev, "failed to gain locality for irq probe\n");
> +		return -EBUSY;
> +	}
> +
>  	rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
>  			   &original_int_vec);
>  	if (rc < 0)
> @@ -836,6 +849,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
>  		return rc;
>  
>  	priv->irq_tested = false;
> +	chip->flags |= TPM_CHIP_FLAG_IRQ;
>  
>  	/* Generate an interrupt by having the core call through to
>  	 * tpm_tis_send

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-10-01 18:09 ` [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles James Bottomley
  2020-10-05 17:05   ` Jarkko Sakkinen
@ 2020-10-20  0:14   ` Jerry Snitselaar
  2020-10-24 12:15     ` Jarkko Sakkinen
  2020-12-01 18:12   ` Jerry Snitselaar
  2 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-20  0:14 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-01 11:09 MST:

> If a TIS TPM doesn't have legacy cycles, any write to the interrupt
> registers is ignored unless a locality is active.  This means even to
> set up the interrupt vectors a locality must first be activated.  Fix
> this by activating the 0 locality in the interrupt probe setup.
>
> Since the TPM_EOI signalling also requires an active locality, the
> interrupt routine cannot end an interrupt if the locality is released.
> This can lead to a situation where the TPM goes command ready after
> locality release and since the interrupt cannot be ended it refires
> continuously.  Fix this by disabling all interrupts except locality
> change when a locality is released (this only fires when a locality
> becomes active, meaning the TPM_EOI should work).
>
> Finally, since we now disable all status based interrupts in the
> locality release, they must be re-enabled before waiting to check the
> condition, so add interrupt enabling to the status wait.
>
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> ---
>
> v2: renamed functions
> ---
>  drivers/char/tpm/tpm_tis_core.c | 125 ++++++++++++++++++++++++++------
>  1 file changed, 101 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 431919d5f48a..0c07da8cd680 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -29,6 +29,46 @@
>  
>  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
>  
> +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8 mask)
> +{
> +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> +	u32 intmask;
> +
> +	/* Take control of the TPM's interrupt hardware and shut it off */

s/shut it off/turn it on/ ?

> +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> +
> +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
> +
> +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> +}
> +
> +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8 mask)
> +{
> +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> +	u32 intmask;
> +
> +	/* Take control of the TPM's interrupt hardware and shut it off */
> +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> +
> +	intmask &= ~mask;
> +
> +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> +}
> +
> +static void tpm_tis_enable_stat_interrupts(struct tpm_chip *chip, u8 stat)
> +{
> +	u32 mask = 0;
> +
> +	if (stat & TPM_STS_COMMAND_READY)
> +		mask |= TPM_INTF_CMD_READY_INT;
> +	if (stat & TPM_STS_VALID)
> +		mask |= TPM_INTF_STS_VALID_INT;
> +	if (stat & TPM_STS_DATA_AVAIL)
> +		mask |= TPM_INTF_DATA_AVAIL_INT;
> +
> +	tpm_tis_enable_interrupt(chip, mask);
> +}
> +
>  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
>  					bool check_cancel, bool *canceled)
>  {
> @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
>  		timeout = stop - jiffies;
>  		if ((long)timeout <= 0)
>  			return -ETIME;
> +		tpm_tis_enable_stat_interrupts(chip, mask);
>  		rc = wait_event_interruptible_timeout(*queue,
>  			wait_for_tpm_stat_cond(chip, mask, check_cancel,
>  					       &canceled),
>  			timeout);
>  		if (rc > 0) {
> +			if (rc == 1)
> +				dev_err(&chip->dev, "Lost Interrupt waiting for TPM stat\n");
>  			if (canceled)
>  				return -ECANCELED;
>  			return 0;
> @@ -138,6 +181,28 @@ static bool check_locality(struct tpm_chip *chip, int l)
>  static int release_locality(struct tpm_chip *chip, int l)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> +	u32 int_status;
> +	int rc;
> +
> +	/*
> +	 * Note that once we relinquish the locality, all writes to
> +	 * the interrupt registers become ineffective meaning we can't
> +	 * do a TPM_EOI.  This means we must disable every interrupt
> +	 * except the locality change one to avoid interrupt
> +	 * storms.
> +	 */
> +	tpm_tis_disable_interrupt(chip, TPM_INTF_CMD_READY_INT
> +				  | TPM_INTF_STS_VALID_INT
> +				  | TPM_INTF_DATA_AVAIL_INT);
> +
> +	rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
> +	if (rc < 0)
> +		return rc;
> +
> +	/* Clear all pending */
> +	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
> +	if (rc < 0)
> +		return rc;
>  
>  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
>  
> @@ -164,12 +229,17 @@ static int request_locality(struct tpm_chip *chip, int l)
>  		timeout = stop - jiffies;
>  		if ((long)timeout <= 0)
>  			return -1;
> +
>  		rc = wait_event_interruptible_timeout(priv->int_queue,
>  						      (check_locality
>  						       (chip, l)),
>  						      timeout);
> -		if (rc > 0)
> +		if (rc > 1)
> +			return l;
> +		if (rc == 1) {
> +			dev_info(&chip->dev, "Lost Interrupt waiting for locality\n");
>  			return l;
> +		}
>  		if (rc == -ERESTARTSYS && freezing(current)) {
>  			clear_thread_flag(TIF_SIGPENDING);
>  			goto again;
> @@ -465,6 +535,10 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  	irq = priv->irq;
>  	priv->irq = 0;
>  	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> +	tpm_tis_enable_interrupt(chip, TPM_INTF_CMD_READY_INT
> +				 | TPM_INTF_LOCALITY_CHANGE_INT
> +				 | TPM_INTF_DATA_AVAIL_INT
> +				 | TPM_INTF_STS_VALID_INT);
>  	rc = tpm_tis_send_main(chip, buf, len);
>  	priv->irq = irq;
>  	chip->flags |= TPM_CHIP_FLAG_IRQ;
> @@ -719,7 +793,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
>   * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
>   * everything and leave in polling mode. Returns 0 on success.
>   */
> -static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> +static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
>  				    int flags, int irq)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> @@ -753,9 +827,11 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
>  	if (rc < 0)
>  		return rc;
>  
> -	/* Turn on */
> -	rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
> -			     intmask | TPM_GLOBAL_INT_ENABLE);
> +	/*
> +	 * Turn on.  The locality change interrupt is the only one
> +	 * always enabled
> +	 */
> +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
>  	if (rc < 0)
>  		return rc;
>  
> @@ -787,7 +863,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
>   * do not have ACPI/etc. We typically expect the interrupt to be declared if
>   * present.
>   */
> -static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
> +static void tpm_tis_probe_irq(struct tpm_chip *chip)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>  	u8 original_int_vec;
> @@ -801,11 +877,9 @@ static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
>  	if (!original_int_vec) {
>  		if (IS_ENABLED(CONFIG_X86))
>  			for (i = 3; i <= 15; i++)
> -				if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> -							      i))
> +				if (!tpm_tis_probe_irq_single(chip, 0, i))
>  					return;
> -	} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> -					     original_int_vec))
> +	} else if (!tpm_tis_probe_irq_single(chip, 0, original_int_vec))
>  		return;
>  }
>  
> @@ -1030,8 +1104,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>  		}
>  
>  		if (irq) {
> -			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
> -						 irq);
> +			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
>  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
>  				dev_err(&chip->dev, FW_BUG
>  					"TPM interrupt not working, polling instead\n");
> @@ -1039,7 +1112,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>  				disable_interrupts(chip);
>  			}
>  		} else {
> -			tpm_tis_probe_irq(chip, intmask);
> +			tpm_tis_probe_irq(chip);
>  		}
>  	}
>  
> @@ -1065,12 +1138,23 @@ EXPORT_SYMBOL_GPL(tpm_tis_core_init);
>  static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> -	u32 intmask;
>  	int rc;
>  
>  	if (chip->ops->clk_enable != NULL)
>  		chip->ops->clk_enable(chip, true);
>  
> +	/*
> +	 * must have the locality before we can enable interrupts, so
> +	 * poll for the locality being ready
> +	 */
> +	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> +	if (request_locality(chip, 0) != 0) {
> +		dev_err(&chip->dev, "Failed to enable interrupts after suspend\n");
> +		goto out;
> +	}
> +	chip->flags |= TPM_CHIP_FLAG_IRQ;
> +
> +
>  	/* reenable interrupts that device may have lost or
>  	 * BIOS/firmware may have disabled
>  	 */
> @@ -1078,17 +1162,10 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
>  	if (rc < 0)
>  		goto out;
>  
> -	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> -	if (rc < 0)
> -		goto out;
> -
> -	intmask |= TPM_INTF_CMD_READY_INT
> -	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
> -	    | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
> +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
>  
> -	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> -
> -out:
> + out:
> +	release_locality(chip, 0);
>  	if (chip->ops->clk_enable != NULL)
>  		chip->ops->clk_enable(chip, false);

Other than the question about the comment in tpm_tis_enable_interrupt

Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-18 21:05     ` Jarkko Sakkinen
@ 2020-10-20 23:10       ` Jerry Snitselaar
  2020-10-24 12:20         ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-20 23:10 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	James Bottomley, linux-integrity, Jason Gunthorpe, Peter Huewe,
	Borislav Petkov, Nayna Jain


Jarkko Sakkinen @ 2020-10-18 14:05 MST:

> On Tue, Oct 13, 2020 at 08:15:36AM -0700, Jerry Snitselaar wrote:
>> 
>> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>> 
>> > On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
>> >> The current state of the TIS TPM is that interrupts have been globally
>> >> disabled by various changes.  The problems we got reported the last
>> >> time they were enabled was interrupt storms.  With my own TIS TPM,
>> >> I've found that this is caused because my TPM doesn't do legacy
>> >> cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
>> >> requires any TIS TPM without legacy cycles not to act on any write to
>> >> an interrupt register unless the locality is enabled.  This means if
>> >> an interrupt fires after we relinquish the locality, the TPM_EOI in
>> >> the interrupt routine is ineffective meaning the same interrupt
>> >> triggers over and over again.  This problem also means we can have
>> >> trouble setting up interrupts on TIS TPMs because the current init
>> >> code does the setup before the locality is claimed for the first time.
>> >> 
>> >> James
>> >
>> > You should consider expanding the audience. Jerry, once you have some
>> > bandwidth (no rush, does not land before rc2), it would be great that if
>> > you could try this. I'm emphasizing this just because of the
>> > intersection. I think it would also make senset to get tested-by from
>> > Nayna.
>> 
>> I will run some tests on some other systems I have access to. As noted
>> in the other email I did a quick test with a t490s with an older bios
>> that exhibits the problem originally reported when Stefan's patch
>> enabled interrupts.
>
> Thank you. As said, I can make a pull request to rc2 or even rc3, if
> needed.
>
> /Jarkko

So outside of the t490s I have access to, it looks like the nuc5 with
tpm2.0 device, and and older lenovo D30 with a tpm1.2 device both are
not using interrupts. I'm digging around to see if I can find some
other systems that I can test interrupts on.

Regards,
Jerry


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

* Re: [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition
  2020-10-19 23:16   ` Jerry Snitselaar
@ 2020-10-24 12:07     ` Jarkko Sakkinen
  2020-10-30 12:13       ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-24 12:07 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Mon, Oct 19, 2020 at 04:16:32PM -0700, Jerry Snitselaar wrote:
> 
> James Bottomley @ 2020-10-01 11:09 MST:
> 
> > The TPM TIS specification says the TPM signals the acquisition of
> > locality when the TMP_ACCESS_REQUEST_USE bit goes to one *and* the
> > TPM_ACCESS_REQUEST_USE bit goes to zero.  Currently we only check the
> > former not the latter, so check both.  Adding the check on
> > TPM_ACCESS_REQUEST_USE should fix the case where the locality is
> > re-requested before the TPM has released it.  In this case the
> > locality may get released briefly before it is reacquired, which
> > causes all sorts of problems. However, with the added check,
> > TPM_ACCESS_REQUEST_USE should remain 1 until the second request for
> > the locality is granted.
> >
> > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> >
> > ---
> >
> > v2: added this patch
> > ---
> >  drivers/char/tpm/tpm_tis_core.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > index 92c51c6cfd1b..f3ecde8df47d 100644
> > --- a/drivers/char/tpm/tpm_tis_core.c
> > +++ b/drivers/char/tpm/tpm_tis_core.c
> > @@ -125,7 +125,8 @@ static bool check_locality(struct tpm_chip *chip, int l)
> >  	if (rc < 0)
> >  		return false;
> >  
> > -	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
> > +	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID
> > +		       | TPM_ACCESS_REQUEST_USE)) ==
> >  	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
> >  		priv->locality = l;
> >  		return true;
> 
> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>

Thank you.

James, few minor remarks.

Given that the failing commit is in the GIT, just for reference

  Fixes: 27084efee0c3 ("[PATCH] tpm: driver for next generation TPM chips")
  Cc: stable@ger.kernel.org

I want fixes tags for everything that has a legit Git commit, even
if it spans through all the existing stable kernels. It's valuable
information to have in the Git log.

Another thing I noticed is that would be less ugly put everything
in the same line, as checkpatch requirement have been relaxed.

Finally, please put a verbose inline comment before the condition.
tpm_tis driver is complicated enough that it should be better
documented. After months pass things tend to fade away and wrong
decisions might be made because of that. You can probably derive
it from the already nice and verbose commit message, so let's
take advantage of it.

About recent debate on patch changelogs. I talked with Dave Hansen
about this, and he said that in x86 tree, they are the standard, but
the practice depends per tree.

After thinking about this, and writing per patch changelogs for the
next iteration of the SGX patch set, my standing point is that either
works as it is properly written and maintained.

/Jarkko

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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-19 23:17   ` Jerry Snitselaar
@ 2020-10-24 12:10     ` Jarkko Sakkinen
  2020-10-30 12:17       ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-24 12:10 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Mon, Oct 19, 2020 at 04:17:59PM -0700, Jerry Snitselaar wrote:
> 
> James Bottomley @ 2020-10-01 11:09 MST:
> 
> > The current release locality code seems to be based on the
> > misunderstanding that the TPM interrupts when a locality is released:
> > it doesn't, only when the locality is acquired.
> >
> > Furthermore, there seems to be no point in waiting for the locality to
> > be released.  All it does is penalize the last TPM user.  However, if
> > there's no next TPM user, this is a pointless wait and if there is a
> > next TPM user, they'll pay the penalty waiting for the new locality
> > (or possibly not if it's the same as the old locality).
> >
> > Fix the code by making release_locality as simple write to release
> > with no waiting for completion.
> >
> > Fixes: 33bafe90824b ("tpm_tis: verify locality released before returning from release_locality")
> > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> >
> > ---
> >
> > v2: added fixes
> > ---
> >  drivers/char/tpm/tpm_tis_core.c | 47 +--------------------------------
> >  1 file changed, 1 insertion(+), 46 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > index f3ecde8df47d..431919d5f48a 100644
> > --- a/drivers/char/tpm/tpm_tis_core.c
> > +++ b/drivers/char/tpm/tpm_tis_core.c
> > @@ -135,58 +135,13 @@ static bool check_locality(struct tpm_chip *chip, int l)
> >  	return false;
> >  }
> >  
> > -static bool locality_inactive(struct tpm_chip *chip, int l)
> > -{
> > -	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > -	int rc;
> > -	u8 access;
> > -
> > -	rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
> > -	if (rc < 0)
> > -		return false;
> > -
> > -	if ((access & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
> > -	    == TPM_ACCESS_VALID)
> > -		return true;
> > -
> > -	return false;
> > -}
> > -
> >  static int release_locality(struct tpm_chip *chip, int l)
> >  {
> >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > -	unsigned long stop, timeout;
> > -	long rc;
> >  
> >  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
> >  
> > -	stop = jiffies + chip->timeout_a;
> > -
> > -	if (chip->flags & TPM_CHIP_FLAG_IRQ) {
> > -again:
> > -		timeout = stop - jiffies;
> > -		if ((long)timeout <= 0)
> > -			return -1;
> > -
> > -		rc = wait_event_interruptible_timeout(priv->int_queue,
> > -						      (locality_inactive(chip, l)),
> > -						      timeout);
> > -
> > -		if (rc > 0)
> > -			return 0;
> > -
> > -		if (rc == -ERESTARTSYS && freezing(current)) {
> > -			clear_thread_flag(TIF_SIGPENDING);
> > -			goto again;
> > -		}
> > -	} else {
> > -		do {
> > -			if (locality_inactive(chip, l))
> > -				return 0;
> > -			tpm_msleep(TPM_TIMEOUT);
> > -		} while (time_before(jiffies, stop));
> > -	}
> > -	return -1;
> > +	return 0;
> >  }
> >  
> >  static int request_locality(struct tpm_chip *chip, int l)
> 
> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>

Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

/Jarkko

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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-10-20  0:14   ` Jerry Snitselaar
@ 2020-10-24 12:15     ` Jarkko Sakkinen
  2020-10-30 12:18       ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-24 12:15 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Mon, Oct 19, 2020 at 05:14:26PM -0700, Jerry Snitselaar wrote:
> 
> James Bottomley @ 2020-10-01 11:09 MST:
> 
> > If a TIS TPM doesn't have legacy cycles, any write to the interrupt
> > registers is ignored unless a locality is active.  This means even to
> > set up the interrupt vectors a locality must first be activated.  Fix
> > this by activating the 0 locality in the interrupt probe setup.
> >
> > Since the TPM_EOI signalling also requires an active locality, the
> > interrupt routine cannot end an interrupt if the locality is released.
> > This can lead to a situation where the TPM goes command ready after
> > locality release and since the interrupt cannot be ended it refires
> > continuously.  Fix this by disabling all interrupts except locality
> > change when a locality is released (this only fires when a locality
> > becomes active, meaning the TPM_EOI should work).
> >
> > Finally, since we now disable all status based interrupts in the
> > locality release, they must be re-enabled before waiting to check the
> > condition, so add interrupt enabling to the status wait.
> >
> > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> >
> > ---
> >
> > v2: renamed functions
> > ---
> >  drivers/char/tpm/tpm_tis_core.c | 125 ++++++++++++++++++++++++++------
> >  1 file changed, 101 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > index 431919d5f48a..0c07da8cd680 100644
> > --- a/drivers/char/tpm/tpm_tis_core.c
> > +++ b/drivers/char/tpm/tpm_tis_core.c
> > @@ -29,6 +29,46 @@
> >  
> >  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
> >  
> > +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8 mask)
> > +{
> > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > +	u32 intmask;
> > +
> > +	/* Take control of the TPM's interrupt hardware and shut it off */
> 
> s/shut it off/turn it on/ ?
> 
> > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> > +
> > +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
> > +
> > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> > +}
> > +
> > +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8 mask)
> > +{
> > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > +	u32 intmask;
> > +
> > +	/* Take control of the TPM's interrupt hardware and shut it off */
> > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> > +
> > +	intmask &= ~mask;
> > +
> > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> > +}
> > +
> > +static void tpm_tis_enable_stat_interrupts(struct tpm_chip *chip, u8 stat)
> > +{
> > +	u32 mask = 0;
> > +
> > +	if (stat & TPM_STS_COMMAND_READY)
> > +		mask |= TPM_INTF_CMD_READY_INT;
> > +	if (stat & TPM_STS_VALID)
> > +		mask |= TPM_INTF_STS_VALID_INT;
> > +	if (stat & TPM_STS_DATA_AVAIL)
> > +		mask |= TPM_INTF_DATA_AVAIL_INT;
> > +
> > +	tpm_tis_enable_interrupt(chip, mask);
> > +}
> > +
> >  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
> >  					bool check_cancel, bool *canceled)
> >  {
> > @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
> >  		timeout = stop - jiffies;
> >  		if ((long)timeout <= 0)
> >  			return -ETIME;
> > +		tpm_tis_enable_stat_interrupts(chip, mask);
> >  		rc = wait_event_interruptible_timeout(*queue,
> >  			wait_for_tpm_stat_cond(chip, mask, check_cancel,
> >  					       &canceled),
> >  			timeout);
> >  		if (rc > 0) {
> > +			if (rc == 1)
> > +				dev_err(&chip->dev, "Lost Interrupt waiting for TPM stat\n");
> >  			if (canceled)
> >  				return -ECANCELED;
> >  			return 0;
> > @@ -138,6 +181,28 @@ static bool check_locality(struct tpm_chip *chip, int l)
> >  static int release_locality(struct tpm_chip *chip, int l)
> >  {
> >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > +	u32 int_status;
> > +	int rc;
> > +
> > +	/*
> > +	 * Note that once we relinquish the locality, all writes to
> > +	 * the interrupt registers become ineffective meaning we can't
> > +	 * do a TPM_EOI.  This means we must disable every interrupt
> > +	 * except the locality change one to avoid interrupt
> > +	 * storms.
> > +	 */
> > +	tpm_tis_disable_interrupt(chip, TPM_INTF_CMD_READY_INT
> > +				  | TPM_INTF_STS_VALID_INT
> > +				  | TPM_INTF_DATA_AVAIL_INT);
> > +
> > +	rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
> > +	if (rc < 0)
> > +		return rc;
> > +
> > +	/* Clear all pending */
> > +	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
> > +	if (rc < 0)
> > +		return rc;
> >  
> >  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
> >  
> > @@ -164,12 +229,17 @@ static int request_locality(struct tpm_chip *chip, int l)
> >  		timeout = stop - jiffies;
> >  		if ((long)timeout <= 0)
> >  			return -1;
> > +
> >  		rc = wait_event_interruptible_timeout(priv->int_queue,
> >  						      (check_locality
> >  						       (chip, l)),
> >  						      timeout);
> > -		if (rc > 0)
> > +		if (rc > 1)
> > +			return l;
> > +		if (rc == 1) {
> > +			dev_info(&chip->dev, "Lost Interrupt waiting for locality\n");
> >  			return l;
> > +		}
> >  		if (rc == -ERESTARTSYS && freezing(current)) {
> >  			clear_thread_flag(TIF_SIGPENDING);
> >  			goto again;
> > @@ -465,6 +535,10 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
> >  	irq = priv->irq;
> >  	priv->irq = 0;
> >  	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> > +	tpm_tis_enable_interrupt(chip, TPM_INTF_CMD_READY_INT
> > +				 | TPM_INTF_LOCALITY_CHANGE_INT
> > +				 | TPM_INTF_DATA_AVAIL_INT
> > +				 | TPM_INTF_STS_VALID_INT);
> >  	rc = tpm_tis_send_main(chip, buf, len);
> >  	priv->irq = irq;
> >  	chip->flags |= TPM_CHIP_FLAG_IRQ;
> > @@ -719,7 +793,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
> >   * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
> >   * everything and leave in polling mode. Returns 0 on success.
> >   */
> > -static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> > +static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
> >  				    int flags, int irq)
> >  {
> >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > @@ -753,9 +827,11 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> >  	if (rc < 0)
> >  		return rc;
> >  
> > -	/* Turn on */
> > -	rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
> > -			     intmask | TPM_GLOBAL_INT_ENABLE);
> > +	/*
> > +	 * Turn on.  The locality change interrupt is the only one
> > +	 * always enabled
> > +	 */
> > +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
> >  	if (rc < 0)
> >  		return rc;
> >  
> > @@ -787,7 +863,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> >   * do not have ACPI/etc. We typically expect the interrupt to be declared if
> >   * present.
> >   */
> > -static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
> > +static void tpm_tis_probe_irq(struct tpm_chip *chip)
> >  {
> >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> >  	u8 original_int_vec;
> > @@ -801,11 +877,9 @@ static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
> >  	if (!original_int_vec) {
> >  		if (IS_ENABLED(CONFIG_X86))
> >  			for (i = 3; i <= 15; i++)
> > -				if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> > -							      i))
> > +				if (!tpm_tis_probe_irq_single(chip, 0, i))
> >  					return;
> > -	} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> > -					     original_int_vec))
> > +	} else if (!tpm_tis_probe_irq_single(chip, 0, original_int_vec))
> >  		return;
> >  }
> >  
> > @@ -1030,8 +1104,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> >  		}
> >  
> >  		if (irq) {
> > -			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
> > -						 irq);
> > +			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
> >  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
> >  				dev_err(&chip->dev, FW_BUG
> >  					"TPM interrupt not working, polling instead\n");
> > @@ -1039,7 +1112,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> >  				disable_interrupts(chip);
> >  			}
> >  		} else {
> > -			tpm_tis_probe_irq(chip, intmask);
> > +			tpm_tis_probe_irq(chip);
> >  		}
> >  	}
> >  
> > @@ -1065,12 +1138,23 @@ EXPORT_SYMBOL_GPL(tpm_tis_core_init);
> >  static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
> >  {
> >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > -	u32 intmask;
> >  	int rc;
> >  
> >  	if (chip->ops->clk_enable != NULL)
> >  		chip->ops->clk_enable(chip, true);
> >  
> > +	/*
> > +	 * must have the locality before we can enable interrupts, so
> > +	 * poll for the locality being ready
> > +	 */
> > +	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> > +	if (request_locality(chip, 0) != 0) {
> > +		dev_err(&chip->dev, "Failed to enable interrupts after suspend\n");
> > +		goto out;
> > +	}
> > +	chip->flags |= TPM_CHIP_FLAG_IRQ;
> > +
> > +
> >  	/* reenable interrupts that device may have lost or
> >  	 * BIOS/firmware may have disabled
> >  	 */
> > @@ -1078,17 +1162,10 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
> >  	if (rc < 0)
> >  		goto out;
> >  
> > -	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> > -	if (rc < 0)
> > -		goto out;
> > -
> > -	intmask |= TPM_INTF_CMD_READY_INT
> > -	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
> > -	    | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
> > +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
> >  
> > -	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> > -
> > -out:
> > + out:
> > +	release_locality(chip, 0);
> >  	if (chip->ops->clk_enable != NULL)
> >  		chip->ops->clk_enable(chip, false);
> 
> Other than the question about the comment in tpm_tis_enable_interrupt
> 
> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>

Should this have

  Fixes: e6aef069b6e9 ("tpm_tis: convert to using locality callbacks")

?

/Jarkko

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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-19 23:41   ` Jerry Snitselaar
@ 2020-10-24 12:17     ` Jarkko Sakkinen
  2020-10-30 12:43       ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-24 12:17 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Mon, Oct 19, 2020 at 04:41:35PM -0700, Jerry Snitselaar wrote:
> 
> James Bottomley @ 2020-10-01 11:09 MST:
> 
> > There are two problems with our current interrupt probing: firstly the
> > TPM_CHIP_FLAG_IRQ never gets set initially, so a check for interrupts
> > is never done.  Fix this by setting the flag before we generate and
> > interrupt for probing.  Secondly our IRQ setup may be ineffective on a
> > TPM without legacy access cycles becuase according to the TPM
> > Interface Specification the interrupt registers are only writeable in
> > the current locality, so issue a request_locality before setting up
> > the interrupts.
> >
> > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> >
> > ---
> >
> > v2: improved description
> > ---
> >  drivers/char/tpm/tpm_tis_core.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> >
> > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > index 0c07da8cd680..12b657ed3a39 100644
> > --- a/drivers/char/tpm/tpm_tis_core.c
> > +++ b/drivers/char/tpm/tpm_tis_core.c
> > @@ -809,6 +809,19 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
> >  	}
> >  	priv->irq = irq;
> >  
> > +	/*
> > +	 * note writes to the interrupt registers are only effective
> > +	 * when the TPM is in the active locality, so we have to
> > +	 * request the locality here to get the interrupt set up.
> > +	 * This request has no corresponding release, because the
> > +	 * locality will be relinquished at the end of the tpm command
> > +	 * that probes the interrupts
> > +	 */
> > +	if (request_locality(chip, 0) != 0) {
> > +		dev_err(&chip->dev, "failed to gain locality for irq probe\n");
> > +		return -EBUSY;
> > +	}

Appreciate the comment a lot, but s/note/Note/

/Jarkko

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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-20 23:10       ` Jerry Snitselaar
@ 2020-10-24 12:20         ` Jarkko Sakkinen
  2020-10-26 18:29           ` Jerry Snitselaar
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-24 12:20 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	James Bottomley, linux-integrity, Jason Gunthorpe, Peter Huewe,
	Borislav Petkov, Nayna Jain

On Tue, Oct 20, 2020 at 04:10:42PM -0700, Jerry Snitselaar wrote:
> 
> Jarkko Sakkinen @ 2020-10-18 14:05 MST:
> 
> > On Tue, Oct 13, 2020 at 08:15:36AM -0700, Jerry Snitselaar wrote:
> >> 
> >> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> >> 
> >> > On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
> >> >> The current state of the TIS TPM is that interrupts have been globally
> >> >> disabled by various changes.  The problems we got reported the last
> >> >> time they were enabled was interrupt storms.  With my own TIS TPM,
> >> >> I've found that this is caused because my TPM doesn't do legacy
> >> >> cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
> >> >> requires any TIS TPM without legacy cycles not to act on any write to
> >> >> an interrupt register unless the locality is enabled.  This means if
> >> >> an interrupt fires after we relinquish the locality, the TPM_EOI in
> >> >> the interrupt routine is ineffective meaning the same interrupt
> >> >> triggers over and over again.  This problem also means we can have
> >> >> trouble setting up interrupts on TIS TPMs because the current init
> >> >> code does the setup before the locality is claimed for the first time.
> >> >> 
> >> >> James
> >> >
> >> > You should consider expanding the audience. Jerry, once you have some
> >> > bandwidth (no rush, does not land before rc2), it would be great that if
> >> > you could try this. I'm emphasizing this just because of the
> >> > intersection. I think it would also make senset to get tested-by from
> >> > Nayna.
> >> 
> >> I will run some tests on some other systems I have access to. As noted
> >> in the other email I did a quick test with a t490s with an older bios
> >> that exhibits the problem originally reported when Stefan's patch
> >> enabled interrupts.
> >
> > Thank you. As said, I can make a pull request to rc2 or even rc3, if
> > needed.
> >
> > /Jarkko
> 
> So outside of the t490s I have access to, it looks like the nuc5 with
> tpm2.0 device, and and older lenovo D30 with a tpm1.2 device both are
> not using interrupts. I'm digging around to see if I can find some
> other systems that I can test interrupts on.
> 
> Regards,
> Jerry

I'm going to test with this C720P chromebook, which has a long standing
bug in the kernel bugzilla. I got it a while ago but it's stuck in the
boot.

If that doesn't boot, I'll pick up old Ivylake NUC from the office,
which has TPM 1.2 and bit newer TPM 2.0 NUC. Should anyway pick them,
have not used them for testing for a while because of pandemia.

/Jarkko

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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-24 12:20         ` Jarkko Sakkinen
@ 2020-10-26 18:29           ` Jerry Snitselaar
  2020-10-27 17:14             ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-26 18:29 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: equired, justmentioningitbecauseIthinkthatwouldbeagood,
	James Bottomley, linux-integrity, Jason Gunthorpe, Peter Huewe,
	Borislav Petkov, Nayna Jain


Jarkko Sakkinen @ 2020-10-24 05:20 MST:

> On Tue, Oct 20, 2020 at 04:10:42PM -0700, Jerry Snitselaar wrote:
>> 
>> Jarkko Sakkinen @ 2020-10-18 14:05 MST:
>> 
>> > On Tue, Oct 13, 2020 at 08:15:36AM -0700, Jerry Snitselaar wrote:
>> >> 
>> >> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
>> >> 
>> >> > On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
>> >> >> The current state of the TIS TPM is that interrupts have been globally
>> >> >> disabled by various changes.  The problems we got reported the last
>> >> >> time they were enabled was interrupt storms.  With my own TIS TPM,
>> >> >> I've found that this is caused because my TPM doesn't do legacy
>> >> >> cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
>> >> >> requires any TIS TPM without legacy cycles not to act on any write to
>> >> >> an interrupt register unless the locality is enabled.  This means if
>> >> >> an interrupt fires after we relinquish the locality, the TPM_EOI in
>> >> >> the interrupt routine is ineffective meaning the same interrupt
>> >> >> triggers over and over again.  This problem also means we can have
>> >> >> trouble setting up interrupts on TIS TPMs because the current init
>> >> >> code does the setup before the locality is claimed for the first time.
>> >> >> 
>> >> >> James
>> >> >
>> >> > You should consider expanding the audience. Jerry, once you have some
>> >> > bandwidth (no rush, does not land before rc2), it would be great that if
>> >> > you could try this. I'm emphasizing this just because of the
>> >> > intersection. I think it would also make senset to get tested-by from
>> >> > Nayna.
>> >> 
>> >> I will run some tests on some other systems I have access to. As noted
>> >> in the other email I did a quick test with a t490s with an older bios
>> >> that exhibits the problem originally reported when Stefan's patch
>> >> enabled interrupts.
>> >
>> > Thank you. As said, I can make a pull request to rc2 or even rc3, if
>> > needed.
>> >
>> > /Jarkko
>> 
>> So outside of the t490s I have access to, it looks like the nuc5 with
>> tpm2.0 device, and and older lenovo D30 with a tpm1.2 device both are
>> not using interrupts. I'm digging around to see if I can find some
>> other systems that I can test interrupts on.
>> 
>> Regards,
>> Jerry
>
> I'm going to test with this C720P chromebook, which has a long standing
> bug in the kernel bugzilla. I got it a while ago but it's stuck in the
> boot.
>
> If that doesn't boot, I'll pick up old Ivylake NUC from the office,
> which has TPM 1.2 and bit newer TPM 2.0 NUC. Should anyway pick them,
> have not used them for testing for a while because of pandemia.
>
> /Jarkko

My search continues through the systems in our labs. Running into the
same issue with the Dells. Looking at the TCPA table it looks like
they aren't set up for interrupts as well. I have some tpm2.0 systems
to still try.

Jerry


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

* Re: [PATCH v2 0/5] tpm_tis: fix interrupts (again)
  2020-10-26 18:29           ` Jerry Snitselaar
@ 2020-10-27 17:14             ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-27 17:14 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe, Peter Huewe,
	Borislav Petkov, Nayna Jain

On Mon, Oct 26, 2020 at 11:29:46AM -0700, Jerry Snitselaar wrote:
> 
> Jarkko Sakkinen @ 2020-10-24 05:20 MST:
> 
> > On Tue, Oct 20, 2020 at 04:10:42PM -0700, Jerry Snitselaar wrote:
> >> 
> >> Jarkko Sakkinen @ 2020-10-18 14:05 MST:
> >> 
> >> > On Tue, Oct 13, 2020 at 08:15:36AM -0700, Jerry Snitselaar wrote:
> >> >> 
> >> >> Jarkko Sakkinen @ 2020-10-12 18:17 MST:
> >> >> 
> >> >> > On Thu, Oct 01, 2020 at 11:09:20AM -0700, James Bottomley wrote:
> >> >> >> The current state of the TIS TPM is that interrupts have been globally
> >> >> >> disabled by various changes.  The problems we got reported the last
> >> >> >> time they were enabled was interrupt storms.  With my own TIS TPM,
> >> >> >> I've found that this is caused because my TPM doesn't do legacy
> >> >> >> cycles, The TIS spec (chapter 6.1 "Locality Usage Per Register")
> >> >> >> requires any TIS TPM without legacy cycles not to act on any write to
> >> >> >> an interrupt register unless the locality is enabled.  This means if
> >> >> >> an interrupt fires after we relinquish the locality, the TPM_EOI in
> >> >> >> the interrupt routine is ineffective meaning the same interrupt
> >> >> >> triggers over and over again.  This problem also means we can have
> >> >> >> trouble setting up interrupts on TIS TPMs because the current init
> >> >> >> code does the setup before the locality is claimed for the first time.
> >> >> >> 
> >> >> >> James
> >> >> >
> >> >> > You should consider expanding the audience. Jerry, once you have some
> >> >> > bandwidth (no rush, does not land before rc2), it would be great that if
> >> >> > you could try this. I'm emphasizing this just because of the
> >> >> > intersection. I think it would also make senset to get tested-by from
> >> >> > Nayna.
> >> >> 
> >> >> I will run some tests on some other systems I have access to. As noted
> >> >> in the other email I did a quick test with a t490s with an older bios
> >> >> that exhibits the problem originally reported when Stefan's patch
> >> >> enabled interrupts.
> >> >
> >> > Thank you. As said, I can make a pull request to rc2 or even rc3, if
> >> > needed.
> >> >
> >> > /Jarkko
> >> 
> >> So outside of the t490s I have access to, it looks like the nuc5 with
> >> tpm2.0 device, and and older lenovo D30 with a tpm1.2 device both are
> >> not using interrupts. I'm digging around to see if I can find some
> >> other systems that I can test interrupts on.
> >> 
> >> Regards,
> >> Jerry
> >
> > I'm going to test with this C720P chromebook, which has a long standing
> > bug in the kernel bugzilla. I got it a while ago but it's stuck in the
> > boot.
> >
> > If that doesn't boot, I'll pick up old Ivylake NUC from the office,
> > which has TPM 1.2 and bit newer TPM 2.0 NUC. Should anyway pick them,
> > have not used them for testing for a while because of pandemia.
> >
> > /Jarkko
> 
> My search continues through the systems in our labs. Running into the
> same issue with the Dells. Looking at the TCPA table it looks like
> they aren't set up for interrupts as well. I have some tpm2.0 systems
> to still try.

The chromebook that I have feels like bricked, at least for the window
for testing this bug. I'll pick up the nucs tomorrow.

> Jerry

/Jarkko

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

* Re: [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition
  2020-10-24 12:07     ` Jarkko Sakkinen
@ 2020-10-30 12:13       ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-30 12:13 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Sat, Oct 24, 2020 at 03:07:44PM +0300, Jarkko Sakkinen wrote:
> On Mon, Oct 19, 2020 at 04:16:32PM -0700, Jerry Snitselaar wrote:
> > 
> > James Bottomley @ 2020-10-01 11:09 MST:
> > 
> > > The TPM TIS specification says the TPM signals the acquisition of
> > > locality when the TMP_ACCESS_REQUEST_USE bit goes to one *and* the
> > > TPM_ACCESS_REQUEST_USE bit goes to zero.  Currently we only check the
> > > former not the latter, so check both.  Adding the check on
> > > TPM_ACCESS_REQUEST_USE should fix the case where the locality is
> > > re-requested before the TPM has released it.  In this case the
> > > locality may get released briefly before it is reacquired, which
> > > causes all sorts of problems. However, with the added check,
> > > TPM_ACCESS_REQUEST_USE should remain 1 until the second request for
> > > the locality is granted.
> > >
> > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> > >
> > > ---
> > >
> > > v2: added this patch
> > > ---
> > >  drivers/char/tpm/tpm_tis_core.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > > index 92c51c6cfd1b..f3ecde8df47d 100644
> > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > @@ -125,7 +125,8 @@ static bool check_locality(struct tpm_chip *chip, int l)
> > >  	if (rc < 0)
> > >  		return false;
> > >  
> > > -	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
> > > +	if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID
> > > +		       | TPM_ACCESS_REQUEST_USE)) ==
> > >  	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
> > >  		priv->locality = l;
> > >  		return true;
> > 
> > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> 
> Thank you.
> 
> James, few minor remarks.
> 
> Given that the failing commit is in the GIT, just for reference
> 
>   Fixes: 27084efee0c3 ("[PATCH] tpm: driver for next generation TPM chips")
>   Cc: stable@ger.kernel.org
> 
> I want fixes tags for everything that has a legit Git commit, even
> if it spans through all the existing stable kernels. It's valuable
> information to have in the Git log.
> 
> Another thing I noticed is that would be less ugly put everything
> in the same line, as checkpatch requirement have been relaxed.
> 
> Finally, please put a verbose inline comment before the condition.
> tpm_tis driver is complicated enough that it should be better
> documented. After months pass things tend to fade away and wrong
> decisions might be made because of that. You can probably derive
> it from the already nice and verbose commit message, so let's
> take advantage of it.
> 
> About recent debate on patch changelogs. I talked with Dave Hansen
> about this, and he said that in x86 tree, they are the standard, but
> the practice depends per tree.
> 
> After thinking about this, and writing per patch changelogs for the
> next iteration of the SGX patch set, my standing point is that either
> works as it is properly written and maintained.

This can be merged immediately once the remarks have been taken care
of (i.e. do not except tested-by for 1/5).

/Jarkko

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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-24 12:10     ` Jarkko Sakkinen
@ 2020-10-30 12:17       ` Jarkko Sakkinen
  2020-10-30 15:47         ` James Bottomley
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-30 12:17 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Sat, Oct 24, 2020 at 03:10:07PM +0300, Jarkko Sakkinen wrote:
> On Mon, Oct 19, 2020 at 04:17:59PM -0700, Jerry Snitselaar wrote:
> > 
> > James Bottomley @ 2020-10-01 11:09 MST:
> > 
> > > The current release locality code seems to be based on the
> > > misunderstanding that the TPM interrupts when a locality is released:
> > > it doesn't, only when the locality is acquired.
> > >
> > > Furthermore, there seems to be no point in waiting for the locality to
> > > be released.  All it does is penalize the last TPM user.  However, if
> > > there's no next TPM user, this is a pointless wait and if there is a
> > > next TPM user, they'll pay the penalty waiting for the new locality
> > > (or possibly not if it's the same as the old locality).
> > >
> > > Fix the code by making release_locality as simple write to release
> > > with no waiting for completion.
> > >
> > > Fixes: 33bafe90824b ("tpm_tis: verify locality released before returning from release_locality")
> > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> > >
> > > ---
> > >
> > > v2: added fixes
> > > ---
> > >  drivers/char/tpm/tpm_tis_core.c | 47 +--------------------------------
> > >  1 file changed, 1 insertion(+), 46 deletions(-)
> > >
> > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > > index f3ecde8df47d..431919d5f48a 100644
> > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > @@ -135,58 +135,13 @@ static bool check_locality(struct tpm_chip *chip, int l)
> > >  	return false;
> > >  }
> > >  
> > > -static bool locality_inactive(struct tpm_chip *chip, int l)
> > > -{
> > > -	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > -	int rc;
> > > -	u8 access;
> > > -
> > > -	rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
> > > -	if (rc < 0)
> > > -		return false;
> > > -
> > > -	if ((access & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
> > > -	    == TPM_ACCESS_VALID)
> > > -		return true;
> > > -
> > > -	return false;
> > > -}
> > > -
> > >  static int release_locality(struct tpm_chip *chip, int l)
> > >  {
> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > -	unsigned long stop, timeout;
> > > -	long rc;
> > >  
> > >  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
> > >  
> > > -	stop = jiffies + chip->timeout_a;
> > > -
> > > -	if (chip->flags & TPM_CHIP_FLAG_IRQ) {
> > > -again:
> > > -		timeout = stop - jiffies;
> > > -		if ((long)timeout <= 0)
> > > -			return -1;
> > > -
> > > -		rc = wait_event_interruptible_timeout(priv->int_queue,
> > > -						      (locality_inactive(chip, l)),
> > > -						      timeout);
> > > -
> > > -		if (rc > 0)
> > > -			return 0;
> > > -
> > > -		if (rc == -ERESTARTSYS && freezing(current)) {
> > > -			clear_thread_flag(TIF_SIGPENDING);
> > > -			goto again;
> > > -		}
> > > -	} else {
> > > -		do {
> > > -			if (locality_inactive(chip, l))
> > > -				return 0;
> > > -			tpm_msleep(TPM_TIMEOUT);
> > > -		} while (time_before(jiffies, stop));
> > > -	}
> > > -	return -1;
> > > +	return 0;
> > >  }
> > >  
> > >  static int request_locality(struct tpm_chip *chip, int l)
> > 
> > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> 
> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

Just noticed that the short summary is wrong: a fix is not a clean up.

Maybe "tpm_tis: Invoke locality release without wait" ? I'm also open
for other suggestions but the current is short summary does not describe
the patch.

/Jarkko

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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-10-24 12:15     ` Jarkko Sakkinen
@ 2020-10-30 12:18       ` Jarkko Sakkinen
  2020-10-30 16:06         ` Jerry Snitselaar
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-30 12:18 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Sat, Oct 24, 2020 at 03:15:53PM +0300, Jarkko Sakkinen wrote:
> On Mon, Oct 19, 2020 at 05:14:26PM -0700, Jerry Snitselaar wrote:
> > 
> > James Bottomley @ 2020-10-01 11:09 MST:
> > 
> > > If a TIS TPM doesn't have legacy cycles, any write to the interrupt
> > > registers is ignored unless a locality is active.  This means even to
> > > set up the interrupt vectors a locality must first be activated.  Fix
> > > this by activating the 0 locality in the interrupt probe setup.
> > >
> > > Since the TPM_EOI signalling also requires an active locality, the
> > > interrupt routine cannot end an interrupt if the locality is released.
> > > This can lead to a situation where the TPM goes command ready after
> > > locality release and since the interrupt cannot be ended it refires
> > > continuously.  Fix this by disabling all interrupts except locality
> > > change when a locality is released (this only fires when a locality
> > > becomes active, meaning the TPM_EOI should work).
> > >
> > > Finally, since we now disable all status based interrupts in the
> > > locality release, they must be re-enabled before waiting to check the
> > > condition, so add interrupt enabling to the status wait.
> > >
> > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> > >
> > > ---
> > >
> > > v2: renamed functions
> > > ---
> > >  drivers/char/tpm/tpm_tis_core.c | 125 ++++++++++++++++++++++++++------
> > >  1 file changed, 101 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > > index 431919d5f48a..0c07da8cd680 100644
> > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > @@ -29,6 +29,46 @@
> > >  
> > >  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
> > >  
> > > +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8 mask)
> > > +{
> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > +	u32 intmask;
> > > +
> > > +	/* Take control of the TPM's interrupt hardware and shut it off */
> > 
> > s/shut it off/turn it on/ ?
> > 
> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> > > +
> > > +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
> > > +
> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> > > +}
> > > +
> > > +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8 mask)
> > > +{
> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > +	u32 intmask;
> > > +
> > > +	/* Take control of the TPM's interrupt hardware and shut it off */
> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> > > +
> > > +	intmask &= ~mask;
> > > +
> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> > > +}
> > > +
> > > +static void tpm_tis_enable_stat_interrupts(struct tpm_chip *chip, u8 stat)
> > > +{
> > > +	u32 mask = 0;
> > > +
> > > +	if (stat & TPM_STS_COMMAND_READY)
> > > +		mask |= TPM_INTF_CMD_READY_INT;
> > > +	if (stat & TPM_STS_VALID)
> > > +		mask |= TPM_INTF_STS_VALID_INT;
> > > +	if (stat & TPM_STS_DATA_AVAIL)
> > > +		mask |= TPM_INTF_DATA_AVAIL_INT;
> > > +
> > > +	tpm_tis_enable_interrupt(chip, mask);
> > > +}
> > > +
> > >  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
> > >  					bool check_cancel, bool *canceled)
> > >  {
> > > @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
> > >  		timeout = stop - jiffies;
> > >  		if ((long)timeout <= 0)
> > >  			return -ETIME;
> > > +		tpm_tis_enable_stat_interrupts(chip, mask);
> > >  		rc = wait_event_interruptible_timeout(*queue,
> > >  			wait_for_tpm_stat_cond(chip, mask, check_cancel,
> > >  					       &canceled),
> > >  			timeout);
> > >  		if (rc > 0) {
> > > +			if (rc == 1)
> > > +				dev_err(&chip->dev, "Lost Interrupt waiting for TPM stat\n");
> > >  			if (canceled)
> > >  				return -ECANCELED;
> > >  			return 0;
> > > @@ -138,6 +181,28 @@ static bool check_locality(struct tpm_chip *chip, int l)
> > >  static int release_locality(struct tpm_chip *chip, int l)
> > >  {
> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > +	u32 int_status;
> > > +	int rc;
> > > +
> > > +	/*
> > > +	 * Note that once we relinquish the locality, all writes to
> > > +	 * the interrupt registers become ineffective meaning we can't
> > > +	 * do a TPM_EOI.  This means we must disable every interrupt
> > > +	 * except the locality change one to avoid interrupt
> > > +	 * storms.
> > > +	 */
> > > +	tpm_tis_disable_interrupt(chip, TPM_INTF_CMD_READY_INT
> > > +				  | TPM_INTF_STS_VALID_INT
> > > +				  | TPM_INTF_DATA_AVAIL_INT);
> > > +
> > > +	rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
> > > +	if (rc < 0)
> > > +		return rc;
> > > +
> > > +	/* Clear all pending */
> > > +	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
> > > +	if (rc < 0)
> > > +		return rc;
> > >  
> > >  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
> > >  
> > > @@ -164,12 +229,17 @@ static int request_locality(struct tpm_chip *chip, int l)
> > >  		timeout = stop - jiffies;
> > >  		if ((long)timeout <= 0)
> > >  			return -1;
> > > +
> > >  		rc = wait_event_interruptible_timeout(priv->int_queue,
> > >  						      (check_locality
> > >  						       (chip, l)),
> > >  						      timeout);
> > > -		if (rc > 0)
> > > +		if (rc > 1)
> > > +			return l;
> > > +		if (rc == 1) {
> > > +			dev_info(&chip->dev, "Lost Interrupt waiting for locality\n");
> > >  			return l;
> > > +		}
> > >  		if (rc == -ERESTARTSYS && freezing(current)) {
> > >  			clear_thread_flag(TIF_SIGPENDING);
> > >  			goto again;
> > > @@ -465,6 +535,10 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
> > >  	irq = priv->irq;
> > >  	priv->irq = 0;
> > >  	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_CMD_READY_INT
> > > +				 | TPM_INTF_LOCALITY_CHANGE_INT
> > > +				 | TPM_INTF_DATA_AVAIL_INT
> > > +				 | TPM_INTF_STS_VALID_INT);
> > >  	rc = tpm_tis_send_main(chip, buf, len);
> > >  	priv->irq = irq;
> > >  	chip->flags |= TPM_CHIP_FLAG_IRQ;
> > > @@ -719,7 +793,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
> > >   * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
> > >   * everything and leave in polling mode. Returns 0 on success.
> > >   */
> > > -static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> > > +static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
> > >  				    int flags, int irq)
> > >  {
> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > @@ -753,9 +827,11 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> > >  	if (rc < 0)
> > >  		return rc;
> > >  
> > > -	/* Turn on */
> > > -	rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
> > > -			     intmask | TPM_GLOBAL_INT_ENABLE);
> > > +	/*
> > > +	 * Turn on.  The locality change interrupt is the only one
> > > +	 * always enabled
> > > +	 */
> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
> > >  	if (rc < 0)
> > >  		return rc;
> > >  
> > > @@ -787,7 +863,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> > >   * do not have ACPI/etc. We typically expect the interrupt to be declared if
> > >   * present.
> > >   */
> > > -static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
> > > +static void tpm_tis_probe_irq(struct tpm_chip *chip)
> > >  {
> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > >  	u8 original_int_vec;
> > > @@ -801,11 +877,9 @@ static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
> > >  	if (!original_int_vec) {
> > >  		if (IS_ENABLED(CONFIG_X86))
> > >  			for (i = 3; i <= 15; i++)
> > > -				if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> > > -							      i))
> > > +				if (!tpm_tis_probe_irq_single(chip, 0, i))
> > >  					return;
> > > -	} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> > > -					     original_int_vec))
> > > +	} else if (!tpm_tis_probe_irq_single(chip, 0, original_int_vec))
> > >  		return;
> > >  }
> > >  
> > > @@ -1030,8 +1104,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> > >  		}
> > >  
> > >  		if (irq) {
> > > -			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
> > > -						 irq);
> > > +			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
> > >  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
> > >  				dev_err(&chip->dev, FW_BUG
> > >  					"TPM interrupt not working, polling instead\n");
> > > @@ -1039,7 +1112,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> > >  				disable_interrupts(chip);
> > >  			}
> > >  		} else {
> > > -			tpm_tis_probe_irq(chip, intmask);
> > > +			tpm_tis_probe_irq(chip);
> > >  		}
> > >  	}
> > >  
> > > @@ -1065,12 +1138,23 @@ EXPORT_SYMBOL_GPL(tpm_tis_core_init);
> > >  static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
> > >  {
> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > -	u32 intmask;
> > >  	int rc;
> > >  
> > >  	if (chip->ops->clk_enable != NULL)
> > >  		chip->ops->clk_enable(chip, true);
> > >  
> > > +	/*
> > > +	 * must have the locality before we can enable interrupts, so
> > > +	 * poll for the locality being ready
> > > +	 */
> > > +	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> > > +	if (request_locality(chip, 0) != 0) {
> > > +		dev_err(&chip->dev, "Failed to enable interrupts after suspend\n");
> > > +		goto out;
> > > +	}
> > > +	chip->flags |= TPM_CHIP_FLAG_IRQ;
> > > +
> > > +
> > >  	/* reenable interrupts that device may have lost or
> > >  	 * BIOS/firmware may have disabled
> > >  	 */
> > > @@ -1078,17 +1162,10 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
> > >  	if (rc < 0)
> > >  		goto out;
> > >  
> > > -	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> > > -	if (rc < 0)
> > > -		goto out;
> > > -
> > > -	intmask |= TPM_INTF_CMD_READY_INT
> > > -	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
> > > -	    | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
> > >  
> > > -	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> > > -
> > > -out:
> > > + out:
> > > +	release_locality(chip, 0);
> > >  	if (chip->ops->clk_enable != NULL)
> > >  		chip->ops->clk_enable(chip, false);
> > 
> > Other than the question about the comment in tpm_tis_enable_interrupt
> > 
> > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> 
> Should this have
> 
>   Fixes: e6aef069b6e9 ("tpm_tis: convert to using locality callbacks")
> 
> ?

?

/Jarkko

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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-24 12:17     ` Jarkko Sakkinen
@ 2020-10-30 12:43       ` Jarkko Sakkinen
  2020-10-30 15:49         ` James Bottomley
  2020-11-06 15:32         ` Jarkko Sakkinen
  0 siblings, 2 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-30 12:43 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Sat, Oct 24, 2020 at 03:17:18PM +0300, Jarkko Sakkinen wrote:
> On Mon, Oct 19, 2020 at 04:41:35PM -0700, Jerry Snitselaar wrote:
> > 
> > James Bottomley @ 2020-10-01 11:09 MST:
> > 
> > > There are two problems with our current interrupt probing: firstly the
> > > TPM_CHIP_FLAG_IRQ never gets set initially, so a check for interrupts
> > > is never done.  Fix this by setting the flag before we generate and
> > > interrupt for probing.  Secondly our IRQ setup may be ineffective on a
> > > TPM without legacy access cycles becuase according to the TPM
> > > Interface Specification the interrupt registers are only writeable in
> > > the current locality, so issue a request_locality before setting up
> > > the interrupts.
> > >
> > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> > >
> > > ---
> > >
> > > v2: improved description
> > > ---
> > >  drivers/char/tpm/tpm_tis_core.c | 14 ++++++++++++++
> > >  1 file changed, 14 insertions(+)
> > >
> > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > > index 0c07da8cd680..12b657ed3a39 100644
> > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > @@ -809,6 +809,19 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
> > >  	}
> > >  	priv->irq = irq;
> > >  
> > > +	/*
> > > +	 * note writes to the interrupt registers are only effective
> > > +	 * when the TPM is in the active locality, so we have to
> > > +	 * request the locality here to get the interrupt set up.
> > > +	 * This request has no corresponding release, because the
> > > +	 * locality will be relinquished at the end of the tpm command
> > > +	 * that probes the interrupts
> > > +	 */
> > > +	if (request_locality(chip, 0) != 0) {
> > > +		dev_err(&chip->dev, "failed to gain locality for irq probe\n");
> > > +		return -EBUSY;
> > > +	}
> 
> Appreciate the comment a lot, but s/note/Note/

I tested this with:

- https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
  dTPM 1.2
- https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
  dTPM 2.0

I did not get "TPM interrupt not working, polling instead" to klog.
But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?

/Jarkko

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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-30 12:17       ` Jarkko Sakkinen
@ 2020-10-30 15:47         ` James Bottomley
  2020-10-30 21:52           ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-10-30 15:47 UTC (permalink / raw)
  To: Jarkko Sakkinen, Jerry Snitselaar
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe

On Fri, 2020-10-30 at 14:17 +0200, Jarkko Sakkinen wrote:
[...]
> Just noticed that the short summary is wrong: a fix is not a clean
> up.

I don't really think this is a fix.  What we currently have is working,
just suboptimally.  This makes it work optimally, which is better, but
it's not fixing anything because apart from a speed up in operations
there will be no user visible change.  If we use the word "fix" it will
excite all the automatic patch selectors for stable.

> Maybe "tpm_tis: Invoke locality release without wait" ? I'm also open
> for other suggestions but the current is short summary does not
> describe the patch.

That sounds fine, not having fix in the subject works for me.

James



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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-30 12:43       ` Jarkko Sakkinen
@ 2020-10-30 15:49         ` James Bottomley
  2020-10-30 16:11           ` Jerry Snitselaar
  2020-11-03  4:17           ` Jarkko Sakkinen
  2020-11-06 15:32         ` Jarkko Sakkinen
  1 sibling, 2 replies; 74+ messages in thread
From: James Bottomley @ 2020-10-30 15:49 UTC (permalink / raw)
  To: Jarkko Sakkinen, Jerry Snitselaar
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe

On Fri, 2020-10-30 at 14:43 +0200, Jarkko Sakkinen wrote:
[...]
> I tested this with:
> 
> - 
> https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
>   dTPM 1.2
> - 
> https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
>   dTPM 2.0
> 
> I did not get "TPM interrupt not working, polling instead" to klog.
> But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?

That's usually what you get when ACPI specifies the interrupt isn't
connected (we don't try to probe it).

James



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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-10-30 12:18       ` Jarkko Sakkinen
@ 2020-10-30 16:06         ` Jerry Snitselaar
  2020-11-03  4:16           ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-30 16:06 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe


Jarkko Sakkinen @ 2020-10-30 05:18 MST:

> On Sat, Oct 24, 2020 at 03:15:53PM +0300, Jarkko Sakkinen wrote:
>> On Mon, Oct 19, 2020 at 05:14:26PM -0700, Jerry Snitselaar wrote:
>> > 
>> > James Bottomley @ 2020-10-01 11:09 MST:
>> > 
>> > > If a TIS TPM doesn't have legacy cycles, any write to the interrupt
>> > > registers is ignored unless a locality is active.  This means even to
>> > > set up the interrupt vectors a locality must first be activated.  Fix
>> > > this by activating the 0 locality in the interrupt probe setup.
>> > >
>> > > Since the TPM_EOI signalling also requires an active locality, the
>> > > interrupt routine cannot end an interrupt if the locality is released.
>> > > This can lead to a situation where the TPM goes command ready after
>> > > locality release and since the interrupt cannot be ended it refires
>> > > continuously.  Fix this by disabling all interrupts except locality
>> > > change when a locality is released (this only fires when a locality
>> > > becomes active, meaning the TPM_EOI should work).
>> > >
>> > > Finally, since we now disable all status based interrupts in the
>> > > locality release, they must be re-enabled before waiting to check the
>> > > condition, so add interrupt enabling to the status wait.
>> > >
>> > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>> > >
>> > > ---
>> > >
>> > > v2: renamed functions
>> > > ---
>> > >  drivers/char/tpm/tpm_tis_core.c | 125 ++++++++++++++++++++++++++------
>> > >  1 file changed, 101 insertions(+), 24 deletions(-)
>> > >
>> > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
>> > > index 431919d5f48a..0c07da8cd680 100644
>> > > --- a/drivers/char/tpm/tpm_tis_core.c
>> > > +++ b/drivers/char/tpm/tpm_tis_core.c
>> > > @@ -29,6 +29,46 @@
>> > >  
>> > >  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
>> > >  
>> > > +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8 mask)
>> > > +{
>> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> > > +	u32 intmask;
>> > > +
>> > > +	/* Take control of the TPM's interrupt hardware and shut it off */
>> > 
>> > s/shut it off/turn it on/ ?
>> > 
>> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
>> > > +
>> > > +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
>> > > +
>> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
>> > > +}
>> > > +
>> > > +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8 mask)
>> > > +{
>> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> > > +	u32 intmask;
>> > > +
>> > > +	/* Take control of the TPM's interrupt hardware and shut it off */
>> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
>> > > +
>> > > +	intmask &= ~mask;
>> > > +
>> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
>> > > +}
>> > > +
>> > > +static void tpm_tis_enable_stat_interrupts(struct tpm_chip *chip, u8 stat)
>> > > +{
>> > > +	u32 mask = 0;
>> > > +
>> > > +	if (stat & TPM_STS_COMMAND_READY)
>> > > +		mask |= TPM_INTF_CMD_READY_INT;
>> > > +	if (stat & TPM_STS_VALID)
>> > > +		mask |= TPM_INTF_STS_VALID_INT;
>> > > +	if (stat & TPM_STS_DATA_AVAIL)
>> > > +		mask |= TPM_INTF_DATA_AVAIL_INT;
>> > > +
>> > > +	tpm_tis_enable_interrupt(chip, mask);
>> > > +}
>> > > +
>> > >  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
>> > >  					bool check_cancel, bool *canceled)
>> > >  {
>> > > @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
>> > >  		timeout = stop - jiffies;
>> > >  		if ((long)timeout <= 0)
>> > >  			return -ETIME;
>> > > +		tpm_tis_enable_stat_interrupts(chip, mask);
>> > >  		rc = wait_event_interruptible_timeout(*queue,
>> > >  			wait_for_tpm_stat_cond(chip, mask, check_cancel,
>> > >  					       &canceled),
>> > >  			timeout);
>> > >  		if (rc > 0) {
>> > > +			if (rc == 1)
>> > > +				dev_err(&chip->dev, "Lost Interrupt waiting for TPM stat\n");
>> > >  			if (canceled)
>> > >  				return -ECANCELED;
>> > >  			return 0;
>> > > @@ -138,6 +181,28 @@ static bool check_locality(struct tpm_chip *chip, int l)
>> > >  static int release_locality(struct tpm_chip *chip, int l)
>> > >  {
>> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> > > +	u32 int_status;
>> > > +	int rc;
>> > > +
>> > > +	/*
>> > > +	 * Note that once we relinquish the locality, all writes to
>> > > +	 * the interrupt registers become ineffective meaning we can't
>> > > +	 * do a TPM_EOI.  This means we must disable every interrupt
>> > > +	 * except the locality change one to avoid interrupt
>> > > +	 * storms.
>> > > +	 */
>> > > +	tpm_tis_disable_interrupt(chip, TPM_INTF_CMD_READY_INT
>> > > +				  | TPM_INTF_STS_VALID_INT
>> > > +				  | TPM_INTF_DATA_AVAIL_INT);
>> > > +
>> > > +	rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
>> > > +	if (rc < 0)
>> > > +		return rc;
>> > > +
>> > > +	/* Clear all pending */
>> > > +	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
>> > > +	if (rc < 0)
>> > > +		return rc;
>> > >  
>> > >  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
>> > >  
>> > > @@ -164,12 +229,17 @@ static int request_locality(struct tpm_chip *chip, int l)
>> > >  		timeout = stop - jiffies;
>> > >  		if ((long)timeout <= 0)
>> > >  			return -1;
>> > > +
>> > >  		rc = wait_event_interruptible_timeout(priv->int_queue,
>> > >  						      (check_locality
>> > >  						       (chip, l)),
>> > >  						      timeout);
>> > > -		if (rc > 0)
>> > > +		if (rc > 1)
>> > > +			return l;
>> > > +		if (rc == 1) {
>> > > +			dev_info(&chip->dev, "Lost Interrupt waiting for locality\n");
>> > >  			return l;
>> > > +		}
>> > >  		if (rc == -ERESTARTSYS && freezing(current)) {
>> > >  			clear_thread_flag(TIF_SIGPENDING);
>> > >  			goto again;
>> > > @@ -465,6 +535,10 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
>> > >  	irq = priv->irq;
>> > >  	priv->irq = 0;
>> > >  	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
>> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_CMD_READY_INT
>> > > +				 | TPM_INTF_LOCALITY_CHANGE_INT
>> > > +				 | TPM_INTF_DATA_AVAIL_INT
>> > > +				 | TPM_INTF_STS_VALID_INT);
>> > >  	rc = tpm_tis_send_main(chip, buf, len);
>> > >  	priv->irq = irq;
>> > >  	chip->flags |= TPM_CHIP_FLAG_IRQ;
>> > > @@ -719,7 +793,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
>> > >   * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
>> > >   * everything and leave in polling mode. Returns 0 on success.
>> > >   */
>> > > -static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
>> > > +static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
>> > >  				    int flags, int irq)
>> > >  {
>> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> > > @@ -753,9 +827,11 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
>> > >  	if (rc < 0)
>> > >  		return rc;
>> > >  
>> > > -	/* Turn on */
>> > > -	rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
>> > > -			     intmask | TPM_GLOBAL_INT_ENABLE);
>> > > +	/*
>> > > +	 * Turn on.  The locality change interrupt is the only one
>> > > +	 * always enabled
>> > > +	 */
>> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
>> > >  	if (rc < 0)
>> > >  		return rc;
>> > >  
>> > > @@ -787,7 +863,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
>> > >   * do not have ACPI/etc. We typically expect the interrupt to be declared if
>> > >   * present.
>> > >   */
>> > > -static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
>> > > +static void tpm_tis_probe_irq(struct tpm_chip *chip)
>> > >  {
>> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> > >  	u8 original_int_vec;
>> > > @@ -801,11 +877,9 @@ static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
>> > >  	if (!original_int_vec) {
>> > >  		if (IS_ENABLED(CONFIG_X86))
>> > >  			for (i = 3; i <= 15; i++)
>> > > -				if (!tpm_tis_probe_irq_single(chip, intmask, 0,
>> > > -							      i))
>> > > +				if (!tpm_tis_probe_irq_single(chip, 0, i))
>> > >  					return;
>> > > -	} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
>> > > -					     original_int_vec))
>> > > +	} else if (!tpm_tis_probe_irq_single(chip, 0, original_int_vec))
>> > >  		return;
>> > >  }
>> > >  
>> > > @@ -1030,8 +1104,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>> > >  		}
>> > >  
>> > >  		if (irq) {
>> > > -			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
>> > > -						 irq);
>> > > +			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
>> > >  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
>> > >  				dev_err(&chip->dev, FW_BUG
>> > >  					"TPM interrupt not working, polling instead\n");
>> > > @@ -1039,7 +1112,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>> > >  				disable_interrupts(chip);
>> > >  			}
>> > >  		} else {
>> > > -			tpm_tis_probe_irq(chip, intmask);
>> > > +			tpm_tis_probe_irq(chip);
>> > >  		}
>> > >  	}
>> > >  
>> > > @@ -1065,12 +1138,23 @@ EXPORT_SYMBOL_GPL(tpm_tis_core_init);
>> > >  static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
>> > >  {
>> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> > > -	u32 intmask;
>> > >  	int rc;
>> > >  
>> > >  	if (chip->ops->clk_enable != NULL)
>> > >  		chip->ops->clk_enable(chip, true);
>> > >  
>> > > +	/*
>> > > +	 * must have the locality before we can enable interrupts, so
>> > > +	 * poll for the locality being ready
>> > > +	 */
>> > > +	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
>> > > +	if (request_locality(chip, 0) != 0) {
>> > > +		dev_err(&chip->dev, "Failed to enable interrupts after suspend\n");
>> > > +		goto out;
>> > > +	}
>> > > +	chip->flags |= TPM_CHIP_FLAG_IRQ;
>> > > +
>> > > +
>> > >  	/* reenable interrupts that device may have lost or
>> > >  	 * BIOS/firmware may have disabled
>> > >  	 */
>> > > @@ -1078,17 +1162,10 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
>> > >  	if (rc < 0)
>> > >  		goto out;
>> > >  
>> > > -	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
>> > > -	if (rc < 0)
>> > > -		goto out;
>> > > -
>> > > -	intmask |= TPM_INTF_CMD_READY_INT
>> > > -	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
>> > > -	    | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
>> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
>> > >  
>> > > -	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
>> > > -
>> > > -out:
>> > > + out:
>> > > +	release_locality(chip, 0);
>> > >  	if (chip->ops->clk_enable != NULL)
>> > >  		chip->ops->clk_enable(chip, false);
>> > 
>> > Other than the question about the comment in tpm_tis_enable_interrupt
>> > 
>> > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
>> 
>> Should this have
>> 
>>   Fixes: e6aef069b6e9 ("tpm_tis: convert to using locality callbacks")
>> 
>> ?
>
> ?
>
> /Jarkko

Yes, I believe so.


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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-30 15:49         ` James Bottomley
@ 2020-10-30 16:11           ` Jerry Snitselaar
  2020-11-03  4:43             ` Jarkko Sakkinen
  2020-11-03  4:17           ` Jarkko Sakkinen
  1 sibling, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-10-30 16:11 UTC (permalink / raw)
  To: James Bottomley
  Cc: Jarkko Sakkinen, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-30 08:49 MST:

> On Fri, 2020-10-30 at 14:43 +0200, Jarkko Sakkinen wrote:
> [...]
>> I tested this with:
>> 
>> - 
>> https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
>>   dTPM 1.2
>> - 
>> https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
>>   dTPM 2.0
>> 
>> I did not get "TPM interrupt not working, polling instead" to klog.
>> But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?
>
> That's usually what you get when ACPI specifies the interrupt isn't
> connected (we don't try to probe it).
>
> James

That is the problem I've been running into. When I do find a system
with a tpm and using tpm_tis, it usually seems to not have the interrupt
connected.

Should this commit have:

Fixes: 570a36097f30 ("tpm: drop 'irq' from struct tpm_vendor_specific")

That is where TPM_CHIP_FLAG_IRQ was added and not set for tpm_tis.


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

* Re: [PATCH v2 2/5] tpm_tis: Clean up locality release
  2020-10-30 15:47         ` James Bottomley
@ 2020-10-30 21:52           ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-10-30 21:52 UTC (permalink / raw)
  To: James Bottomley
  Cc: Jarkko Sakkinen, Jerry Snitselaar, linux-integrity,
	Jason Gunthorpe, Peter Huewe

On Fri, Oct 30, 2020 at 08:47:30AM -0700, James Bottomley wrote:
> On Fri, 2020-10-30 at 14:17 +0200, Jarkko Sakkinen wrote:
> [...]
> > Just noticed that the short summary is wrong: a fix is not a clean
> > up.
> 
> I don't really think this is a fix.  What we currently have is working,
> just suboptimally.  This makes it work optimally, which is better, but
> it's not fixing anything because apart from a speed up in operations
> there will be no user visible change.  If we use the word "fix" it will
> excite all the automatic patch selectors for stable.
> 
> > Maybe "tpm_tis: Invoke locality release without wait" ? I'm also open
> > for other suggestions but the current is short summary does not
> > describe the patch.
> 
> That sounds fine, not having fix in the subject works for me.
> 
> James

OK, great.

/Jarkko

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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-10-30 16:06         ` Jerry Snitselaar
@ 2020-11-03  4:16           ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-11-03  4:16 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Fri, Oct 30, 2020 at 09:06:39AM -0700, Jerry Snitselaar wrote:
> 
> Jarkko Sakkinen @ 2020-10-30 05:18 MST:
> 
> > On Sat, Oct 24, 2020 at 03:15:53PM +0300, Jarkko Sakkinen wrote:
> >> On Mon, Oct 19, 2020 at 05:14:26PM -0700, Jerry Snitselaar wrote:
> >> > 
> >> > James Bottomley @ 2020-10-01 11:09 MST:
> >> > 
> >> > > If a TIS TPM doesn't have legacy cycles, any write to the interrupt
> >> > > registers is ignored unless a locality is active.  This means even to
> >> > > set up the interrupt vectors a locality must first be activated.  Fix
> >> > > this by activating the 0 locality in the interrupt probe setup.
> >> > >
> >> > > Since the TPM_EOI signalling also requires an active locality, the
> >> > > interrupt routine cannot end an interrupt if the locality is released.
> >> > > This can lead to a situation where the TPM goes command ready after
> >> > > locality release and since the interrupt cannot be ended it refires
> >> > > continuously.  Fix this by disabling all interrupts except locality
> >> > > change when a locality is released (this only fires when a locality
> >> > > becomes active, meaning the TPM_EOI should work).
> >> > >
> >> > > Finally, since we now disable all status based interrupts in the
> >> > > locality release, they must be re-enabled before waiting to check the
> >> > > condition, so add interrupt enabling to the status wait.
> >> > >
> >> > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> >> > >
> >> > > ---
> >> > >
> >> > > v2: renamed functions
> >> > > ---
> >> > >  drivers/char/tpm/tpm_tis_core.c | 125 ++++++++++++++++++++++++++------
> >> > >  1 file changed, 101 insertions(+), 24 deletions(-)
> >> > >
> >> > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> >> > > index 431919d5f48a..0c07da8cd680 100644
> >> > > --- a/drivers/char/tpm/tpm_tis_core.c
> >> > > +++ b/drivers/char/tpm/tpm_tis_core.c
> >> > > @@ -29,6 +29,46 @@
> >> > >  
> >> > >  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
> >> > >  
> >> > > +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8 mask)
> >> > > +{
> >> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> >> > > +	u32 intmask;
> >> > > +
> >> > > +	/* Take control of the TPM's interrupt hardware and shut it off */
> >> > 
> >> > s/shut it off/turn it on/ ?
> >> > 
> >> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> >> > > +
> >> > > +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
> >> > > +
> >> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> >> > > +}
> >> > > +
> >> > > +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8 mask)
> >> > > +{
> >> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> >> > > +	u32 intmask;
> >> > > +
> >> > > +	/* Take control of the TPM's interrupt hardware and shut it off */
> >> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> >> > > +
> >> > > +	intmask &= ~mask;
> >> > > +
> >> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> >> > > +}
> >> > > +
> >> > > +static void tpm_tis_enable_stat_interrupts(struct tpm_chip *chip, u8 stat)
> >> > > +{
> >> > > +	u32 mask = 0;
> >> > > +
> >> > > +	if (stat & TPM_STS_COMMAND_READY)
> >> > > +		mask |= TPM_INTF_CMD_READY_INT;
> >> > > +	if (stat & TPM_STS_VALID)
> >> > > +		mask |= TPM_INTF_STS_VALID_INT;
> >> > > +	if (stat & TPM_STS_DATA_AVAIL)
> >> > > +		mask |= TPM_INTF_DATA_AVAIL_INT;
> >> > > +
> >> > > +	tpm_tis_enable_interrupt(chip, mask);
> >> > > +}
> >> > > +
> >> > >  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
> >> > >  					bool check_cancel, bool *canceled)
> >> > >  {
> >> > > @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
> >> > >  		timeout = stop - jiffies;
> >> > >  		if ((long)timeout <= 0)
> >> > >  			return -ETIME;
> >> > > +		tpm_tis_enable_stat_interrupts(chip, mask);
> >> > >  		rc = wait_event_interruptible_timeout(*queue,
> >> > >  			wait_for_tpm_stat_cond(chip, mask, check_cancel,
> >> > >  					       &canceled),
> >> > >  			timeout);
> >> > >  		if (rc > 0) {
> >> > > +			if (rc == 1)
> >> > > +				dev_err(&chip->dev, "Lost Interrupt waiting for TPM stat\n");
> >> > >  			if (canceled)
> >> > >  				return -ECANCELED;
> >> > >  			return 0;
> >> > > @@ -138,6 +181,28 @@ static bool check_locality(struct tpm_chip *chip, int l)
> >> > >  static int release_locality(struct tpm_chip *chip, int l)
> >> > >  {
> >> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> >> > > +	u32 int_status;
> >> > > +	int rc;
> >> > > +
> >> > > +	/*
> >> > > +	 * Note that once we relinquish the locality, all writes to
> >> > > +	 * the interrupt registers become ineffective meaning we can't
> >> > > +	 * do a TPM_EOI.  This means we must disable every interrupt
> >> > > +	 * except the locality change one to avoid interrupt
> >> > > +	 * storms.
> >> > > +	 */
> >> > > +	tpm_tis_disable_interrupt(chip, TPM_INTF_CMD_READY_INT
> >> > > +				  | TPM_INTF_STS_VALID_INT
> >> > > +				  | TPM_INTF_DATA_AVAIL_INT);
> >> > > +
> >> > > +	rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
> >> > > +	if (rc < 0)
> >> > > +		return rc;
> >> > > +
> >> > > +	/* Clear all pending */
> >> > > +	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
> >> > > +	if (rc < 0)
> >> > > +		return rc;
> >> > >  
> >> > >  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
> >> > >  
> >> > > @@ -164,12 +229,17 @@ static int request_locality(struct tpm_chip *chip, int l)
> >> > >  		timeout = stop - jiffies;
> >> > >  		if ((long)timeout <= 0)
> >> > >  			return -1;
> >> > > +
> >> > >  		rc = wait_event_interruptible_timeout(priv->int_queue,
> >> > >  						      (check_locality
> >> > >  						       (chip, l)),
> >> > >  						      timeout);
> >> > > -		if (rc > 0)
> >> > > +		if (rc > 1)
> >> > > +			return l;
> >> > > +		if (rc == 1) {
> >> > > +			dev_info(&chip->dev, "Lost Interrupt waiting for locality\n");
> >> > >  			return l;
> >> > > +		}
> >> > >  		if (rc == -ERESTARTSYS && freezing(current)) {
> >> > >  			clear_thread_flag(TIF_SIGPENDING);
> >> > >  			goto again;
> >> > > @@ -465,6 +535,10 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
> >> > >  	irq = priv->irq;
> >> > >  	priv->irq = 0;
> >> > >  	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> >> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_CMD_READY_INT
> >> > > +				 | TPM_INTF_LOCALITY_CHANGE_INT
> >> > > +				 | TPM_INTF_DATA_AVAIL_INT
> >> > > +				 | TPM_INTF_STS_VALID_INT);
> >> > >  	rc = tpm_tis_send_main(chip, buf, len);
> >> > >  	priv->irq = irq;
> >> > >  	chip->flags |= TPM_CHIP_FLAG_IRQ;
> >> > > @@ -719,7 +793,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
> >> > >   * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
> >> > >   * everything and leave in polling mode. Returns 0 on success.
> >> > >   */
> >> > > -static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> >> > > +static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
> >> > >  				    int flags, int irq)
> >> > >  {
> >> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> >> > > @@ -753,9 +827,11 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> >> > >  	if (rc < 0)
> >> > >  		return rc;
> >> > >  
> >> > > -	/* Turn on */
> >> > > -	rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
> >> > > -			     intmask | TPM_GLOBAL_INT_ENABLE);
> >> > > +	/*
> >> > > +	 * Turn on.  The locality change interrupt is the only one
> >> > > +	 * always enabled
> >> > > +	 */
> >> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
> >> > >  	if (rc < 0)
> >> > >  		return rc;
> >> > >  
> >> > > @@ -787,7 +863,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> >> > >   * do not have ACPI/etc. We typically expect the interrupt to be declared if
> >> > >   * present.
> >> > >   */
> >> > > -static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
> >> > > +static void tpm_tis_probe_irq(struct tpm_chip *chip)
> >> > >  {
> >> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> >> > >  	u8 original_int_vec;
> >> > > @@ -801,11 +877,9 @@ static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
> >> > >  	if (!original_int_vec) {
> >> > >  		if (IS_ENABLED(CONFIG_X86))
> >> > >  			for (i = 3; i <= 15; i++)
> >> > > -				if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> >> > > -							      i))
> >> > > +				if (!tpm_tis_probe_irq_single(chip, 0, i))
> >> > >  					return;
> >> > > -	} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> >> > > -					     original_int_vec))
> >> > > +	} else if (!tpm_tis_probe_irq_single(chip, 0, original_int_vec))
> >> > >  		return;
> >> > >  }
> >> > >  
> >> > > @@ -1030,8 +1104,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> >> > >  		}
> >> > >  
> >> > >  		if (irq) {
> >> > > -			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
> >> > > -						 irq);
> >> > > +			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
> >> > >  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
> >> > >  				dev_err(&chip->dev, FW_BUG
> >> > >  					"TPM interrupt not working, polling instead\n");
> >> > > @@ -1039,7 +1112,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
> >> > >  				disable_interrupts(chip);
> >> > >  			}
> >> > >  		} else {
> >> > > -			tpm_tis_probe_irq(chip, intmask);
> >> > > +			tpm_tis_probe_irq(chip);
> >> > >  		}
> >> > >  	}
> >> > >  
> >> > > @@ -1065,12 +1138,23 @@ EXPORT_SYMBOL_GPL(tpm_tis_core_init);
> >> > >  static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
> >> > >  {
> >> > >  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> >> > > -	u32 intmask;
> >> > >  	int rc;
> >> > >  
> >> > >  	if (chip->ops->clk_enable != NULL)
> >> > >  		chip->ops->clk_enable(chip, true);
> >> > >  
> >> > > +	/*
> >> > > +	 * must have the locality before we can enable interrupts, so
> >> > > +	 * poll for the locality being ready
> >> > > +	 */
> >> > > +	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> >> > > +	if (request_locality(chip, 0) != 0) {
> >> > > +		dev_err(&chip->dev, "Failed to enable interrupts after suspend\n");
> >> > > +		goto out;
> >> > > +	}
> >> > > +	chip->flags |= TPM_CHIP_FLAG_IRQ;
> >> > > +
> >> > > +
> >> > >  	/* reenable interrupts that device may have lost or
> >> > >  	 * BIOS/firmware may have disabled
> >> > >  	 */
> >> > > @@ -1078,17 +1162,10 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
> >> > >  	if (rc < 0)
> >> > >  		goto out;
> >> > >  
> >> > > -	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> >> > > -	if (rc < 0)
> >> > > -		goto out;
> >> > > -
> >> > > -	intmask |= TPM_INTF_CMD_READY_INT
> >> > > -	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
> >> > > -	    | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
> >> > > +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
> >> > >  
> >> > > -	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> >> > > -
> >> > > -out:
> >> > > + out:
> >> > > +	release_locality(chip, 0);
> >> > >  	if (chip->ops->clk_enable != NULL)
> >> > >  		chip->ops->clk_enable(chip, false);
> >> > 
> >> > Other than the question about the comment in tpm_tis_enable_interrupt
> >> > 
> >> > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> >> 
> >> Should this have
> >> 
> >>   Fixes: e6aef069b6e9 ("tpm_tis: convert to using locality callbacks")
> >> 
> >> ?
> >
> > ?
> >
> > /Jarkko
> 
> Yes, I believe so.

OK, let's have it in the next patch set version.

/Jarkko

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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-30 15:49         ` James Bottomley
  2020-10-30 16:11           ` Jerry Snitselaar
@ 2020-11-03  4:17           ` Jarkko Sakkinen
  1 sibling, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-11-03  4:17 UTC (permalink / raw)
  To: James Bottomley
  Cc: Jerry Snitselaar, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Fri, Oct 30, 2020 at 08:49:27AM -0700, James Bottomley wrote:
> On Fri, 2020-10-30 at 14:43 +0200, Jarkko Sakkinen wrote:
> [...]
> > I tested this with:
> > 
> > - 
> > https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
> >   dTPM 1.2
> > - 
> > https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
> >   dTPM 2.0
> > 
> > I did not get "TPM interrupt not working, polling instead" to klog.
> > But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?
> 
> That's usually what you get when ACPI specifies the interrupt isn't
> connected (we don't try to probe it).
> 
> James

Right, I'll test today with the same NUC's with "force=1".

/Jarkko

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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-30 16:11           ` Jerry Snitselaar
@ 2020-11-03  4:43             ` Jarkko Sakkinen
  2020-11-03 23:00               ` Jerry Snitselaar
  0 siblings, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-11-03  4:43 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Fri, Oct 30, 2020 at 09:11:30AM -0700, Jerry Snitselaar wrote:
> 
> James Bottomley @ 2020-10-30 08:49 MST:
> 
> > On Fri, 2020-10-30 at 14:43 +0200, Jarkko Sakkinen wrote:
> > [...]
> >> I tested this with:
> >> 
> >> - 
> >> https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
> >>   dTPM 1.2
> >> - 
> >> https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
> >>   dTPM 2.0
> >> 
> >> I did not get "TPM interrupt not working, polling instead" to klog.
> >> But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?
> >
> > That's usually what you get when ACPI specifies the interrupt isn't
> > connected (we don't try to probe it).
> >
> > James
> 
> That is the problem I've been running into. When I do find a system
> with a tpm and using tpm_tis, it usually seems to not have the interrupt
> connected.
> 
> Should this commit have:
> 
> Fixes: 570a36097f30 ("tpm: drop 'irq' from struct tpm_vendor_specific")
> 
> That is where TPM_CHIP_FLAG_IRQ was added and not set for tpm_tis.

Have you tested 4eea703caaac?

/Jarkko

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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-11-03  4:43             ` Jarkko Sakkinen
@ 2020-11-03 23:00               ` Jerry Snitselaar
  2020-11-04  0:31                 ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-11-03 23:00 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe


Jarkko Sakkinen @ 2020-11-02 21:43 MST:

> On Fri, Oct 30, 2020 at 09:11:30AM -0700, Jerry Snitselaar wrote:
>> 
>> James Bottomley @ 2020-10-30 08:49 MST:
>> 
>> > On Fri, 2020-10-30 at 14:43 +0200, Jarkko Sakkinen wrote:
>> > [...]
>> >> I tested this with:
>> >> 
>> >> - 
>> >> https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
>> >>   dTPM 1.2
>> >> - 
>> >> https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
>> >>   dTPM 2.0
>> >> 
>> >> I did not get "TPM interrupt not working, polling instead" to klog.
>> >> But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?
>> >
>> > That's usually what you get when ACPI specifies the interrupt isn't
>> > connected (we don't try to probe it).
>> >
>> > James
>> 
>> That is the problem I've been running into. When I do find a system
>> with a tpm and using tpm_tis, it usually seems to not have the interrupt
>> connected.
>> 
>> Should this commit have:
>> 
>> Fixes: 570a36097f30 ("tpm: drop 'irq' from struct tpm_vendor_specific")
>> 
>> That is where TPM_CHIP_FLAG_IRQ was added and not set for tpm_tis.
>
> Have you tested 4eea703caaac?
>
> /Jarkko

Is that the right commit id?

4eea703caaac tpm: drop 'iobase' from struct tpm_vendor_specific | 2016-06-25 | (Christophe Ricard)


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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-11-03 23:00               ` Jerry Snitselaar
@ 2020-11-04  0:31                 ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-11-04  0:31 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Tue, Nov 03, 2020 at 04:00:29PM -0700, Jerry Snitselaar wrote:
> 
> Jarkko Sakkinen @ 2020-11-02 21:43 MST:
> 
> > On Fri, Oct 30, 2020 at 09:11:30AM -0700, Jerry Snitselaar wrote:
> >> 
> >> James Bottomley @ 2020-10-30 08:49 MST:
> >> 
> >> > On Fri, 2020-10-30 at 14:43 +0200, Jarkko Sakkinen wrote:
> >> > [...]
> >> >> I tested this with:
> >> >> 
> >> >> - 
> >> >> https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
> >> >>   dTPM 1.2
> >> >> - 
> >> >> https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
> >> >>   dTPM 2.0
> >> >> 
> >> >> I did not get "TPM interrupt not working, polling instead" to klog.
> >> >> But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?
> >> >
> >> > That's usually what you get when ACPI specifies the interrupt isn't
> >> > connected (we don't try to probe it).
> >> >
> >> > James
> >> 
> >> That is the problem I've been running into. When I do find a system
> >> with a tpm and using tpm_tis, it usually seems to not have the interrupt
> >> connected.
> >> 
> >> Should this commit have:
> >> 
> >> Fixes: 570a36097f30 ("tpm: drop 'irq' from struct tpm_vendor_specific")
> >> 
> >> That is where TPM_CHIP_FLAG_IRQ was added and not set for tpm_tis.
> >
> > Have you tested 4eea703caaac?
> >
> > /Jarkko
> 
> Is that the right commit id?
> 
> 4eea703caaac tpm: drop 'iobase' from struct tpm_vendor_specific | 2016-06-25 | (Christophe Ricard)

Yeah.

/Jarkko

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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-10-30 12:43       ` Jarkko Sakkinen
  2020-10-30 15:49         ` James Bottomley
@ 2020-11-06 15:32         ` Jarkko Sakkinen
  2020-11-06 16:21           ` James Bottomley
  1 sibling, 1 reply; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-11-06 15:32 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: James Bottomley, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Fri, Oct 30, 2020 at 02:43:35PM +0200, Jarkko Sakkinen wrote:
> On Sat, Oct 24, 2020 at 03:17:18PM +0300, Jarkko Sakkinen wrote:
> > On Mon, Oct 19, 2020 at 04:41:35PM -0700, Jerry Snitselaar wrote:
> > > 
> > > James Bottomley @ 2020-10-01 11:09 MST:
> > > 
> > > > There are two problems with our current interrupt probing: firstly the
> > > > TPM_CHIP_FLAG_IRQ never gets set initially, so a check for interrupts
> > > > is never done.  Fix this by setting the flag before we generate and
> > > > interrupt for probing.  Secondly our IRQ setup may be ineffective on a
> > > > TPM without legacy access cycles becuase according to the TPM
> > > > Interface Specification the interrupt registers are only writeable in
> > > > the current locality, so issue a request_locality before setting up
> > > > the interrupts.
> > > >
> > > > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
> > > >
> > > > ---
> > > >
> > > > v2: improved description
> > > > ---
> > > >  drivers/char/tpm/tpm_tis_core.c | 14 ++++++++++++++
> > > >  1 file changed, 14 insertions(+)
> > > >
> > > > diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> > > > index 0c07da8cd680..12b657ed3a39 100644
> > > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > > @@ -809,6 +809,19 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
> > > >  	}
> > > >  	priv->irq = irq;
> > > >  
> > > > +	/*
> > > > +	 * note writes to the interrupt registers are only effective
> > > > +	 * when the TPM is in the active locality, so we have to
> > > > +	 * request the locality here to get the interrupt set up.
> > > > +	 * This request has no corresponding release, because the
> > > > +	 * locality will be relinquished at the end of the tpm command
> > > > +	 * that probes the interrupts
> > > > +	 */
> > > > +	if (request_locality(chip, 0) != 0) {
> > > > +		dev_err(&chip->dev, "failed to gain locality for irq probe\n");
> > > > +		return -EBUSY;
> > > > +	}
> > 
> > Appreciate the comment a lot, but s/note/Note/
> 
> I tested this with:
> 
> - https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
>   dTPM 1.2
> - https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
>   dTPM 2.0
> 
> I did not get "TPM interrupt not working, polling instead" to klog.
> But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?

With dTPM2 NUC, I ended up get this when I just pass 'irq=0' to
tpm_tis_core_init():

[    0.584421] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x1A, rev-id 16)
[    0.680417] genirq: Flags mismatch irq 7. 00000008 (tpm0) vs. 00040088 (INT3432:00)
[    0.680448] tpm tpm0: Unable to request irq: 7 for probe
[    0.704416] genirq: Flags mismatch irq 9. 00000000 (tpm0) vs. 00000080 (acpi)
[    0.704444] tpm tpm0: Unable to request irq: 9 for probe

/Jarkko

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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-11-06 15:32         ` Jarkko Sakkinen
@ 2020-11-06 16:21           ` James Bottomley
  2020-11-06 22:07             ` Jarkko Sakkinen
  0 siblings, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-11-06 16:21 UTC (permalink / raw)
  To: Jarkko Sakkinen, Jerry Snitselaar
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe

On Fri, 2020-11-06 at 17:32 +0200, Jarkko Sakkinen wrote:
> On Fri, Oct 30, 2020 at 02:43:35PM +0200, Jarkko Sakkinen wrote:
> > On Sat, Oct 24, 2020 at 03:17:18PM +0300, Jarkko Sakkinen wrote:
> > > On Mon, Oct 19, 2020 at 04:41:35PM -0700, Jerry Snitselaar wrote:
> > > > James Bottomley @ 2020-10-01 11:09 MST:
> > > > 
> > > > > There are two problems with our current interrupt probing:
> > > > > firstly the TPM_CHIP_FLAG_IRQ never gets set initially, so a
> > > > > check for interrupts is never done.  Fix this by setting the
> > > > > flag before we generate and interrupt for probing.  Secondly
> > > > > our IRQ setup may be ineffective on a TPM without legacy
> > > > > access cycles becuase according to the TPM Interface
> > > > > Specification the interrupt registers are only
> > > > > writeable in the current locality, so issue a
> > > > > request_locality before setting up the interrupts.
> > > > > 
> > > > > Signed-off-by: James Bottomley <
> > > > > James.Bottomley@HansenPartnership.com>
> > > > > 
> > > > > ---
> > > > > 
> > > > > v2: improved description
> > > > > ---
> > > > >  drivers/char/tpm/tpm_tis_core.c | 14 ++++++++++++++
> > > > >  1 file changed, 14 insertions(+)
> > > > > 
> > > > > diff --git a/drivers/char/tpm/tpm_tis_core.c
> > > > > b/drivers/char/tpm/tpm_tis_core.c
> > > > > index 0c07da8cd680..12b657ed3a39 100644
> > > > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > > > @@ -809,6 +809,19 @@ static int
> > > > > tpm_tis_probe_irq_single(struct tpm_chip *chip,
> > > > >  	}
> > > > >  	priv->irq = irq;
> > > > >  
> > > > > +	/*
> > > > > +	 * note writes to the interrupt registers are only
> > > > > effective
> > > > > +	 * when the TPM is in the active locality, so we have
> > > > > to
> > > > > +	 * request the locality here to get the interrupt set
> > > > > up.
> > > > > +	 * This request has no corresponding release, because
> > > > > the
> > > > > +	 * locality will be relinquished at the end of the tpm
> > > > > command
> > > > > +	 * that probes the interrupts
> > > > > +	 */
> > > > > +	if (request_locality(chip, 0) != 0) {
> > > > > +		dev_err(&chip->dev, "failed to gain locality
> > > > > for irq probe\n");
> > > > > +		return -EBUSY;
> > > > > +	}
> > > 
> > > Appreciate the comment a lot, but s/note/Note/
> > 
> > I tested this with:
> > 
> > - 
> > https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
> >   dTPM 1.2
> > - 
> > https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
> >   dTPM 2.0
> > 
> > I did not get "TPM interrupt not working, polling instead" to klog.
> > But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?
> 
> With dTPM2 NUC, I ended up get this when I just pass 'irq=0' to
> tpm_tis_core_init():
> 
> [    0.584421] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x1A, rev-id
> 16)
> [    0.680417] genirq: Flags mismatch irq 7. 00000008 (tpm0) vs.
> 00040088 (INT3432:00)
> [    0.680448] tpm tpm0: Unable to request irq: 7 for probe
> [    0.704416] genirq: Flags mismatch irq 9. 00000000 (tpm0) vs.
> 00000080 (acpi)
> [    0.704444] tpm tpm0: Unable to request irq: 9 for probe

Well this looks normal: you forced the tis subsystem to probe for an
IRQ even though ACPI says there isn't one and it didn't find one ... so
ACPI was actually right (for once).

James



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

* Re: [PATCH v2 4/5] tpm_tis: fix IRQ probing
  2020-11-06 16:21           ` James Bottomley
@ 2020-11-06 22:07             ` Jarkko Sakkinen
  0 siblings, 0 replies; 74+ messages in thread
From: Jarkko Sakkinen @ 2020-11-06 22:07 UTC (permalink / raw)
  To: James Bottomley
  Cc: Jerry Snitselaar, linux-integrity, Jason Gunthorpe,
	Jarkko Sakkinen, Peter Huewe

On Fri, Nov 06, 2020 at 08:21:44AM -0800, James Bottomley wrote:
> On Fri, 2020-11-06 at 17:32 +0200, Jarkko Sakkinen wrote:
> > On Fri, Oct 30, 2020 at 02:43:35PM +0200, Jarkko Sakkinen wrote:
> > > On Sat, Oct 24, 2020 at 03:17:18PM +0300, Jarkko Sakkinen wrote:
> > > > On Mon, Oct 19, 2020 at 04:41:35PM -0700, Jerry Snitselaar wrote:
> > > > > James Bottomley @ 2020-10-01 11:09 MST:
> > > > > 
> > > > > > There are two problems with our current interrupt probing:
> > > > > > firstly the TPM_CHIP_FLAG_IRQ never gets set initially, so a
> > > > > > check for interrupts is never done.  Fix this by setting the
> > > > > > flag before we generate and interrupt for probing.  Secondly
> > > > > > our IRQ setup may be ineffective on a TPM without legacy
> > > > > > access cycles becuase according to the TPM Interface
> > > > > > Specification the interrupt registers are only
> > > > > > writeable in the current locality, so issue a
> > > > > > request_locality before setting up the interrupts.
> > > > > > 
> > > > > > Signed-off-by: James Bottomley <
> > > > > > James.Bottomley@HansenPartnership.com>
> > > > > > 
> > > > > > ---
> > > > > > 
> > > > > > v2: improved description
> > > > > > ---
> > > > > >  drivers/char/tpm/tpm_tis_core.c | 14 ++++++++++++++
> > > > > >  1 file changed, 14 insertions(+)
> > > > > > 
> > > > > > diff --git a/drivers/char/tpm/tpm_tis_core.c
> > > > > > b/drivers/char/tpm/tpm_tis_core.c
> > > > > > index 0c07da8cd680..12b657ed3a39 100644
> > > > > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > > > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > > > > @@ -809,6 +809,19 @@ static int
> > > > > > tpm_tis_probe_irq_single(struct tpm_chip *chip,
> > > > > >  	}
> > > > > >  	priv->irq = irq;
> > > > > >  
> > > > > > +	/*
> > > > > > +	 * note writes to the interrupt registers are only
> > > > > > effective
> > > > > > +	 * when the TPM is in the active locality, so we have
> > > > > > to
> > > > > > +	 * request the locality here to get the interrupt set
> > > > > > up.
> > > > > > +	 * This request has no corresponding release, because
> > > > > > the
> > > > > > +	 * locality will be relinquished at the end of the tpm
> > > > > > command
> > > > > > +	 * that probes the interrupts
> > > > > > +	 */
> > > > > > +	if (request_locality(chip, 0) != 0) {
> > > > > > +		dev_err(&chip->dev, "failed to gain locality
> > > > > > for irq probe\n");
> > > > > > +		return -EBUSY;
> > > > > > +	}
> > > > 
> > > > Appreciate the comment a lot, but s/note/Note/
> > > 
> > > I tested this with:
> > > 
> > > - 
> > > https://ark.intel.com/content/www/us/en/ark/products/84861/intel-nuc-kit-nuc5i5myhe.html
> > >   dTPM 1.2
> > > - 
> > > https://ark.intel.com/content/www/us/en/ark/products/74483/intel-nuc-kit-dc53427hye.html
> > >   dTPM 2.0
> > > 
> > > I did not get "TPM interrupt not working, polling instead" to klog.
> > > But I neither see tpm0 in /proc/interrupts. What I'm doing wrong?
> > 
> > With dTPM2 NUC, I ended up get this when I just pass 'irq=0' to
> > tpm_tis_core_init():
> > 
> > [    0.584421] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x1A, rev-id
> > 16)
> > [    0.680417] genirq: Flags mismatch irq 7. 00000008 (tpm0) vs.
> > 00040088 (INT3432:00)
> > [    0.680448] tpm tpm0: Unable to request irq: 7 for probe
> > [    0.704416] genirq: Flags mismatch irq 9. 00000000 (tpm0) vs.
> > 00000080 (acpi)
> > [    0.704444] tpm tpm0: Unable to request irq: 9 for probe
> 
> Well this looks normal: you forced the tis subsystem to probe for an
> IRQ even though ACPI says there isn't one and it didn't find one ... so
> ACPI was actually right (for once).
> 
> James

True. I wanted to give quick feedback with the results, did not have
time to analyze at that point. Can you do one more round with remarks
fixed that I mentioned (if I recall right they were only about comments
and commit messages, code itself is in great condition), and you can add
my tested-by to each commit?

I'll put this then to my next rc request so that we get this to 5.10.

/Jarkko

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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-10-01 18:09 ` [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles James Bottomley
  2020-10-05 17:05   ` Jarkko Sakkinen
  2020-10-20  0:14   ` Jerry Snitselaar
@ 2020-12-01 18:12   ` Jerry Snitselaar
  2020-12-01 19:49     ` Jerry Snitselaar
  2 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-12-01 18:12 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-10-01 11:09 MST:

> If a TIS TPM doesn't have legacy cycles, any write to the interrupt
> registers is ignored unless a locality is active.  This means even to
> set up the interrupt vectors a locality must first be activated.  Fix
> this by activating the 0 locality in the interrupt probe setup.
>
> Since the TPM_EOI signalling also requires an active locality, the
> interrupt routine cannot end an interrupt if the locality is released.
> This can lead to a situation where the TPM goes command ready after
> locality release and since the interrupt cannot be ended it refires
> continuously.  Fix this by disabling all interrupts except locality
> change when a locality is released (this only fires when a locality
> becomes active, meaning the TPM_EOI should work).
>
> Finally, since we now disable all status based interrupts in the
> locality release, they must be re-enabled before waiting to check the
> condition, so add interrupt enabling to the status wait.
>
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>
> ---
>
> v2: renamed functions
> ---
>  drivers/char/tpm/tpm_tis_core.c | 125 ++++++++++++++++++++++++++------
>  1 file changed, 101 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index 431919d5f48a..0c07da8cd680 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -29,6 +29,46 @@
>  
>  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
>  
> +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8 mask)
> +{
> +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> +	u32 intmask;
> +
> +	/* Take control of the TPM's interrupt hardware and shut it off */
> +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> +
> +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
> +
> +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> +}
> +
> +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8 mask)
> +{
> +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> +	u32 intmask;
> +
> +	/* Take control of the TPM's interrupt hardware and shut it off */
> +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> +
> +	intmask &= ~mask;
> +
> +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> +}
> +
> +static void tpm_tis_enable_stat_interrupts(struct tpm_chip *chip, u8 stat)
> +{
> +	u32 mask = 0;
> +
> +	if (stat & TPM_STS_COMMAND_READY)
> +		mask |= TPM_INTF_CMD_READY_INT;
> +	if (stat & TPM_STS_VALID)
> +		mask |= TPM_INTF_STS_VALID_INT;
> +	if (stat & TPM_STS_DATA_AVAIL)
> +		mask |= TPM_INTF_DATA_AVAIL_INT;
> +
> +	tpm_tis_enable_interrupt(chip, mask);
> +}
> +
>  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
>  					bool check_cancel, bool *canceled)
>  {
> @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
>  		timeout = stop - jiffies;
>  		if ((long)timeout <= 0)
>  			return -ETIME;
> +		tpm_tis_enable_stat_interrupts(chip, mask);
>  		rc = wait_event_interruptible_timeout(*queue,
>  			wait_for_tpm_stat_cond(chip, mask, check_cancel,
>  					       &canceled),
>  			timeout);
>  		if (rc > 0) {
> +			if (rc == 1)
> +				dev_err(&chip->dev, "Lost Interrupt waiting for TPM stat\n");

With my proposed patch to check for the interrupt storm condition I
sometimes see this message. Do you think it would make sense to have a
check here and in the request_locality location to see that
TPM_CHIP_FLAG is still enabled? It will print a message about the
interrupt storm being detected, and switching to polling, so I don't
know if this will cause confusion for people to have this show up as
well in that case.

>  			if (canceled)
>  				return -ECANCELED;
>  			return 0;
> @@ -138,6 +181,28 @@ static bool check_locality(struct tpm_chip *chip, int l)
>  static int release_locality(struct tpm_chip *chip, int l)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> +	u32 int_status;
> +	int rc;
> +
> +	/*
> +	 * Note that once we relinquish the locality, all writes to
> +	 * the interrupt registers become ineffective meaning we can't
> +	 * do a TPM_EOI.  This means we must disable every interrupt
> +	 * except the locality change one to avoid interrupt
> +	 * storms.
> +	 */
> +	tpm_tis_disable_interrupt(chip, TPM_INTF_CMD_READY_INT
> +				  | TPM_INTF_STS_VALID_INT
> +				  | TPM_INTF_DATA_AVAIL_INT);
> +
> +	rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
> +	if (rc < 0)
> +		return rc;
> +
> +	/* Clear all pending */
> +	rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
> +	if (rc < 0)
> +		return rc;
>  
>  	tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
>  
> @@ -164,12 +229,17 @@ static int request_locality(struct tpm_chip *chip, int l)
>  		timeout = stop - jiffies;
>  		if ((long)timeout <= 0)
>  			return -1;
> +
>  		rc = wait_event_interruptible_timeout(priv->int_queue,
>  						      (check_locality
>  						       (chip, l)),
>  						      timeout);
> -		if (rc > 0)
> +		if (rc > 1)
> +			return l;
> +		if (rc == 1) {
> +			dev_info(&chip->dev, "Lost Interrupt waiting for locality\n");
>  			return l;
> +		}
>  		if (rc == -ERESTARTSYS && freezing(current)) {
>  			clear_thread_flag(TIF_SIGPENDING);
>  			goto again;
> @@ -465,6 +535,10 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  	irq = priv->irq;
>  	priv->irq = 0;
>  	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> +	tpm_tis_enable_interrupt(chip, TPM_INTF_CMD_READY_INT
> +				 | TPM_INTF_LOCALITY_CHANGE_INT
> +				 | TPM_INTF_DATA_AVAIL_INT
> +				 | TPM_INTF_STS_VALID_INT);
>  	rc = tpm_tis_send_main(chip, buf, len);
>  	priv->irq = irq;
>  	chip->flags |= TPM_CHIP_FLAG_IRQ;
> @@ -719,7 +793,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
>   * irq is seen then leave the chip setup for IRQ operation, otherwise reverse
>   * everything and leave in polling mode. Returns 0 on success.
>   */
> -static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> +static int tpm_tis_probe_irq_single(struct tpm_chip *chip,
>  				    int flags, int irq)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> @@ -753,9 +827,11 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
>  	if (rc < 0)
>  		return rc;
>  
> -	/* Turn on */
> -	rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
> -			     intmask | TPM_GLOBAL_INT_ENABLE);
> +	/*
> +	 * Turn on.  The locality change interrupt is the only one
> +	 * always enabled
> +	 */
> +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
>  	if (rc < 0)
>  		return rc;
>  
> @@ -787,7 +863,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
>   * do not have ACPI/etc. We typically expect the interrupt to be declared if
>   * present.
>   */
> -static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
> +static void tpm_tis_probe_irq(struct tpm_chip *chip)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>  	u8 original_int_vec;
> @@ -801,11 +877,9 @@ static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask)
>  	if (!original_int_vec) {
>  		if (IS_ENABLED(CONFIG_X86))
>  			for (i = 3; i <= 15; i++)
> -				if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> -							      i))
> +				if (!tpm_tis_probe_irq_single(chip, 0, i))
>  					return;
> -	} else if (!tpm_tis_probe_irq_single(chip, intmask, 0,
> -					     original_int_vec))
> +	} else if (!tpm_tis_probe_irq_single(chip, 0, original_int_vec))
>  		return;
>  }
>  
> @@ -1030,8 +1104,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>  		}
>  
>  		if (irq) {
> -			tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
> -						 irq);
> +			tpm_tis_probe_irq_single(chip, IRQF_SHARED, irq);
>  			if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
>  				dev_err(&chip->dev, FW_BUG
>  					"TPM interrupt not working, polling instead\n");
> @@ -1039,7 +1112,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>  				disable_interrupts(chip);
>  			}
>  		} else {
> -			tpm_tis_probe_irq(chip, intmask);
> +			tpm_tis_probe_irq(chip);
>  		}
>  	}
>  
> @@ -1065,12 +1138,23 @@ EXPORT_SYMBOL_GPL(tpm_tis_core_init);
>  static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
>  {
>  	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> -	u32 intmask;
>  	int rc;
>  
>  	if (chip->ops->clk_enable != NULL)
>  		chip->ops->clk_enable(chip, true);
>  
> +	/*
> +	 * must have the locality before we can enable interrupts, so
> +	 * poll for the locality being ready
> +	 */
> +	chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> +	if (request_locality(chip, 0) != 0) {
> +		dev_err(&chip->dev, "Failed to enable interrupts after suspend\n");
> +		goto out;
> +	}
> +	chip->flags |= TPM_CHIP_FLAG_IRQ;
> +
> +
>  	/* reenable interrupts that device may have lost or
>  	 * BIOS/firmware may have disabled
>  	 */
> @@ -1078,17 +1162,10 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
>  	if (rc < 0)
>  		goto out;
>  
> -	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> -	if (rc < 0)
> -		goto out;
> -
> -	intmask |= TPM_INTF_CMD_READY_INT
> -	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
> -	    | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
> +	tpm_tis_enable_interrupt(chip, TPM_INTF_LOCALITY_CHANGE_INT);
>  
> -	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> -
> -out:
> + out:
> +	release_locality(chip, 0);
>  	if (chip->ops->clk_enable != NULL)
>  		chip->ops->clk_enable(chip, false);



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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-12-01 18:12   ` Jerry Snitselaar
@ 2020-12-01 19:49     ` Jerry Snitselaar
  2020-12-01 21:06       ` James Bottomley
  0 siblings, 1 reply; 74+ messages in thread
From: Jerry Snitselaar @ 2020-12-01 19:49 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


Jerry Snitselaar @ 2020-12-01 11:12 MST:

> James Bottomley @ 2020-10-01 11:09 MST:
>
>> If a TIS TPM doesn't have legacy cycles, any write to the interrupt
>> registers is ignored unless a locality is active.  This means even to
>> set up the interrupt vectors a locality must first be activated.  Fix
>> this by activating the 0 locality in the interrupt probe setup.
>>
>> Since the TPM_EOI signalling also requires an active locality, the
>> interrupt routine cannot end an interrupt if the locality is released.
>> This can lead to a situation where the TPM goes command ready after
>> locality release and since the interrupt cannot be ended it refires
>> continuously.  Fix this by disabling all interrupts except locality
>> change when a locality is released (this only fires when a locality
>> becomes active, meaning the TPM_EOI should work).
>>
>> Finally, since we now disable all status based interrupts in the
>> locality release, they must be re-enabled before waiting to check the
>> condition, so add interrupt enabling to the status wait.
>>
>> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>>
>> ---
>>
>> v2: renamed functions
>> ---
>>  drivers/char/tpm/tpm_tis_core.c | 125 ++++++++++++++++++++++++++------
>>  1 file changed, 101 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
>> index 431919d5f48a..0c07da8cd680 100644
>> --- a/drivers/char/tpm/tpm_tis_core.c
>> +++ b/drivers/char/tpm/tpm_tis_core.c
>> @@ -29,6 +29,46 @@
>>  
>>  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
>>  
>> +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8 mask)
>> +{
>> +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> +	u32 intmask;
>> +
>> +	/* Take control of the TPM's interrupt hardware and shut it off */
>> +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
>> +
>> +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
>> +
>> +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
>> +}
>> +
>> +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8 mask)
>> +{
>> +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> +	u32 intmask;
>> +
>> +	/* Take control of the TPM's interrupt hardware and shut it off */
>> +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
>> +
>> +	intmask &= ~mask;
>> +
>> +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
>> +}
>> +
>> +static void tpm_tis_enable_stat_interrupts(struct tpm_chip *chip, u8 stat)
>> +{
>> +	u32 mask = 0;
>> +
>> +	if (stat & TPM_STS_COMMAND_READY)
>> +		mask |= TPM_INTF_CMD_READY_INT;
>> +	if (stat & TPM_STS_VALID)
>> +		mask |= TPM_INTF_STS_VALID_INT;
>> +	if (stat & TPM_STS_DATA_AVAIL)
>> +		mask |= TPM_INTF_DATA_AVAIL_INT;
>> +
>> +	tpm_tis_enable_interrupt(chip, mask);
>> +}
>> +
>>  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
>>  					bool check_cancel, bool *canceled)
>>  {
>> @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
>>  		timeout = stop - jiffies;
>>  		if ((long)timeout <= 0)
>>  			return -ETIME;
>> +		tpm_tis_enable_stat_interrupts(chip, mask);
>>  		rc = wait_event_interruptible_timeout(*queue,
>>  			wait_for_tpm_stat_cond(chip, mask, check_cancel,
>>  					       &canceled),
>>  			timeout);
>>  		if (rc > 0) {
>> +			if (rc == 1)
>> +				dev_err(&chip->dev, "Lost Interrupt waiting for TPM stat\n");
>
> With my proposed patch to check for the interrupt storm condition I
> sometimes see this message. Do you think it would make sense to have a
> check here and in the request_locality location to see that
> TPM_CHIP_FLAG is still enabled? It will print a message about the
> interrupt storm being detected, and switching to polling, so I don't
> know if this will cause confusion for people to have this show up as
> well in that case.
>

I guess it wouldn't be too confusing since the messages will appear
close together.


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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-12-01 19:49     ` Jerry Snitselaar
@ 2020-12-01 21:06       ` James Bottomley
  2020-12-01 21:47         ` Jerry Snitselaar
  0 siblings, 1 reply; 74+ messages in thread
From: James Bottomley @ 2020-12-01 21:06 UTC (permalink / raw)
  To: Jerry Snitselaar
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe

On Tue, 2020-12-01 at 12:49 -0700, Jerry Snitselaar wrote:
> Jerry Snitselaar @ 2020-12-01 11:12 MST:
> 
> > James Bottomley @ 2020-10-01 11:09 MST:
> > 
> > > If a TIS TPM doesn't have legacy cycles, any write to the
> > > interrupt
> > > registers is ignored unless a locality is active.  This means
> > > even to
> > > set up the interrupt vectors a locality must first be
> > > activated.  Fix
> > > this by activating the 0 locality in the interrupt probe setup.
> > > 
> > > Since the TPM_EOI signalling also requires an active locality,
> > > the
> > > interrupt routine cannot end an interrupt if the locality is
> > > released.
> > > This can lead to a situation where the TPM goes command ready
> > > after
> > > locality release and since the interrupt cannot be ended it
> > > refires
> > > continuously.  Fix this by disabling all interrupts except
> > > locality
> > > change when a locality is released (this only fires when a
> > > locality
> > > becomes active, meaning the TPM_EOI should work).
> > > 
> > > Finally, since we now disable all status based interrupts in the
> > > locality release, they must be re-enabled before waiting to check
> > > the
> > > condition, so add interrupt enabling to the status wait.
> > > 
> > > Signed-off-by: James Bottomley <
> > > James.Bottomley@HansenPartnership.com>
> > > 
> > > ---
> > > 
> > > v2: renamed functions
> > > ---
> > >  drivers/char/tpm/tpm_tis_core.c | 125
> > > ++++++++++++++++++++++++++------
> > >  1 file changed, 101 insertions(+), 24 deletions(-)
> > > 
> > > diff --git a/drivers/char/tpm/tpm_tis_core.c
> > > b/drivers/char/tpm/tpm_tis_core.c
> > > index 431919d5f48a..0c07da8cd680 100644
> > > --- a/drivers/char/tpm/tpm_tis_core.c
> > > +++ b/drivers/char/tpm/tpm_tis_core.c
> > > @@ -29,6 +29,46 @@
> > >  
> > >  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool
> > > value);
> > >  
> > > +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8
> > > mask)
> > > +{
> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > +	u32 intmask;
> > > +
> > > +	/* Take control of the TPM's interrupt hardware and shut it off
> > > */
> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> > > +
> > > +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
> > > +
> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> > > +}
> > > +
> > > +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8
> > > mask)
> > > +{
> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> > > +	u32 intmask;
> > > +
> > > +	/* Take control of the TPM's interrupt hardware and shut it off
> > > */
> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
> > > +
> > > +	intmask &= ~mask;
> > > +
> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
> > > +}
> > > +
> > > +static void tpm_tis_enable_stat_interrupts(struct tpm_chip
> > > *chip, u8 stat)
> > > +{
> > > +	u32 mask = 0;
> > > +
> > > +	if (stat & TPM_STS_COMMAND_READY)
> > > +		mask |= TPM_INTF_CMD_READY_INT;
> > > +	if (stat & TPM_STS_VALID)
> > > +		mask |= TPM_INTF_STS_VALID_INT;
> > > +	if (stat & TPM_STS_DATA_AVAIL)
> > > +		mask |= TPM_INTF_DATA_AVAIL_INT;
> > > +
> > > +	tpm_tis_enable_interrupt(chip, mask);
> > > +}
> > > +
> > >  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8
> > > mask,
> > >  					bool check_cancel, bool
> > > *canceled)
> > >  {
> > > @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip
> > > *chip, u8 mask,
> > >  		timeout = stop - jiffies;
> > >  		if ((long)timeout <= 0)
> > >  			return -ETIME;
> > > +		tpm_tis_enable_stat_interrupts(chip, mask);
> > >  		rc = wait_event_interruptible_timeout(*queue,
> > >  			wait_for_tpm_stat_cond(chip, mask,
> > > check_cancel,
> > >  					       &canceled),
> > >  			timeout);
> > >  		if (rc > 0) {
> > > +			if (rc == 1)
> > > +				dev_err(&chip->dev, "Lost Interrupt
> > > waiting for TPM stat\n");
> > 
> > With my proposed patch to check for the interrupt storm condition I
> > sometimes see this message. Do you think it would make sense to
> > have a check here and in the request_locality location to see that
> > TPM_CHIP_FLAG is still enabled? It will print a message about the
> > interrupt storm being detected, and switching to polling, so I
> > don't know if this will cause confusion for people to have this
> > show up as well in that case.
> > 
> 
> I guess it wouldn't be too confusing since the messages will appear
> close together.

But since we have a discriminator I'll try to use it and see if we can
tidy up the messages.  I think the condition just becomes

if (rc == 1 && (chip->flags & TPM_CHIP_FLAG_IRQ))

because you'll have reset that if you found a storm?

James



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

* Re: [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles
  2020-12-01 21:06       ` James Bottomley
@ 2020-12-01 21:47         ` Jerry Snitselaar
  0 siblings, 0 replies; 74+ messages in thread
From: Jerry Snitselaar @ 2020-12-01 21:47 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-integrity, Jason Gunthorpe, Jarkko Sakkinen, Peter Huewe


James Bottomley @ 2020-12-01 14:06 MST:

> On Tue, 2020-12-01 at 12:49 -0700, Jerry Snitselaar wrote:
>> Jerry Snitselaar @ 2020-12-01 11:12 MST:
>> 
>> > James Bottomley @ 2020-10-01 11:09 MST:
>> > 
>> > > If a TIS TPM doesn't have legacy cycles, any write to the
>> > > interrupt
>> > > registers is ignored unless a locality is active.  This means
>> > > even to
>> > > set up the interrupt vectors a locality must first be
>> > > activated.  Fix
>> > > this by activating the 0 locality in the interrupt probe setup.
>> > > 
>> > > Since the TPM_EOI signalling also requires an active locality,
>> > > the
>> > > interrupt routine cannot end an interrupt if the locality is
>> > > released.
>> > > This can lead to a situation where the TPM goes command ready
>> > > after
>> > > locality release and since the interrupt cannot be ended it
>> > > refires
>> > > continuously.  Fix this by disabling all interrupts except
>> > > locality
>> > > change when a locality is released (this only fires when a
>> > > locality
>> > > becomes active, meaning the TPM_EOI should work).
>> > > 
>> > > Finally, since we now disable all status based interrupts in the
>> > > locality release, they must be re-enabled before waiting to check
>> > > the
>> > > condition, so add interrupt enabling to the status wait.
>> > > 
>> > > Signed-off-by: James Bottomley <
>> > > James.Bottomley@HansenPartnership.com>
>> > > 
>> > > ---
>> > > 
>> > > v2: renamed functions
>> > > ---
>> > >  drivers/char/tpm/tpm_tis_core.c | 125
>> > > ++++++++++++++++++++++++++------
>> > >  1 file changed, 101 insertions(+), 24 deletions(-)
>> > > 
>> > > diff --git a/drivers/char/tpm/tpm_tis_core.c
>> > > b/drivers/char/tpm/tpm_tis_core.c
>> > > index 431919d5f48a..0c07da8cd680 100644
>> > > --- a/drivers/char/tpm/tpm_tis_core.c
>> > > +++ b/drivers/char/tpm/tpm_tis_core.c
>> > > @@ -29,6 +29,46 @@
>> > >  
>> > >  static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool
>> > > value);
>> > >  
>> > > +static void tpm_tis_enable_interrupt(struct tpm_chip *chip, u8
>> > > mask)
>> > > +{
>> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> > > +	u32 intmask;
>> > > +
>> > > +	/* Take control of the TPM's interrupt hardware and shut it off
>> > > */
>> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
>> > > +
>> > > +	intmask |= mask | TPM_GLOBAL_INT_ENABLE;
>> > > +
>> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
>> > > +}
>> > > +
>> > > +static void tpm_tis_disable_interrupt(struct tpm_chip *chip, u8
>> > > mask)
>> > > +{
>> > > +	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>> > > +	u32 intmask;
>> > > +
>> > > +	/* Take control of the TPM's interrupt hardware and shut it off
>> > > */
>> > > +	tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
>> > > +
>> > > +	intmask &= ~mask;
>> > > +
>> > > +	tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
>> > > +}
>> > > +
>> > > +static void tpm_tis_enable_stat_interrupts(struct tpm_chip
>> > > *chip, u8 stat)
>> > > +{
>> > > +	u32 mask = 0;
>> > > +
>> > > +	if (stat & TPM_STS_COMMAND_READY)
>> > > +		mask |= TPM_INTF_CMD_READY_INT;
>> > > +	if (stat & TPM_STS_VALID)
>> > > +		mask |= TPM_INTF_STS_VALID_INT;
>> > > +	if (stat & TPM_STS_DATA_AVAIL)
>> > > +		mask |= TPM_INTF_DATA_AVAIL_INT;
>> > > +
>> > > +	tpm_tis_enable_interrupt(chip, mask);
>> > > +}
>> > > +
>> > >  static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8
>> > > mask,
>> > >  					bool check_cancel, bool
>> > > *canceled)
>> > >  {
>> > > @@ -65,11 +105,14 @@ static int wait_for_tpm_stat(struct tpm_chip
>> > > *chip, u8 mask,
>> > >  		timeout = stop - jiffies;
>> > >  		if ((long)timeout <= 0)
>> > >  			return -ETIME;
>> > > +		tpm_tis_enable_stat_interrupts(chip, mask);
>> > >  		rc = wait_event_interruptible_timeout(*queue,
>> > >  			wait_for_tpm_stat_cond(chip, mask,
>> > > check_cancel,
>> > >  					       &canceled),
>> > >  			timeout);
>> > >  		if (rc > 0) {
>> > > +			if (rc == 1)
>> > > +				dev_err(&chip->dev, "Lost Interrupt
>> > > waiting for TPM stat\n");
>> > 
>> > With my proposed patch to check for the interrupt storm condition I
>> > sometimes see this message. Do you think it would make sense to
>> > have a check here and in the request_locality location to see that
>> > TPM_CHIP_FLAG is still enabled? It will print a message about the
>> > interrupt storm being detected, and switching to polling, so I
>> > don't know if this will cause confusion for people to have this
>> > show up as well in that case.
>> > 
>> 
>> I guess it wouldn't be too confusing since the messages will appear
>> close together.
>
> But since we have a discriminator I'll try to use it and see if we can
> tidy up the messages.  I think the condition just becomes
>
> if (rc == 1 && (chip->flags & TPM_CHIP_FLAG_IRQ))
>
> because you'll have reset that if you found a storm?
>
> James


Yes, the worker calls disable_interrupts() and that clears the flag.

Jerry


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

end of thread, other threads:[~2020-12-01 21:48 UTC | newest]

Thread overview: 74+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-01 18:09 [PATCH v2 0/5] tpm_tis: fix interrupts (again) James Bottomley
2020-10-01 18:09 ` [PATCH v2 1/5] tpm_tis: Fix check_locality for correct locality acquisition James Bottomley
2020-10-05 15:34   ` Jarkko Sakkinen
2020-10-05 19:00     ` James Bottomley
2020-10-05 20:32       ` Jarkko Sakkinen
2020-10-19 23:16   ` Jerry Snitselaar
2020-10-24 12:07     ` Jarkko Sakkinen
2020-10-30 12:13       ` Jarkko Sakkinen
2020-10-01 18:09 ` [PATCH v2 2/5] tpm_tis: Clean up locality release James Bottomley
2020-10-05 17:02   ` Jarkko Sakkinen
2020-10-05 19:05     ` James Bottomley
2020-10-05 20:34       ` Jarkko Sakkinen
2020-10-05 17:03   ` Jarkko Sakkinen
2020-10-19 23:17   ` Jerry Snitselaar
2020-10-24 12:10     ` Jarkko Sakkinen
2020-10-30 12:17       ` Jarkko Sakkinen
2020-10-30 15:47         ` James Bottomley
2020-10-30 21:52           ` Jarkko Sakkinen
2020-10-01 18:09 ` [PATCH v2 3/5] tpm_tis: Fix interrupts for TIS TPMs without legacy cycles James Bottomley
2020-10-05 17:05   ` Jarkko Sakkinen
2020-10-20  0:14   ` Jerry Snitselaar
2020-10-24 12:15     ` Jarkko Sakkinen
2020-10-30 12:18       ` Jarkko Sakkinen
2020-10-30 16:06         ` Jerry Snitselaar
2020-11-03  4:16           ` Jarkko Sakkinen
2020-12-01 18:12   ` Jerry Snitselaar
2020-12-01 19:49     ` Jerry Snitselaar
2020-12-01 21:06       ` James Bottomley
2020-12-01 21:47         ` Jerry Snitselaar
2020-10-01 18:09 ` [PATCH v2 4/5] tpm_tis: fix IRQ probing James Bottomley
2020-10-05 17:05   ` Jarkko Sakkinen
2020-10-19 23:41   ` Jerry Snitselaar
2020-10-24 12:17     ` Jarkko Sakkinen
2020-10-30 12:43       ` Jarkko Sakkinen
2020-10-30 15:49         ` James Bottomley
2020-10-30 16:11           ` Jerry Snitselaar
2020-11-03  4:43             ` Jarkko Sakkinen
2020-11-03 23:00               ` Jerry Snitselaar
2020-11-04  0:31                 ` Jarkko Sakkinen
2020-11-03  4:17           ` Jarkko Sakkinen
2020-11-06 15:32         ` Jarkko Sakkinen
2020-11-06 16:21           ` James Bottomley
2020-11-06 22:07             ` Jarkko Sakkinen
2020-10-01 18:09 ` [PATCH v2 5/5] Revert "tpm: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's"" James Bottomley
2020-10-19 20:23   ` Jerry Snitselaar
2020-10-19 22:54     ` James Bottomley
2020-10-19 23:40   ` Jerry Snitselaar
2020-10-12  5:39 ` [PATCH v2 0/5] tpm_tis: fix interrupts (again) Jerry Snitselaar
2020-10-13  1:23   ` Jarkko Sakkinen
2020-10-18  5:34     ` Jarkko Sakkinen
2020-10-13  1:17 ` Jarkko Sakkinen
2020-10-13 15:15   ` Jerry Snitselaar
2020-10-13 15:24     ` James Bottomley
2020-10-13 16:05       ` Jerry Snitselaar
2020-10-14 15:03         ` Hans de Goede
2020-10-14 15:23           ` James Bottomley
2020-10-14 16:04             ` Hans de Goede
2020-10-14 16:34               ` Jerry Snitselaar
2020-10-14 16:46                 ` Hans de Goede
2020-10-14 17:01                   ` Jerry Snitselaar
2020-10-14 17:04                     ` Jerry Snitselaar
2020-10-14 20:58                   ` Jerry Snitselaar
2020-10-15  7:38                     ` Hans de Goede
2020-10-18 21:09                       ` Jarkko Sakkinen
2020-10-15 15:36                     ` James Bottomley
2020-10-15 18:48                       ` Jerry Snitselaar
2020-10-15 18:57                         ` James Bottomley
2020-10-15 19:16                           ` Jerry Snitselaar
2020-10-14 16:49                 ` James Bottomley
2020-10-18 21:05     ` Jarkko Sakkinen
2020-10-20 23:10       ` Jerry Snitselaar
2020-10-24 12:20         ` Jarkko Sakkinen
2020-10-26 18:29           ` Jerry Snitselaar
2020-10-27 17:14             ` Jarkko Sakkinen

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.