Re: [PATCH v12 12/22] gpu: nova-core: Hopper/Blackwell: add FSP secure boot completion waiting
From: Alexandre Courbot
Date: Tue Jun 02 2026 - 04:29:41 EST
On Tue Jun 2, 2026 at 4:56 PM JST, Eliot Courtney wrote:
> On Tue Jun 2, 2026 at 12:21 PM JST, John Hubbard wrote:
>> Hopper and Blackwell use FSP instead of SEC2 for secure boot. The
>> driver must wait for FSP secure boot to complete before continuing
>> with GSP bring-up. Poll for boot success with a 5-second timeout, and
>> return the FSP interface only on success so that later Chain of Trust
>> operations cannot run before FSP is ready. The interface owns the FSP
>> falcon and the FMC firmware.
>>
>> Co-developed-by: Alexandre Courbot <acourbot@xxxxxxxxxx>
>> Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxx>
>> Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx>
>> ---
>> drivers/gpu/nova-core/falcon/fsp.rs | 1 -
>> drivers/gpu/nova-core/fsp.rs | 73 ++++++++++++++++++++++++++
>> drivers/gpu/nova-core/fsp/hal.rs | 27 ++++++++++
>> drivers/gpu/nova-core/fsp/hal/gb202.rs | 23 ++++++++
>> drivers/gpu/nova-core/fsp/hal/gh100.rs | 23 ++++++++
>> drivers/gpu/nova-core/gsp/hal/gh100.rs | 6 ++-
>> drivers/gpu/nova-core/nova_core.rs | 1 +
>> drivers/gpu/nova-core/regs.rs | 36 +++++++++++++
>> 8 files changed, 187 insertions(+), 3 deletions(-)
>> create mode 100644 drivers/gpu/nova-core/fsp.rs
>> create mode 100644 drivers/gpu/nova-core/fsp/hal.rs
>> create mode 100644 drivers/gpu/nova-core/fsp/hal/gb202.rs
>> create mode 100644 drivers/gpu/nova-core/fsp/hal/gh100.rs
>>
>> diff --git a/drivers/gpu/nova-core/falcon/fsp.rs b/drivers/gpu/nova-core/falcon/fsp.rs
>> index c4a9ce8a47f8..d9f87262e8b1 100644
>> --- a/drivers/gpu/nova-core/falcon/fsp.rs
>> +++ b/drivers/gpu/nova-core/falcon/fsp.rs
>> @@ -15,7 +15,6 @@
>> };
>>
>> /// Type specifying the `Fsp` falcon engine. Cannot be instantiated.
>> -#[expect(dead_code)]
>> pub(crate) struct Fsp(());
>>
>> impl RegisterBase<PFalconBase> for Fsp {
>> diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs
>> new file mode 100644
>> index 000000000000..f3524137d9f7
>> --- /dev/null
>> +++ b/drivers/gpu/nova-core/fsp.rs
>> @@ -0,0 +1,73 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
>> +
>> +//! FSP (Foundation Security Processor) interface for Hopper/Blackwell GPUs.
>> +//!
>> +//! Hopper/Blackwell use a simplified firmware boot sequence: FMC, then FSP, then GSP.
>> +//! Unlike Turing/Ampere/Ada, there is no SEC2 (Security Engine 2) usage.
>> +//! FSP handles secure boot directly using FMC firmware and Chain of Trust.
>> +
>> +use kernel::{
>> + device,
>> + io::poll::read_poll_timeout,
>> + prelude::*,
>> + time::Delta, //
>> +};
>> +
>> +use crate::{
>> + driver::Bar0,
>> + falcon::{
>> + fsp::Fsp as FspEngine,
>> + Falcon, //
>> + },
>> + firmware::fsp::FspFirmware,
>> + gpu::Chipset,
>> + regs, //
>> +};
>> +
>> +mod hal;
>> +
>> +/// FSP interface for Hopper/Blackwell GPUs.
>> +///
>> +/// An `Fsp` is produced by [`Fsp::wait_secure_boot`], which only returns once FSP secure boot
>> +/// has completed. It owns the FSP falcon and the FMC firmware, which are used for the subsequent
>> +/// Chain of Trust boot.
>> +pub(crate) struct Fsp {
>> + #[expect(dead_code)]
>> + falcon: Falcon<FspEngine>,
>> + #[expect(dead_code)]
>> + fsp_fw: FspFirmware,
>> +}
>> +
>> +impl Fsp {
>> + /// Waits for FSP secure boot completion, then returns the [`Fsp`] interface.
>> + ///
>> + /// Polls the thermal scratch register until FSP signals boot completion or the timeout
>> + /// elapses. Returning an [`Fsp`] only on success guarantees, at the API level, that the
>> + /// interface is not used before secure boot has completed.
>> + pub(crate) fn wait_secure_boot(
>> + dev: &device::Device<device::Bound>,
>> + bar: &Bar0,
>> + chipset: Chipset,
>> + fsp_fw: FspFirmware,
>
> What about constructing FspFirmware inside `wait_secure_boot`? It fits
> the concept of having this Fsp object own and control the FSP. This also
> matches the pattern of Gsp::boot creating its own GspFirmware.
That makes sense, otoh since this method is named after its most
important side-effect its name does not carry the expectation of loading
some firmware image. So after consideration I think it makes sense to
keep firmware loading a separate step - I would say differently if this
was named "new", but then we lose the important fact that this is also
touching the hardware and waiting on it.
At the end of the day, `Fsp` ends up ownning the `FspFirmware`, so the
most important architectural point is addressed.
>
>> + ) -> Result<Fsp> {
>> + /// FSP secure boot completion timeout in milliseconds.
>> + const FSP_SECURE_BOOT_TIMEOUT_MS: i64 = 5000;
>> +
>> + let hal = hal::fsp_hal(chipset).ok_or(ENOTSUPP)?;
>> + let falcon = Falcon::<FspEngine>::new(dev, chipset)?;
>> +
>> + read_poll_timeout(
>> + || Ok(hal.fsp_boot_status(bar)),
>> + |&status| status == regs::NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS,
>> + Delta::from_millis(10),
>> + Delta::from_millis(FSP_SECURE_BOOT_TIMEOUT_MS),
>> + )
>> + .map_err(|_| {
>> + dev_err!(dev, "FSP secure boot completion timeout\n");
>> + ETIMEDOUT
>> + })?;
>
> nit: this can just be inspect_err(), it will be ETIMEDOUT if it times
> out.
Indeed, I'll fixup when applying.
>
>> +
>> + Ok(Fsp { falcon, fsp_fw })
>> + }
>> +}
>> diff --git a/drivers/gpu/nova-core/fsp/hal.rs b/drivers/gpu/nova-core/fsp/hal.rs
>> new file mode 100644
>> index 000000000000..83d1e7daa998
>> --- /dev/null
>> +++ b/drivers/gpu/nova-core/fsp/hal.rs
>> @@ -0,0 +1,27 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
>> +
>> +use crate::{
>> + driver::Bar0,
>> + gpu::{
>> + Architecture,
>> + Chipset, //
>> + },
>> +};
>> +
>> +mod gb202;
>> +mod gh100;
>> +
>> +pub(super) trait FspHal {
>> + /// Returns the secure boot status from the architecture-specific `NV_THERM_I2CS_SCRATCH` register.
>> + fn fsp_boot_status(&self, bar: &Bar0) -> u32;
>> +}
>> +
>> +/// Returns the FSP HAL, or `None` if the architecture doesn't support FSP.
>> +pub(crate) fn fsp_hal(chipset: Chipset) -> Option<&'static dyn FspHal> {
>
> nit: this can be pub(super)
Same.
>
> With above changes,
>
> Reviewed-by: Eliot Courtney <ecourtney@xxxxxxxxxx>
Thanks!