Subject: Re: [RFC PATCH 1/4] security: ima: move ima_init into late_initcall_sync

From: Jonathan McDowell <[email-masked]>
Date: Mon, 20 Apr 2026 11:32:56 +0100

On Fri, Apr 17, 2026 at 06:57:56PM +0100, Yeoreum Yun wrote:
>To generate the boot_aggregate log in the IMA subsystem with 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.
>
>To ensure the TPM device operating over the FF-A protocol with
>the CRB interface is probed before IMA initialization,
>the following conditions must be met:
>
>   1. The corresponding ffa_device must be registered,
>      which is done via ffa_init().
>
>   2. The tpm_crb_driver must successfully probe this device via
>      tpm_crb_ffa_init().
>
>   3. The tpm_crb driver using CRB over FF-A can then
>      be probed successfully. (See crb_acpi_add() and
>      tpm_crb_ffa_init() for reference.)
>
>Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
>all registered with device_initcall, which means crb_acpi_driver_init() may
>be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
>
>When this occurs, probing the TPM device is deferred.
>However, the deferred probe can happen after the IMA subsystem
>has already been initialized, since IMA initialization is performed
>during late_initcall, and deferred_probe_initcall() is performed
>at the same level.
>
>To resolve this, move ima_init() into late_inicall_sync level
>so that let IMA not miss TPM PCR value when generating boot_aggregate
>log though TPM device presents in the system.
>
>Signed-off-by: Yeoreum Yun <[email-masked]>

Awesome. This fixes the problems I saw with an SPI TPM on an NVIDIA 
GB200 system and reported in 

https://lore.kernel.org/linux-integrity/[email-masked]/

Reviewed-by: Jonathan McDowell <[email-masked]>
Tested-by: Jonathan McDowell <[email-masked]>

>---
> include/linux/lsm_hooks.h         |  2 ++
> security/integrity/ima/ima_main.c |  2 +-
> security/lsm_init.c               | 13 +++++++++++--
> 3 files changed, 14 insertions(+), 3 deletions(-)
>
>diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
>index d48bf0ad26f4..88fe105b7f00 100644
>--- a/include/linux/lsm_hooks.h
>+++ b/include/linux/lsm_hooks.h
>@@ -166,6 +166,7 @@ enum lsm_order {
>  * @initcall_fs: LSM callback for fs_initcall setup, optional
>  * @initcall_device: LSM callback for device_initcall() setup, optional
>  * @initcall_late: LSM callback for late_initcall() setup, optional
>+ * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional
>  */
> struct lsm_info {
> 	const struct lsm_id *id;
>@@ -181,6 +182,7 @@ struct lsm_info {
> 	int (*initcall_fs)(void);
> 	int (*initcall_device)(void);
> 	int (*initcall_late)(void);
>+	int (*initcall_late_sync)(void);
> };
>
> #define DEFINE_LSM(lsm)							\
>diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
>index 1d6229b156fb..ace280fa3212 100644
>--- a/security/integrity/ima/ima_main.c
>+++ b/security/integrity/ima/ima_main.c
>@@ -1320,5 +1320,5 @@ DEFINE_LSM(ima) = {
> 	.order = LSM_ORDER_LAST,
> 	.blobs = &ima_blob_sizes,
> 	/* Start IMA after the TPM is available */
>-	.initcall_late = init_ima,
>+	.initcall_late_sync = init_ima,
> };
>diff --git a/security/lsm_init.c b/security/lsm_init.c
>index 573e2a7250c4..4e5c59beb82a 100644
>--- a/security/lsm_init.c
>+++ b/security/lsm_init.c
>@@ -547,13 +547,22 @@ device_initcall(security_initcall_device);
>  * security_initcall_late - Run the LSM late initcalls
>  */
> static int __init security_initcall_late(void)
>+{
>+	return lsm_initcall(late);
>+}
>+late_initcall(security_initcall_late);
>+
>+/**
>+ * security_initcall_late_sync - Run the LSM late initcalls sync
>+ */
>+static int __init security_initcall_late_sync(void)
> {
> 	int rc;
>
>-	rc = lsm_initcall(late);
>+	rc = lsm_initcall(late_sync);
> 	lsm_pr_dbg("all enabled LSMs fully activated\n");
> 	call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
>
> 	return rc;
> }
>-late_initcall(security_initcall_late);
>+late_initcall_sync(security_initcall_late_sync);
>--
>LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>
>

J.

-- 
] https://www.earth.li/~noodles/ []  "Do I scare you?" "No." "Do you   [
]  PGP/GPG Key @ the.earth.li    []   want me to?" -- Wayne's World.   [
] via keyserver, web or email.   []                                    [
] RSA: 4096/0x94FA372B2DA8B985   []                                    [