diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-26 02:20:52 +0300 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-26 02:20:52 +0300 |
| commit | 1d9f1b5e4374c6b40df1a56b35901312ec98c9af (patch) | |
| tree | d4619174e5c8572a61a0d3b103abd776bb509a29 /drivers | |
| parent | 897d54018cc9aa97fd1529ca08a53b429d05a566 (diff) | |
| parent | 949692da7211572fac419b2986b6abc0cd1aeb76 (diff) | |
| download | linux-1d9f1b5e4374c6b40df1a56b35901312ec98c9af.tar.xz | |
Merge tag 'for-next-tpm-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull tpm updates from Jarkko Sakkinen:
"Here are the accumulated fixes for 7.1-rc1 and a single structural
change worth mentioning separately: Rafael's commit converting tpm_crb
from ACPI driver to a platform driver"
* tag 'for-next-tpm-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
tpm: tpm_tis: stop transmit if retries are exhausted
tpm: tpm_tis: add error logging for data transfer
tpm: avoid -Wunused-but-set-variable
tpm: Use kfree_sensitive() to free auth session in tpm_dev_release()
tpm2-sessions: Fix missing tpm_buf_destroy() in tpm2_read_public()
tpm: Fix auth session leak in tpm2_get_random() error path
tpm: i2c: atmel: fix block comment formatting
tpm_crb: Convert ACPI driver to a platform one
tpm: Make tcpci_pm_ops variable static const
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/char/tpm/tpm-chip.c | 2 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm2-cmd.c | 8 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm2-sessions.c | 5 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_crb.c | 35 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_i2c_atmel.c | 34 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_tis_core.c | 11 |
6 files changed, 57 insertions, 38 deletions
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 0719577e584d..12b7394b34bd 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -247,7 +247,7 @@ static void tpm_dev_release(struct device *dev) kfree(chip->work_space.context_buf); kfree(chip->work_space.session_buf); #ifdef CONFIG_TCG_TPM2_HMAC - kfree(chip->auth); + kfree_sensitive(chip->auth); #endif kfree(chip); } diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 3a77be7ebf4a..b11e6fa8b740 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -21,7 +21,7 @@ static bool disable_pcr_integrity; module_param(disable_pcr_integrity, bool, 0444); MODULE_PARM_DESC(disable_pcr_integrity, "Disable integrity protection of TPM2_PCR_Extend"); -struct tpm2_hash tpm2_hash_map[] = { +static const struct tpm2_hash tpm2_hash_map[] = { {HASH_ALGO_SHA1, TPM_ALG_SHA1}, {HASH_ALGO_SHA256, TPM_ALG_SHA256}, {HASH_ALGO_SHA384, TPM_ALG_SHA384}, @@ -295,10 +295,8 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) } tpm_buf_append_u16(&buf, num_bytes); err = tpm_buf_fill_hmac_session(chip, &buf); - if (err) { - tpm_buf_destroy(&buf); - return err; - } + if (err) + goto out; err = tpm_transmit_cmd(chip, &buf, offsetof(struct tpm2_get_random_out, diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 3b1cf1ca0420..c4da6fde748f 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -203,8 +203,10 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name) rc = tpm_buf_read_u16(&buf, &offset); name_size_alg = name_size(&buf.data[offset]); - if (name_size_alg < 0) + if (name_size_alg < 0) { + tpm_buf_destroy(&buf); return name_size_alg; + } if (rc != name_size_alg) { tpm_buf_destroy(&buf); @@ -217,6 +219,7 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name) } memcpy(name, &buf.data[offset], rc); + tpm_buf_destroy(&buf); return name_size_alg; } #endif /* CONFIG_TCG_TPM2_HMAC */ diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 6c25305c256e..7d1377e8e616 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -15,6 +15,7 @@ #include <linux/highmem.h> #include <linux/rculist.h> #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #ifdef CONFIG_ARM64 #include <linux/arm-smccc.h> @@ -602,13 +603,13 @@ static u64 crb_fixup_cmd_size(struct device *dev, struct resource *io_res, return io_res->end - start + 1; } -static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, +static int crb_map_io(struct device *dev, struct crb_priv *priv, struct acpi_table_tpm2 *buf) { + struct acpi_device *device = ACPI_COMPANION(dev); struct list_head acpi_resource_list; struct resource iores_array[TPM_CRB_MAX_RESOURCES + 1] = { {0} }; void __iomem *iobase_array[TPM_CRB_MAX_RESOURCES] = {NULL}; - struct device *dev = &device->dev; struct resource *iores; void __iomem **iobase_ptr; int i; @@ -782,12 +783,13 @@ static int crb_map_pluton(struct device *dev, struct crb_priv *priv, return 0; } -static int crb_acpi_add(struct acpi_device *device) +static int crb_acpi_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; + struct acpi_device *device = ACPI_COMPANION(dev); struct acpi_table_tpm2 *buf; struct crb_priv *priv; struct tpm_chip *chip; - struct device *dev = &device->dev; struct tpm2_crb_smc *crb_smc; struct tpm2_crb_ffa *crb_ffa; struct tpm2_crb_pluton *crb_pluton; @@ -867,7 +869,7 @@ static int crb_acpi_add(struct acpi_device *device) priv->sm = sm; priv->hid = acpi_device_hid(device); - rc = crb_map_io(device, priv, buf); + rc = crb_map_io(dev, priv, buf); if (rc) goto out; @@ -901,12 +903,9 @@ out: return rc; } -static void crb_acpi_remove(struct acpi_device *device) +static void crb_acpi_remove(struct platform_device *pdev) { - struct device *dev = &device->dev; - struct tpm_chip *chip = dev_get_drvdata(dev); - - tpm_chip_unregister(chip); + tpm_chip_unregister(platform_get_drvdata(pdev)); } static const struct dev_pm_ops crb_pm = { @@ -919,19 +918,17 @@ static const struct acpi_device_id crb_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, crb_device_ids); -static struct acpi_driver crb_acpi_driver = { - .name = "tpm_crb", - .ids = crb_device_ids, - .ops = { - .add = crb_acpi_add, - .remove = crb_acpi_remove, - }, - .drv = { +static struct platform_driver crb_acpi_driver = { + .probe = crb_acpi_probe, + .remove = crb_acpi_remove, + .driver = { + .name = "tpm_crb_acpi", + .acpi_match_table = crb_device_ids, .pm = &crb_pm, }, }; -module_acpi_driver(crb_acpi_driver); +module_platform_driver(crb_acpi_driver); MODULE_AUTHOR("Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>"); MODULE_DESCRIPTION("TPM2 Driver"); MODULE_VERSION("0.1"); diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index 4f229656a8e2..9fd73049821f 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c @@ -31,9 +31,11 @@ struct priv_data { size_t len; - /* This is the amount we read on the first try. 25 was chosen to fit a + /* + * This is the amount we read on the first try. 25 was chosen to fit a * fair number of read responses in the buffer so a 2nd retry can be - * avoided in small message cases. */ + * avoided in small message cases. + */ u8 buffer[sizeof(struct tpm_header) + 25]; }; @@ -58,7 +60,9 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, if (status < 0) return status; - /* The upper layer does not support incomplete sends. */ + /* + * The upper layer does not support incomplete sends. + */ if (status != len) return -E2BIG; @@ -76,9 +80,11 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count) if (priv->len == 0) return -EIO; - /* Get the message size from the message header, if we didn't get the + /* + * Get the message size from the message header, if we didn't get the * whole message in read_status then we need to re-read the - * message. */ + * message. + */ expected_len = be32_to_cpu(hdr->length); if (expected_len > count) return -ENOMEM; @@ -111,15 +117,19 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip) struct i2c_client *client = to_i2c_client(chip->dev.parent); int rc; - /* The TPM fails the I2C read until it is ready, so we do the entire + /* + * The TPM fails the I2C read until it is ready, so we do the entire * transfer here and buffer it locally. This way the common code can - * properly handle the timeouts. */ + * properly handle the timeouts. + */ priv->len = 0; memset(priv->buffer, 0, sizeof(priv->buffer)); - /* Once the TPM has completed the command the command remains readable - * until another command is issued. */ + /* + * Once the TPM has completed the command the command remains readable + * until another command is issued. + */ rc = i2c_master_recv(client, priv->buffer, sizeof(priv->buffer)); dev_dbg(&chip->dev, "%s: sts=%d", __func__, rc); @@ -172,9 +182,11 @@ static int i2c_atmel_probe(struct i2c_client *client) dev_set_drvdata(&chip->dev, priv); - /* There is no known way to probe for this device, and all version + /* + * There is no known way to probe for this device, and all version * information seems to be read via TPM commands. Thus we rely on the - * TPM startup process in the common code to detect the device. */ + * TPM startup process in the common code to detect the device. + */ return tpm_chip_register(chip); } diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index e2a1769081b1..21d79ad3b164 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -471,6 +471,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len) status = tpm_tis_status(chip); if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { rc = -EIO; + dev_err(&chip->dev, "TPM_STS_DATA_EXPECT should be set. sts = 0x%08x\n", + status); goto out_err; } } @@ -491,6 +493,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len) status = tpm_tis_status(chip); if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) { rc = -EIO; + dev_err(&chip->dev, "TPM_STS_DATA_EXPECT should be unset. sts = 0x%08x\n", + status); goto out_err; } @@ -552,11 +556,16 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len) break; else if (rc != -EAGAIN && rc != -EIO) /* Data transfer failed, not recoverable */ - return rc; + goto out_err; usleep_range(priv->timeout_min, priv->timeout_max); } + if (rc == -EAGAIN || rc == -EIO) { + dev_err(&chip->dev, "Exhausted %d tpm_tis_send_data retries\n", TPM_RETRY); + goto out_err; + } + /* go and do it */ rc = tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_GO); if (rc < 0) |
