[PATCH 2/4] tpm: get locality before writing to TPM chip

From: Lino Sanfilippo
Date: Sun Feb 21 2021 - 19:59:07 EST


When running with TPM chips like the SLB 9670VQ2.0 the TPM drivers probe
function prints the following warning:

TPM returned invalid status
WARNING: CPU: 3 PID: 1416 at drivers/char/tpm/tpm_tis_core.c:249 tpm_tis_status+0xbc/0xc8 [tpm_tis_core]
Modules linked in: tpm_tis_spi tpm_tis_core tpm spi_bcm2835 sha256_generic cfg80211 rfkill 8021q garp stp llc spidev v3d gpu_sched raspberrypi_hwmon vc4 cec drm_kms_helper bcm2835_codec(C) drm v4l2_mem2mem drm_panel_orientation_quirks bcm2835_v4l2(C) bcm2835_isp(C) videobuf2_dma_contig snd_soc_core bcm2835_mmal_vchiq(C) snd_bcm2835(C) videobuf2_vmalloc snd_compress videobuf2_memops videobuf2_v4l2 snd_pcm_dmaengine videobuf2_common snd_pcm snd_timer videodev vc_sm_cma(C) mc snd syscopyarea sysfillrect sysimgblt fb_sys_fops backlight rpivid_mem uio_pdrv_genirq uio ip_tables x_tables ipv6 [last unloaded: tpm]
CPU: 3 PID: 1416 Comm: kworker/u8:2 Tainted: G WC 5.10.5-LS-HOME+ #1
Hardware name: Raspberry Pi Compute Module 4 Rev 1.0 (DT)
Workqueue: events_unbound async_run_entry_fn
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
pc : tpm_tis_status+0xbc/0xc8 [tpm_tis_core]
lr : tpm_tis_status+0xbc/0xc8 [tpm_tis_core]
sp : ffffffc0120a38f0
x29: ffffffc0120a38f0 x28: ffffffc011238000
x27: 0000000000000016 x26: 000000000000017a
x25: 0000000000000014 x24: ffffff80497f9000
x23: 0000000000000000 x22: 0000000000000016
x21: ffffff8045680080 x20: 0000000000000000
x19: ffffffc011238000 x18: ffffffc011238948
x17: 0000000000000000 x16: 0000000000000000
x15: ffffffc011437c50 x14: ffffffffffffffff
x13: ffffffc0114378a6 x12: ffffffffffffffff
x11: ffffff807fbde5f0 x10: 0000000000000007
x9 : ffffffc0120a38f0 x8 : 6174732064696c61
x7 : 0000000000000000 x6 : ffffffc011239000
x5 : ffffff807fbc78e0 x4 : 0000000000000000
x3 : 0000000000000027 x2 : 0000000000000000
x1 : 670c5477f4483200 x0 : 0000000000000000
Call trace:
tpm_tis_status+0xbc/0xc8 [tpm_tis_core]
tpm_tis_send_data+0x58/0x250 [tpm_tis_core]
tpm_tis_send_main+0x50/0x128 [tpm_tis_core]
tpm_tis_send+0x4c/0x128 [tpm_tis_core]
tpm_transmit+0xd0/0x350 [tpm]
tpm_transmit_cmd+0x3c/0xc0 [tpm]
tpm2_get_tpm_pt+0x124/0x1e8 [tpm]
tpm_tis_probe_irq_single+0x17c/0x388 [tpm_tis_core]
tpm_tis_core_init+0x2e0/0x4f8 [tpm_tis_core]
tpm_tis_spi_init+0x5c/0x78 [tpm_tis_spi]
tpm_tis_spi_probe+0x80/0x98 [tpm_tis_spi]
tpm_tis_spi_driver_probe+0x4c/0x60 [tpm_tis_spi]
spi_drv_probe+0x84/0xf0
really_probe+0x118/0x420
driver_probe_device+0x5c/0xc0
__driver_attach_async_helper+0x64/0x68
async_run_entry_fn+0x48/0x150
process_one_work+0x15c/0x4d0
worker_thread+0x50/0x490
kthread+0x118/0x150
ret_from_fork+0x10/0x18
---[ end trace 209c86815cd15eab ]---

The reason is the attempt to read TPM 2.0 properties from the hardware
while the concerning locality has not been maintained before.

To avoid this issue and the need to request and release the locality
multiple times during driver initialization, and since the driver only
supports the legacy locality 0, request it once at driver startup
and only release it at driver shutdown.

Signed-off-by: Lino Sanfilippo <LinoSanfilippo@xxxxxx>
---
drivers/char/tpm/tpm-chip.c | 10 ----------
drivers/char/tpm/tpm_tis_core.c | 16 +++++++++-------
2 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index ddaeceb..5eb63f2 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -103,17 +103,8 @@ int tpm_chip_start(struct tpm_chip *chip)

tpm_clk_enable(chip);

- if (chip->locality == -1) {
- ret = tpm_request_locality(chip);
- if (ret) {
- tpm_clk_disable(chip);
- return ret;
- }
- }
-
ret = tpm_cmd_ready(chip);
if (ret) {
- tpm_relinquish_locality(chip);
tpm_clk_disable(chip);
return ret;
}
@@ -133,7 +124,6 @@ EXPORT_SYMBOL_GPL(tpm_chip_start);
void tpm_chip_stop(struct tpm_chip *chip)
{
tpm_go_idle(chip);
- tpm_relinquish_locality(chip);
tpm_clk_disable(chip);
}
EXPORT_SYMBOL_GPL(tpm_chip_stop);
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 2c956a1..e2f8585 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -670,9 +670,6 @@ static int probe_itpm(struct tpm_chip *chip)
if (vendor != TPM_VID_INTEL)
return 0;

- if (request_locality(chip, 0) != 0)
- return -EBUSY;
-
rc = tpm_tis_send_data(chip, cmd_getticks, len);
if (rc == 0)
goto out;
@@ -691,7 +688,6 @@ static int probe_itpm(struct tpm_chip *chip)

out:
tpm_tis_ready(chip);
- release_locality(chip, priv->locality);

return rc;
}
@@ -870,6 +866,7 @@ void tpm_tis_remove(struct tpm_chip *chip)

tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt);

+ release_locality(chip, 0);
tpm_tis_clkrun_enable(chip, false);

if (priv->ilb_base_addr)
@@ -997,6 +994,14 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
goto out_err;
}

+ rc = request_locality(chip, 0);
+ if (rc)
+ goto out_err;
+
+ rc = tpm_chip_start(chip);
+ if (rc)
+ goto out_err;
+
/* Take control of the TPM's interrupt hardware and shut it off */
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
if (rc < 0)
@@ -1007,9 +1012,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
intmask &= ~TPM_GLOBAL_INT_ENABLE;
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);

- rc = tpm_chip_start(chip);
- if (rc)
- goto out_err;
rc = tpm2_probe(chip);
tpm_chip_stop(chip);
if (rc)
--
2.7.4