From ebc242f78c52ef9de0e650bf48f64eb110351a4f Mon Sep 17 00:00:00 2001 From: David Windsor Date: Tue, 5 May 2026 16:27:38 -0400 Subject: tpm: svsm: constify tpm_chip_ops Constify the SVSM vTPM ops. It is statically initialized and never written to, so let's store it in .rodata. Every other tpm_class_ops instance in drivers/char/tpm/ is already const. Signed-off-by: David Windsor Reviewed-by: Stefano Garzarella Link: https://lore.kernel.org/r/20260505202738.145800-1-dwindsor@gmail.com Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_svsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm_svsm.c b/drivers/char/tpm/tpm_svsm.c index f5ba0f64850b..b74d60f687d5 100644 --- a/drivers/char/tpm/tpm_svsm.c +++ b/drivers/char/tpm/tpm_svsm.c @@ -49,7 +49,7 @@ static int tpm_svsm_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, return svsm_vtpm_cmd_response_parse(priv->buffer, buf, bufsiz); } -static struct tpm_class_ops tpm_chip_ops = { +static const struct tpm_class_ops tpm_chip_ops = { .flags = TPM_OPS_AUTO_STARTUP, .send = tpm_svsm_send, }; -- cgit v1.2.3 From de59d78e64039baa5fed455ddb905ba8263e7ede Mon Sep 17 00:00:00 2001 From: Baoli Zhang Date: Tue, 21 Apr 2026 08:50:20 +0800 Subject: tpm: restore timeout for key creation commands Commit 207696b17f38 ("tpm: use a map for tpm2_calc_ordinal_duration()") inadvertently reduced the timeout for TPM2 key creation commands (`CREATE_PRIMARY`, `CREATE`, `CREATE_LOADED`) from 300 seconds to 30 seconds. This causes intermittent timeout failures, with several failures observed across hundreds of test runs on some Intel platforms using Infineon SLB9670 and SLB9672 TPM modules. Restore the timeout to 300 seconds to avoid spurious failures. Cc: stable@vger.kernel.org # v6.18+ Fixes: 207696b17f38 ("tpm: use a map for tpm2_calc_ordinal_duration()") Co-developed-by: Lili Li Signed-off-by: Lili Li Signed-off-by: Baoli Zhang Link: https://lore.kernel.org/r/20260421005021.13765-1-baoli.zhang@linux.intel.com Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm2-cmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index b11e6fa8b740..52ee350da867 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -71,9 +71,9 @@ static const struct { {TPM2_CC_HIERARCHY_CHANGE_AUTH, 2000}, {TPM2_CC_GET_CAPABILITY, 750}, {TPM2_CC_NV_READ, 2000}, - {TPM2_CC_CREATE_PRIMARY, 30000}, - {TPM2_CC_CREATE, 30000}, - {TPM2_CC_CREATE_LOADED, 30000}, + {TPM2_CC_CREATE_PRIMARY, 300000}, + {TPM2_CC_CREATE, 300000}, + {TPM2_CC_CREATE_LOADED, 300000}, }; /** -- cgit v1.2.3 From 595ca21f797e43da24cb80529fb8b29381ed8716 Mon Sep 17 00:00:00 2001 From: Gunnar Kudrjavets Date: Sun, 10 May 2026 17:11:27 +0000 Subject: tpm: Initialize name_size_alg for non-NULL name in tpm_buf_append_name() tpm_buf_append_name() supports callers passing a pre-computed name for handles. When name is non-NULL, the code skips the tpm2_read_public() path but leaves name_size_alg uninitialized before it is used as the memcpy size argument. No current in-tree caller passes a non-NULL name, but future use cases such as name caching would exercise this path. Initialize name_size_alg by calling name_size() on the caller-provided name, sharing the error check and assignment with the existing tpm2_read_public() path. This prevents unmasking a latent bug when the non-NULL name path is eventually used. Assisted-by: Kiro:claude-opus-4.6 Reviewed-by: Justinien Bouron Reviewed-by: Muhammad Hammad Ijaz Signed-off-by: Gunnar Kudrjavets Link: https://lore.kernel.org/r/20260510171152.4607-1-gunnarku@amazon.com Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm2-sessions.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index c4da6fde748f..795cd99dc6fe 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -285,11 +285,14 @@ int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf, mso == TPM2_MSO_NVRAM) { if (!name) { ret = tpm2_read_public(chip, handle, auth->name[slot]); - if (ret < 0) - goto err; - - name_size_alg = ret; + } else { + ret = name_size(name); } + + if (ret < 0) + goto err; + + name_size_alg = ret; } else { if (name) { dev_err(&chip->dev, "handle 0x%08x does not use a name\n", -- cgit v1.2.3 From c0c9cfb3b75def8bf200a2d4db09015806acfeaf Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Sat, 9 May 2026 21:51:07 +0300 Subject: tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat() wait_event_interruptible_timeout() evaluates its condition after setting the current task state to TASK_INTERRUPTIBLE. With CONFIG_DEBUG_ATOMIC_SLEEP this triggers a warning when the IRQ wait path is used: tpm_tis_status() tpm_tis_spi_read_bytes() tpm_tis_spi_transfer_full() spi_bus_lock() mutex_lock() Address this with the following measures: 1. Call wait_tpm_stat_cond() only while tasking is running. 2. Use wait_woken() to wait for changes. Cc: stable@vger.kernel.org # v4.19+ Cc: Linus Walleij Reported-by: Stefan Wahren Closes: https://lore.kernel.org/linux-integrity/6964bec7-3dbb-453b-89ef-9b990217a8b9@gmx.net/ Fixes: 1a339b658d9d ("tpm_tis_spi: Pass the SPI IRQ down to the driver") Reviewed-by: Linus Walleij Tested-by: Stefan Wahren Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_tis_core.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 21d79ad3b164..153a57c79240 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -66,8 +66,8 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, bool check_cancel) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + DEFINE_WAIT_FUNC(wait, woken_wake_function); unsigned long stop; - long rc; u8 status; bool canceled = false; u8 sts_mask; @@ -87,23 +87,30 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, /* process status changes with irq support */ if (sts_mask) { ret = -ETIME; + add_wait_queue(queue, &wait); again: + if (wait_for_tpm_stat_cond(chip, sts_mask, check_cancel, + &canceled)) { + ret = canceled ? -ECANCELED : 0; + goto out; + } + timeout = stop - jiffies; if ((long)timeout <= 0) - return -ETIME; - rc = wait_event_interruptible_timeout(*queue, - wait_for_tpm_stat_cond(chip, sts_mask, check_cancel, - &canceled), - timeout); - if (rc > 0) { - if (canceled) - return -ECANCELED; - ret = 0; - } - if (rc == -ERESTARTSYS && freezing(current)) { - clear_thread_flag(TIF_SIGPENDING); - goto again; + goto out; + + if (signal_pending(current)) { + if (freezing(current)) { + clear_thread_flag(TIF_SIGPENDING); + goto again; + } + goto out; } + + wait_woken(&wait, TASK_INTERRUPTIBLE, timeout); + goto again; +out: + remove_wait_queue(queue, &wait); } if (ret) -- cgit v1.2.3 From ddd33806b8911fa2ef849e8bbbab1e3fcb26adc0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 May 2026 18:16:23 +0200 Subject: tpm_crb: Check ACPI_COMPANION() against NULL during probe Every platform driver can be forced to match a device that doesn't match its list of device IDs because of device_match_driver_override(), so platform drivers that rely on the existence of a device's ACPI companion object need to verify its presence. Accordingly, add a requisite ACPI_COMPANION() check against NULL to the tpm_crb driver. Fixes: 48fe2cddc85c ("tpm_crb: Convert ACPI driver to a platform one") Signed-off-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/2848144.mvXUDI8C0e@rafael.j.wysocki Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_crb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 7d1377e8e616..ceb4100ba400 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -786,8 +786,8 @@ static int crb_map_pluton(struct device *dev, struct crb_priv *priv, 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 acpi_device *device; struct crb_priv *priv; struct tpm_chip *chip; struct tpm2_crb_smc *crb_smc; @@ -797,6 +797,10 @@ static int crb_acpi_probe(struct platform_device *pdev) u32 sm; int rc; + device = ACPI_COMPANION(dev); + if (!device) + return -ENODEV; + status = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **) &buf); if (ACPI_FAILURE(status) || buf->header.length < sizeof(*buf)) { -- cgit v1.2.3 From c4d52950536bb421eaf11d83c0ba8612c443bb20 Mon Sep 17 00:00:00 2001 From: Jim Broadus Date: Tue, 26 May 2026 16:22:43 -0700 Subject: tpm: tpm_tis: store entire did_vid The entire 32 bit did_vid is read from the device, but only the 16 bit vendor id portion was stored in the tpm_tis_data structure. Storing the entire value allows the device id to be used to handle quirks. Printing the vid and did in the error case also helps identify problem devices. Signed-off-by: Jim Broadus Link: https://lore.kernel.org/r/20260526232245.5409-2-jbroadus@gmail.com Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_tis_core.c | 22 ++++++++++++++-------- drivers/char/tpm/tpm_tis_core.h | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 153a57c79240..3408b531d3b8 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -799,9 +799,10 @@ out: static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + u16 vendor_id = priv->did_vid; if (!test_bit(TPM_TIS_DEFAULT_CANCELLATION, &priv->flags)) { - switch (priv->manufacturer_id) { + switch (vendor_id) { case TPM_VID_WINBOND: return ((status == TPM_STS_VALID) || (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY))); @@ -1122,7 +1123,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, const struct tpm_tis_phy_ops *phy_ops, acpi_handle acpi_dev_handle) { - u32 vendor; + u16 vendor_id; + u16 device_id; u32 intfcaps; u32 intmask; u32 clkrun_val; @@ -1155,19 +1157,20 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, dev_set_drvdata(&chip->dev, priv); - rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); + rc = tpm_tis_read32(priv, TPM_DID_VID(0), &priv->did_vid); if (rc < 0) return rc; - priv->manufacturer_id = vendor; + vendor_id = priv->did_vid; + device_id = priv->did_vid >> 16; - if (priv->manufacturer_id == TPM_VID_ATML && + if (vendor_id == TPM_VID_ATML && !(chip->flags & TPM_CHIP_FLAG_TPM2)) { priv->timeout_min = TIS_TIMEOUT_MIN_ATML; priv->timeout_max = TIS_TIMEOUT_MAX_ATML; } - if (priv->manufacturer_id == TPM_VID_IFX) + if (vendor_id == TPM_VID_IFX) set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags); if (is_bsw()) { @@ -1254,9 +1257,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, if (rc < 0) goto out_err; - dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n", + dev_info(dev, "%s TPM (vendor-id 0x%X, device-id 0x%X, rev-id %d)\n", (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2", - vendor >> 16, rid); + vendor_id, device_id, rid); probe = probe_itpm(chip); if (probe < 0) { @@ -1322,6 +1325,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, return 0; out_err: + dev_err(dev, "TPM vid 0x%X, did 0x%X init failed with error %d\n", + vendor_id, device_id, rc); + if (chip->ops->clk_enable != NULL) chip->ops->clk_enable(chip, false); diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 6c3aa480396b..f2c77844062a 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -94,7 +94,7 @@ enum tpm_tis_flags { struct tpm_tis_data { struct tpm_chip *chip; - u16 manufacturer_id; + u32 did_vid; struct mutex locality_count_mutex; unsigned int locality_count; int locality; -- cgit v1.2.3 From 661f4d304960e3b093fae5211504e0e8c9fd4f23 Mon Sep 17 00:00:00 2001 From: Jim Broadus Date: Tue, 26 May 2026 16:22:44 -0700 Subject: tpm: tpm_tis: Add settle time for some TPMs Some TPMs fail to grant locality when requested immediately after being relinquished. In this case, the TPM_ACCESS_REQUEST_USE bit of the TPM_ACCESS register is cleared immediately without setting TPM_ACCESS_ACTIVE_LOCALITY. This issue can be seen at boot since tpm_chip_start, called right after locality is relinquished, will fail. This causes the probe to fail: tpm_tis MSFT0101:00: probe with driver tpm_tis failed with error -1 This occurs on some older Dell Latitudes. For the Nuvoton TPM used in these machines, add a delay after locality is relinquished. Signed-off-by: Jim Broadus Link: https://lore.kernel.org/r/20260526232245.5409-3-jbroadus@gmail.com Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_tis_core.c | 6 ++++++ drivers/char/tpm/tpm_tis_core.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 3408b531d3b8..143ef160820e 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -178,6 +178,9 @@ static int __tpm_tis_relinquish_locality(struct tpm_tis_data *priv, int l) { tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); + if (test_bit(TPM_TIS_SETTLE_AFTER_RELINQUISH, &priv->flags)) + tpm_msleep(TPM_TIMEOUT); + return 0; } @@ -1173,6 +1176,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, if (vendor_id == TPM_VID_IFX) set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags); + if (vendor_id == TPM_VID_WINBOND && device_id == 0x00FE) + set_bit(TPM_TIS_SETTLE_AFTER_RELINQUISH, &priv->flags); + if (is_bsw()) { priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, ILB_REMAP_SIZE); diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index f2c77844062a..aa6d78898ef3 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -90,6 +90,7 @@ enum tpm_tis_flags { TPM_TIS_DEFAULT_CANCELLATION = 2, TPM_TIS_IRQ_TESTED = 3, TPM_TIS_STATUS_VALID_RETRY = 4, + TPM_TIS_SETTLE_AFTER_RELINQUISH = 5, }; struct tpm_tis_data { -- cgit v1.2.3 From 73851a7c43dfa52d2ed9415889b33daf85da0ed9 Mon Sep 17 00:00:00 2001 From: Michael Bommarito Date: Sun, 31 May 2026 08:44:28 -0400 Subject: tpm: tpm2-sessions: wait for async KPP completion in tpm_buf_append_salt tpm_buf_append_salt() in drivers/char/tpm/tpm2-sessions.c calls crypto_kpp_generate_public_key() and crypto_kpp_compute_shared_secret() without installing a completion callback, discards both return values, and immediately frees the kpp_request via kpp_request_free(). When the resolved ecdh-nist-p256 KPP backend is asynchronous (atmel-ecc, HPRE, keembay-ocs), either operation returns -EINPROGRESS and the deferred completion worker dereferences the freed request. The path fires automatically from the hwrng_fillfn kernel thread via tpm_get_random -> tpm2_get_random -> tpm2_start_auth_session -> tpm_buf_append_salt on every entropy poll, without any userland action. Install crypto_req_done as the completion callback, wrap both KPP operations in crypto_wait_req(), and propagate errors to the caller. The wait is a no-op for synchronous backends. Fixes: 1085b8276bb4 ("tpm: Add the rest of the session HMAC API") Cc: stable@vger.kernel.org # v6.10+ Signed-off-by: Michael Bommarito Assisted-by: Claude:claude-opus-4-7 Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm2-sessions.c | 45 ++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 795cd99dc6fe..a1ae5e1829cb 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -492,15 +492,17 @@ static void tpm2_KDFe(u8 z[EC_PT_SZ], const char *str, u8 *pt_u, u8 *pt_v, sha256_final(&sctx, out); } -static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, - struct tpm2_auth *auth) +static int tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, + struct tpm2_auth *auth) { struct crypto_kpp *kpp; struct kpp_request *req; + DECLARE_CRYPTO_WAIT(wait); struct scatterlist s[2], d[1]; struct ecdh p = {0}; u8 encoded_key[EC_PT_SZ], *x, *y; unsigned int buf_len; + int rc; /* secret is two sized points */ tpm_buf_append_u16(buf, (EC_PT_SZ + 2)*2); @@ -523,14 +525,15 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, kpp = crypto_alloc_kpp("ecdh-nist-p256", CRYPTO_ALG_INTERNAL, 0); if (IS_ERR(kpp)) { dev_err(&chip->dev, "crypto ecdh allocation failed\n"); - return; + return PTR_ERR(kpp); } buf_len = crypto_ecdh_key_len(&p); if (sizeof(encoded_key) < buf_len) { dev_err(&chip->dev, "salt buffer too small needs %d\n", buf_len); - goto out; + rc = -EINVAL; + goto err_free_kpp; } crypto_ecdh_encode_key(encoded_key, buf_len, &p); /* this generates a random private key */ @@ -538,11 +541,17 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, /* salt is now the public point of this private key */ req = kpp_request_alloc(kpp, GFP_KERNEL); - if (!req) - goto out; + if (!req) { + rc = -ENOMEM; + goto err_free_kpp; + } + kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + crypto_req_done, &wait); kpp_request_set_input(req, NULL, 0); kpp_request_set_output(req, s, EC_PT_SZ*2); - crypto_kpp_generate_public_key(req); + rc = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait); + if (rc) + goto err_free_req; /* * we're not done: now we have to compute the shared secret * which is our private key multiplied by the tpm_key public @@ -554,8 +563,9 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, kpp_request_set_input(req, s, EC_PT_SZ*2); sg_init_one(d, auth->salt, EC_PT_SZ); kpp_request_set_output(req, d, EC_PT_SZ); - crypto_kpp_compute_shared_secret(req); - kpp_request_free(req); + rc = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait); + if (rc) + goto err_free_req; /* * pass the shared secret through KDFe for salt. Note salt @@ -565,8 +575,16 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, */ tpm2_KDFe(auth->salt, "SECRET", x, chip->null_ec_key_x, auth->salt); - out: + kpp_request_free(req); crypto_free_kpp(kpp); + return 0; + +err_free_req: + kpp_request_free(req); + +err_free_kpp: + crypto_free_kpp(kpp); + return rc; } /** @@ -1021,7 +1039,12 @@ int tpm2_start_auth_session(struct tpm_chip *chip) tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce)); /* append encrypted salt and squirrel away unencrypted in auth */ - tpm_buf_append_salt(&buf, chip, auth); + rc = tpm_buf_append_salt(&buf, chip, auth); + if (rc) { + tpm2_flush_context(chip, null_key); + tpm_buf_destroy(&buf); + goto out; + } /* session type (HMAC, audit or policy) */ tpm_buf_append_u8(&buf, TPM2_SE_HMAC); -- cgit v1.2.3 From 677042afb97ac5057e1d2900139f123bb15ba6e6 Mon Sep 17 00:00:00 2001 From: Yeoreum Yun Date: Fri, 5 Jun 2026 15:43:25 +0100 Subject: tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in commit 746d9e9f62a6 ("tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's built-in") probe tpm_crb_ffa forcefully when it's built-in to integrate with IMA. However, IMA now provides the IMA_INIT_LATE_SYNC build option, which initialises IMA at the late_initcall_sync level, so this change is no longer required. Signed-off-by: Yeoreum Yun Link: https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git/commit/?h=for-next/ffa/updates&id=cc7e8f21b9f0c229d68cf19a837cba82b5ac2d87 [0] Link: https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git/commit/?h=for-next/ffa/updates&id=e659fc8e537c7a21d5d693d6f30d8852f2fa8d91 [1] Link: https://lore.kernel.org/r/20260605144325.434436-5-yeoreum.yun@arm.com Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_crb_ffa.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/char/tpm/tpm_crb_ffa.c b/drivers/char/tpm/tpm_crb_ffa.c index 99f1c1e5644b..025c4d4b17ca 100644 --- a/drivers/char/tpm/tpm_crb_ffa.c +++ b/drivers/char/tpm/tpm_crb_ffa.c @@ -177,23 +177,13 @@ static int tpm_crb_ffa_to_linux_errno(int errno) */ int tpm_crb_ffa_init(void) { - int ret = 0; - - if (!IS_MODULE(CONFIG_TCG_ARM_CRB_FFA)) { - ret = ffa_register(&tpm_crb_ffa_driver); - if (ret) { - tpm_crb_ffa = ERR_PTR(-ENODEV); - return ret; - } - } - if (!tpm_crb_ffa) - ret = -ENOENT; + return -ENOENT; if (IS_ERR_VALUE(tpm_crb_ffa)) - ret = -ENODEV; + return -ENODEV; - return ret; + return 0; } EXPORT_SYMBOL_GPL(tpm_crb_ffa_init); @@ -405,9 +395,7 @@ static struct ffa_driver tpm_crb_ffa_driver = { .id_table = tpm_crb_ffa_device_id, }; -#ifdef MODULE module_ffa_driver(tpm_crb_ffa_driver); -#endif MODULE_AUTHOR("Arm"); MODULE_DESCRIPTION("TPM CRB FFA driver"); -- cgit v1.2.3 From 1a58f6115bfb34eabcc7de8a3a9745b219179781 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 15 Jun 2026 15:02:05 +0300 Subject: tpm: fix event_size output in tpm1_binary_bios_measurements_show Commit 186d124f07da ("tpm_eventlog.c: fix binary_bios_measurements") split the output to write the endian-converted event header first and then the variable-length event data. However, the split was at sizeof(struct tcpa_event) - 1, even though event_data was a zero-length array, and later a flexible array member, both of which already excluded the event data. Therefore, the current code writes the first three bytes of event_size from the endian-converted header and then the last byte from the raw header, which can emit a corrupted event_size on PPC64, where do_endian_conversion() maps to be32_to_cpu(). Split one byte later to write the full endian-converted header first, followed by the variable-length event->event_data. Fixes: 186d124f07da ("tpm_eventlog.c: fix binary_bios_measurements") Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Thorsten Blum Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/eventlog/tpm1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/eventlog/tpm1.c b/drivers/char/tpm/eventlog/tpm1.c index e7913b2853d5..0397e3361020 100644 --- a/drivers/char/tpm/eventlog/tpm1.c +++ b/drivers/char/tpm/eventlog/tpm1.c @@ -236,12 +236,12 @@ static int tpm1_binary_bios_measurements_show(struct seq_file *m, void *v) temp_ptr = (char *) &temp_event; - for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++) + for (i = 0; i < sizeof(struct tcpa_event); i++) seq_putc(m, temp_ptr[i]); temp_ptr = (char *) v; - for (i = (sizeof(struct tcpa_event) - 1); + for (i = sizeof(struct tcpa_event); i < (sizeof(struct tcpa_event) + temp_event.event_size); i++) seq_putc(m, temp_ptr[i]); -- cgit v1.2.3