]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's built-in
authorYeoreum Yun <yeoreum.yun@arm.com>
Sat, 19 Jul 2025 10:27:46 +0000 (13:27 +0300)
committerJarkko Sakkinen <jarkko@kernel.org>
Tue, 22 Jul 2025 23:23:18 +0000 (02:23 +0300)
To generate the boot_aggregate log in the IMA subsystem using TPM PCR
values, the TPM driver must be built as built-in and must be probed
before the IMA subsystem is initialized.

However, when the TPM device operates over the FF-A protocol using the
CRB interface, probing fails and returns -EPROBE_DEFER if the
tpm_crb_ffa device — an FF-A device that provides the communication
interface to the tpm_crb driver — has not yet been probed.

This issue occurs because both crb_acpi_driver_init() and
tpm_crb_ffa_driver_init() are registered with device_initcall.  As a
result, crb_acpi_driver_init() may be invoked before
tpm_crb_ffa_driver_init(), which is responsible for probing the
tpm_crb_ffa device.

When this happens, IMA fails to detect the TPM device and logs the
following message:

  | ima: No TPM chip found, activating TPM-bypass!

Consequently, it cannot generate the boot_aggregate log with the PCR
values provided by the TPM.

To resolve this issue, the tpm_crb_ffa_init() function explicitly
attempts to probe the tpm_crb_ffa by register tpm_crb_ffa driver so that
when tpm_crb_ffa device is created before tpm_crb_ffa_init(), probe the
tpm_crb_ffa device in tpm_crb_ffa_init() to finish probe the TPM device
completely.

This ensures that the TPM device using CRB over FF-A can be successfully
probed, even if crb_acpi_driver_init() is called first.

[ jarkko: reformatted some of the paragraphs because they were going past
  the 75 character boundary. ]

Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
drivers/char/tpm/tpm_crb_ffa.c

index 4ead61f012996f5452df7464d24eafc8354cd5bc..462fcf6100208c236e475be0af25f4f772f84ec1 100644 (file)
@@ -115,6 +115,7 @@ struct tpm_crb_ffa {
 };
 
 static struct tpm_crb_ffa *tpm_crb_ffa;
+static struct ffa_driver tpm_crb_ffa_driver;
 
 static int tpm_crb_ffa_to_linux_errno(int errno)
 {
@@ -168,13 +169,23 @@ 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)
-               return -ENOENT;
+               ret = -ENOENT;
 
        if (IS_ERR_VALUE(tpm_crb_ffa))
-               return -ENODEV;
+               ret = -ENODEV;
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(tpm_crb_ffa_init);
 
@@ -369,7 +380,9 @@ 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");