tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's built-in

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>
This commit is contained in:
Yeoreum Yun
2025-07-19 13:27:46 +03:00
committed by Jarkko Sakkinen
parent 0e0546eabc
commit 746d9e9f62

View 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");