lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1ca3a53d-2b83-7522-5ce1-83d9cc2f207d@linux.ibm.com>
Date:   Thu, 25 Jun 2020 10:56:43 -0400
From:   Stefan Berger <stefanb@...ux.ibm.com>
To:     Jerry Snitselaar <jsnitsel@...hat.com>,
        linux-integrity <linux-integrity@...r.kernel.org>,
        Jarkko Sakkinen <jarkko.sakkinen@...ux.intel.com>
Cc:     LSM List <linux-security-module@...r.kernel.org>,
        LKML <linux-kernel@...r.kernel.org>
Subject: Enabling interrupts in QEMU TPM TIS

Hello!

  I want to enable IRQs now in QEMU's TPM TIS device model and I need to 
work with the following patch to Linux TIS. I am wondering whether the 
changes there look reasonable to you? Windows works with the QEMU 
modifications as-is, so maybe it's a bug in the TIS code (which I had 
not run into before).


The point of the loop I need to introduce in the interrupt handler is 
that while the interrupt handler is running another interrupt may 
occur/be posted that then does NOT cause the interrupt handler to be 
invoked again but causes a stall, unless the loop is there.

The 'o' in the dmesg log indicates the original IRQ for which the 
handler was invoked. The interrupt values have the following meaning.

0x2: STS valid

0x4: locality changed

0x80: command ready

So the first 'looping entry' [in log below] indicates that a locality 
change interrupt occurred while the interrupt handler was running due to 
STS_valid + command ready. This sounds reasonable considering that we 
are frequently acquiring and releasing the locality. The loop then deals 
with the locality change interrupt and the interrupts then settle.

[  210.365129] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x1, rev-id 1)
[  210.367124] looping: 0x4  (o: 0x82)
[  212.375045] looping: 0x80  (o: 0x2)
[  212.389218] looping: 0x4  (o: 0x82)
[  212.404161] looping: 0x80  (o: 0x2)
[  212.526427] looping: 0x4  (o: 0x82)
[  212.595488] looping: 0x4  (o: 0x82)
[  212.614357] looping: 0x80  (o: 0x2)

diff --git a/drivers/char/tpm/tpm_tis_core.c 
b/drivers/char/tpm/tpm_tis_core.c
index 65ab1b027949..f77544563fb1 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -704,7 +704,7 @@ static irqreturn_t tis_int_handler(int dummy, void 
*dev_id)
  {
      struct tpm_chip *chip = dev_id;
      struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
-    u32 interrupt;
+    u32 interrupt, o;
      int i, rc;

      rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
@@ -715,6 +715,7 @@ static irqreturn_t tis_int_handler(int dummy, void 
*dev_id)
          return IRQ_NONE;

      priv->irq_tested = true;
+again:
      if (interrupt & TPM_INTF_DATA_AVAIL_INT)
          wake_up_interruptible(&priv->read_queue);
      if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
@@ -731,7 +732,12 @@ static irqreturn_t tis_int_handler(int dummy, void 
*dev_id)
      if (rc < 0)
          return IRQ_NONE;

+    o = interrupt;
      tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt);
+    if (interrupt != 0) {
+        printk("looping: 0x%x  (o: 0x%x)\n", interrupt, o);
+        goto again;
+    }
      return IRQ_HANDLED;
  }

@@ -1062,6 +1068,8 @@ int tpm_tis_core_init(struct device *dev, struct 
tpm_tis_data *priv, int irq,
              goto out_err;
          }

+        tpm_chip_start(chip);
+        chip->flags |= TPM_CHIP_FLAG_IRQ;
          if (irq) {
              tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
                           irq);
@@ -1074,6 +1082,7 @@ int tpm_tis_core_init(struct device *dev, struct 
tpm_tis_data *priv, int irq,
          } else {
              tpm_tis_probe_irq(chip, intmask);
          }
+        tpm_chip_stop(chip);
      }

      rc = tpm_chip_register(chip);
-- 
2.26.2

    Stefan

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ