From: Jarkko Sakkinen <jarkko@kernel.org>
To: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Cc: peterhuewe@gmx.de, jgg@ziepe.ca, stefanb@linux.vnet.ibm.com,
James.Bottomley@hansenpartnership.com, keescook@chromium.org,
jsnitsel@redhat.com, ml.linux@elloe.vision,
linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 3/4] tpm: Fix test for interrupts
Date: Mon, 3 May 2021 18:52:28 +0300 [thread overview]
Message-ID: <YJAcPAbFopeW7PYs@kernel.org> (raw)
In-Reply-To: <20210501135727.17747-4-LinoSanfilippo@gmx.de>
On Sat, May 01, 2021 at 03:57:26PM +0200, Lino Sanfilippo wrote:
> The current test for functional interrupts is broken in multiple ways:
> 1. The needed flag TPM_CHIP_FLAG_IRQ is never set, so the test is never
> executed.
> 2. The test includes the check for two variables and the check is done for
> each transmission which is unnecessarily complicated.
Unnecessary complicated is again terminolgy that I don't decipher,
unfortunately. I get "something that works" or "has a regression".
We don't polish things for nothing.
> 3. Part of the test is setting a bool variable in an interrupt handler and
> then check the value in the main thread. However there is nothing that
> guarantees the visibility of the value set in the interrupt handler for
> any other thread. Some kind of synchronization primitive is required for this purpose.
>
> Fix all these issues by a reimplementation:
> Instead of doing the test in tpm_tis_send() which is called for each
> transmission do it only once in tpm_tis_probe_irq_single(). Furthermore
> use proper accessor functions like get_bit()/set_bit() which include the
> required synchronization primitives to guarantee visibility between the
> interrupt handler and threads.
> Finally remove one function which is no longer needed.
>
> Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Not sure why to take this patch.
> ---
> drivers/char/tpm/tpm_tis_core.c | 61 ++++++++++-----------------------
> drivers/char/tpm/tpm_tis_core.h | 1 -
> include/linux/tpm.h | 2 +-
> 3 files changed, 20 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
> index f892b1ae46f2..9615234054aa 100644
> --- a/drivers/char/tpm/tpm_tis_core.c
> +++ b/drivers/char/tpm/tpm_tis_core.c
> @@ -420,7 +420,7 @@ static void disable_interrupts(struct tpm_chip *chip)
> * tpm.c can skip polling for the data to be available as the interrupt is
> * waited for here
> */
> -static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> +static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
> {
> struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> int rc;
> @@ -453,29 +453,6 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
> return rc;
> }
>
> -static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
> -{
> - int rc, irq;
> - struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
> -
> - if (!(chip->flags & TPM_CHIP_FLAG_IRQ) || priv->irq_tested)
> - return tpm_tis_send_main(chip, buf, len);
> -
> - /* Verify receipt of the expected IRQ */
> - irq = priv->irq;
> - priv->irq = 0;
> - chip->flags &= ~TPM_CHIP_FLAG_IRQ;
> - rc = tpm_tis_send_main(chip, buf, len);
> - priv->irq = irq;
> - chip->flags |= TPM_CHIP_FLAG_IRQ;
> - if (!priv->irq_tested)
> - tpm_msleep(1);
> - if (!priv->irq_tested)
> - disable_interrupts(chip);
> - priv->irq_tested = true;
> - return rc;
> -}
> -
> struct tis_vendor_durations_override {
> u32 did_vid;
> struct tpm1_version version;
> @@ -677,7 +654,8 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
> if (interrupt == 0)
> return IRQ_NONE;
>
> - priv->irq_tested = true;
> + set_bit(TPM_CHIP_FLAG_IRQ, &chip->flags);
> +
> if (interrupt & TPM_INTF_DATA_AVAIL_INT)
> wake_up_interruptible(&priv->read_queue);
> if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
> @@ -734,45 +712,44 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
> }
> priv->irq = irq;
>
> + clear_bit(TPM_CHIP_FLAG_IRQ, &chip->flags);
> +
> rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality),
> &original_int_vec);
> if (rc < 0)
> - return rc;
> + goto out;
>
> rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq);
> if (rc < 0)
> - return rc;
> + goto out;
>
> rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status);
> if (rc < 0)
> - return rc;
> + goto out;
>
> /* Clear all existing */
> rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status);
> if (rc < 0)
> - return rc;
> + goto out;
>
> /* Turn on */
> rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality),
> intmask | TPM_GLOBAL_INT_ENABLE);
> if (rc < 0)
> - return rc;
> -
> - priv->irq_tested = false;
> + goto out;
>
> - /* Generate an interrupt by having the core call through to
> - * tpm_tis_send
> - */
> + /* Generate an interrupt by transmitting a command to the chip */
> rc = tpm_tis_gen_interrupt(chip);
> if (rc < 0)
> - return rc;
> + goto out;
> +
> + tpm_msleep(1);
> +out:
> + if (!test_bit(TPM_CHIP_FLAG_IRQ, &chip->flags)) {
> + disable_interrupts(chip);
>
> - /* tpm_tis_send will either confirm the interrupt is working or it
> - * will call disable_irq which undoes all of the above.
> - */
> - if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
> rc = tpm_tis_write8(priv, original_int_vec,
> - TPM_INT_VECTOR(priv->locality));
> + TPM_INT_VECTOR(priv->locality));
> if (rc < 0)
> return rc;
>
> @@ -1039,7 +1016,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);
> - if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
> + if (!test_bit(TPM_CHIP_FLAG_IRQ, &chip->flags)) {
> dev_err(&chip->dev, FW_BUG
> "TPM interrupt not working, polling instead\n");
>
> diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
> index 9b2d32a59f67..dc5f92b18dca 100644
> --- a/drivers/char/tpm/tpm_tis_core.h
> +++ b/drivers/char/tpm/tpm_tis_core.h
> @@ -89,7 +89,6 @@ struct tpm_tis_data {
> u16 manufacturer_id;
> int locality;
> int irq;
> - bool irq_tested;
> unsigned int flags;
> void __iomem *ilb_base_addr;
> u16 clkrun_enabled;
> diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> index 7a68832b14bb..c57d0f0395f0 100644
> --- a/include/linux/tpm.h
> +++ b/include/linux/tpm.h
> @@ -133,7 +133,7 @@ struct tpm_chip {
> struct tpm_chip_seqops bin_log_seqops;
> struct tpm_chip_seqops ascii_log_seqops;
>
> - unsigned int flags;
> + unsigned long flags;
>
> int dev_num; /* /dev/tpm# */
> unsigned long is_open; /* only one allowed */
> --
> 2.31.1
>
/Jarkko
next prev parent reply other threads:[~2021-05-03 15:52 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-01 13:57 [PATCH v3 0/4] Fixes for TPM interrupt handling Lino Sanfilippo
2021-05-01 13:57 ` [PATCH v3 1/4] tpm: Use a threaded interrupt handler Lino Sanfilippo
2021-05-03 15:14 ` Jarkko Sakkinen
2021-05-04 22:54 ` Lino Sanfilippo
2021-05-06 1:46 ` Jarkko Sakkinen
2021-05-01 13:57 ` [PATCH v3 2/4] tpm: Simplify locality handling Lino Sanfilippo
2021-05-03 15:50 ` Jarkko Sakkinen
2021-05-04 23:15 ` Lino Sanfilippo
2021-05-06 1:47 ` Jarkko Sakkinen
2022-03-24 17:04 ` [PATCH v3 0/4] Fixes for TPM interrupt handling Michael Niewöhner
2022-03-25 2:14 ` Jarkko Sakkinen
2022-03-25 12:32 ` Michael Niewöhner
2022-03-26 3:24 ` Lino Sanfilippo
2022-03-26 8:59 ` Michael Niewöhner
2022-03-30 15:19 ` Jarkko Sakkinen
2022-04-20 5:30 ` Jarkko Sakkinen
2022-04-20 5:32 ` Jarkko Sakkinen
2022-04-24 2:22 ` Lino Sanfilippo
2022-04-25 13:57 ` Jarkko Sakkinen
2022-03-30 15:18 ` Jarkko Sakkinen
2021-05-01 13:57 ` [PATCH v3 3/4] tpm: Fix test for interrupts Lino Sanfilippo
2021-05-03 15:52 ` Jarkko Sakkinen [this message]
2021-05-04 23:18 ` Lino Sanfilippo
2021-05-01 13:57 ` [PATCH v3 4/4] tpm: Only enable supported irqs Lino Sanfilippo
2021-05-01 19:09 ` Stefan Berger
2021-05-02 3:15 ` Lino Sanfilippo
2021-05-03 15:52 ` Jarkko Sakkinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YJAcPAbFopeW7PYs@kernel.org \
--to=jarkko@kernel.org \
--cc=James.Bottomley@hansenpartnership.com \
--cc=LinoSanfilippo@gmx.de \
--cc=jgg@ziepe.ca \
--cc=jsnitsel@redhat.com \
--cc=keescook@chromium.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ml.linux@elloe.vision \
--cc=peterhuewe@gmx.de \
--cc=stefanb@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).