Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 1/1] tpm: tpm_crb_ffa: Only register driver when ACPI TPM2 uses FF-A
@ 2026-11-12 23:38 Siddharth Chintamaneni
  0 siblings, 0 replies; only message in thread
From: Siddharth Chintamaneni @ 2026-11-12 23:38 UTC (permalink / raw)
  To: Peter Huewe, Jarkko Sakkinen
  Cc: Jason Gunthorpe, Sudeep Holla, Yeoreum Yun, Stuart Yoder, apais,
	rlmenge, hargar, linux-integrity, linux-arm-kernel, linux-kernel,
	Siddharth Chintamaneni, stable

Prior to commit 677042afb97a ("tpm: tpm_crb_ffa: revert defered_probed
when tpm_crb_ffa is built-in"), built-in tpm_crb_ffa only registered
tpm_crb_ffa_driver from tpm_crb_ffa_init() after crb_acpi_probe()
confirmed start_method == ACPI_TPM2_CRB_WITH_ARM_FFA. After that
commit, tpm_crb_ffa unconditionally registers on the FF-A bus at
device_initcall time (and when loaded as a module) without checking
the platform's ACPI TPM2 table.

A platform's firmware may expose a TPM CRB over FF-A Secure Partition
for UEFI boot services while advertising a non-FF-A start method to
the OS in the ACPI TPM2 table. When the ACPI TPM2 table designates a
non-FF-A start method, Linux has no consumer for tpm_crb_ffa and
should not probe the FF-A TPM service.

On Microsoft Cobalt 200 systems, the ACPI TPM2 table does not use
ACPI_TPM2_CRB_WITH_ARM_FFA, yet ffa_init() discovers the FF-A TPM
partition and tpm_crb_ffa_probe() unconditionally sends
CRB_FFA_GET_INTERFACE_VERSION via FFA_MSG_SEND_DIRECT_REQ2/REQ SMC.
That request wedges the calling CPU in Secure World (with Non-Secure
interrupts and GICv3 pseudo-NMIs masked), hanging boot with an RCU CPU
stall:

  [    5.507519] ARM FF-A: Driver version 1.2
  [    5.507519] ARM FF-A: Firmware version 1.2 found
  [    5.507551] ARM FF-A: Notification setup failed -61, not enabled
  [    7.150580] Freeing initrd memory: 293640K
  [   65.515248] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
  [   65.521346] rcu:     10-...0: (3 GPs behind) idle=dd9c/1/0x4000000000000000 softirq=37/37 fqs=5262
  [   65.530031] rcu:              hardirqs   softirqs   csw/system
  [   65.535589] rcu:      number:        0          0            0
  [   65.541146] rcu:     cputime:        0          0            0   ==> 30028(ms)
  [   65.548102] rcu:     (detected by 66, t=15010 jiffies, g=-951, q=1384 ncpus=132)
  [   65.555228] Sending NMI from CPU 66 to CPUs 10:
  [   75.560686] After 10 seconds, these CPUS still haven't responded to the NMI: 10

Check the ACPI TPM2 table in tpm_crb_ffa_driver_init() and return
-ENODEV before calling ffa_register() unless the table is present and
specifies ACPI_TPM2_CRB_WITH_ARM_FFA, matching the check_acpi_tpm2()
pattern in tpm_tis.c. This ensures Linux only issues FF-A TPM requests
when ACPI advertises the FF-A start method (for both built-in and
modular builds), while preserving normal FF-A bus probing on platforms
that use CRB over FF-A.

Fixes: 677042afb97a ("tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in")
Fixes: eb93f0734ef1 ("tpm_crb: ffa_tpm: Implement driver compliant to CRB over FF-A")
Cc: stable@vger.kernel.org
Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@gmail.com>
---
 drivers/char/tpm/tpm_crb_ffa.c | 37 +++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm_crb_ffa.c b/drivers/char/tpm/tpm_crb_ffa.c
index 025c4d4b17ca..8219a8d01344 100644
--- a/drivers/char/tpm/tpm_crb_ffa.c
+++ b/drivers/char/tpm/tpm_crb_ffa.c
@@ -9,6 +9,7 @@
 
 #define pr_fmt(fmt) "CRB_FFA: " fmt
 
+#include <linux/acpi.h>
 #include <linux/arm_ffa.h>
 #include <linux/delay.h>
 #include <linux/moduleparam.h>
@@ -395,7 +396,41 @@ static struct ffa_driver tpm_crb_ffa_driver = {
 	.id_table = tpm_crb_ffa_device_id,
 };
 
-module_ffa_driver(tpm_crb_ffa_driver);
+static bool __init tpm_crb_ffa_has_acpi_tpm2(void)
+{
+	struct acpi_table_tpm2 *buf;
+	acpi_status status;
+	bool match;
+
+	if (acpi_disabled)
+		return false;
+
+	status = acpi_get_table(ACPI_SIG_TPM2, 1,
+				(struct acpi_table_header **)&buf);
+	if (ACPI_FAILURE(status))
+		return false;
+
+	match = buf->header.length >= sizeof(*buf) &&
+		buf->start_method == ACPI_TPM2_CRB_WITH_ARM_FFA;
+	acpi_put_table((struct acpi_table_header *)buf);
+
+	return match;
+}
+
+static int __init tpm_crb_ffa_driver_init(void)
+{
+	if (!tpm_crb_ffa_has_acpi_tpm2())
+		return -ENODEV;
+
+	return ffa_register(&tpm_crb_ffa_driver);
+}
+module_init(tpm_crb_ffa_driver_init);
+
+static void __exit tpm_crb_ffa_driver_exit(void)
+{
+	ffa_unregister(&tpm_crb_ffa_driver);
+}
+module_exit(tpm_crb_ffa_driver_exit);
 
 MODULE_AUTHOR("Arm");
 MODULE_DESCRIPTION("TPM CRB FFA driver");
-- 
2.45.4



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-12 23:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-12 23:38 [PATCH v1 1/1] tpm: tpm_crb_ffa: Only register driver when ACPI TPM2 uses FF-A Siddharth Chintamaneni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox