Re: [PATCH v6 23/34] gpu: nova-core: Hopper/Blackwell: add FSP message structures
From: Alexandre Courbot
Date: Tue Mar 10 2026 - 07:09:09 EST
On Tue Mar 10, 2026 at 11:11 AM JST, John Hubbard wrote:
> Add the NVDM COT payload, FSP message, and FSP response structures
> needed for FSP Chain of Trust communication. Also add FmcSignatures
> to hold the hash, public key, and signature extracted from FMC firmware.
>
> Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx>
> ---
> drivers/gpu/nova-core/firmware.rs | 5 +-
> drivers/gpu/nova-core/fsp.rs | 78 +++++++++++++++++++++++++++++++
> 2 files changed, 82 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
> index 6a0a02177f6f..be41e07b8448 100644
> --- a/drivers/gpu/nova-core/firmware.rs
> +++ b/drivers/gpu/nova-core/firmware.rs
> @@ -26,6 +26,9 @@
> },
> };
>
> +#[expect(unused)]
> +pub(crate) use elf::elf_section;
> +
> pub(crate) mod booter;
> pub(crate) mod fsp;
> pub(crate) mod fwsec;
> @@ -627,7 +630,7 @@ fn elf32_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
> }
>
> /// Automatically detects ELF32 vs ELF64 based on the ELF header.
> - pub(super) fn elf_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
> + pub(crate) fn elf_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
> // Check ELF magic.
> if elf.len() < 5 || elf.get(0..4)? != b"\x7fELF" {
> return None;
> diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs
> index d464ad325881..15731d24d0c5 100644
> --- a/drivers/gpu/nova-core/fsp.rs
> +++ b/drivers/gpu/nova-core/fsp.rs
> @@ -105,6 +105,84 @@ unsafe impl AsBytes for GspFmcBootParams {}
> // SAFETY: All bit patterns are valid for the primitive fields.
> unsafe impl FromBytes for GspFmcBootParams {}
>
> +/// Size constraints for FSP security signatures (Hopper/Blackwell).
> +const FSP_HASH_SIZE: usize = 48; // SHA-384 hash
> +const FSP_PKEY_SIZE: usize = 384; // RSA-3072 public key
> +const FSP_SIG_SIZE: usize = 384; // RSA-3072 signature
> +
> +/// Structure to hold FMC signatures.
> +#[derive(Debug, Clone, Copy)]
> +#[expect(dead_code)]
> +pub(crate) struct FmcSignatures {
> + hash384: [u8; FSP_HASH_SIZE],
> + public_key: [u8; FSP_PKEY_SIZE],
> + signature: [u8; FSP_SIG_SIZE],
> +}
> +
> +impl Default for FmcSignatures {
> + fn default() -> Self {
> + Self {
> + hash384: [0u8; FSP_HASH_SIZE],
> + public_key: [0u8; FSP_PKEY_SIZE],
> + signature: [0u8; FSP_SIG_SIZE],
> + }
> + }
> +}
Since everything is initialized to zero you should be able to derive
`Default` instead of bringing your own implementation.
> +
> +/// FSP Command Response payload structure.
> +/// NVDM_PAYLOAD_COMMAND_RESPONSE structure.
> +#[repr(C, packed)]
> +#[derive(Clone, Copy)]
> +struct NvdmPayloadCommandResponse {
> + task_id: u32,
> + command_nvdm_type: u32,
> + error_code: u32,
> +}
> +
> +/// NVDM (NVIDIA Device Management) COT (Chain of Trust) payload structure.
> +/// This is the main message payload sent to FSP for Chain of Trust.
> +#[repr(C, packed)]
> +#[derive(Clone, Copy)]
> +struct NvdmPayloadCot {
> + version: u16,
> + size: u16,
> + gsp_fmc_sysmem_offset: u64,
> + frts_sysmem_offset: u64,
> + frts_sysmem_size: u32,
> + frts_vidmem_offset: u64,
> + frts_vidmem_size: u32,
> + hash384: [u8; FSP_HASH_SIZE],
> + public_key: [u8; FSP_PKEY_SIZE],
> + signature: [u8; FSP_SIG_SIZE],
> + gsp_boot_args_sysmem_offset: u64,
> +}
> +
> +/// Complete FSP message structure with MCTP and NVDM headers.
> +#[repr(C, packed)]
> +#[derive(Clone, Copy)]
> +#[expect(dead_code)]
> +struct FspMessage {
> + mctp_header: u32,
> + nvdm_header: u32,
> + cot: NvdmPayloadCot,
> +}
> +
> +// SAFETY: FspMessage is a packed C struct with only integral fields.
> +unsafe impl AsBytes for FspMessage {}
> +
> +/// Complete FSP response structure with MCTP and NVDM headers.
> +#[repr(C, packed)]
> +#[derive(Clone, Copy)]
> +#[expect(dead_code)]
> +struct FspResponse {
> + mctp_header: u32,
> + nvdm_header: u32,
> + response: NvdmPayloadCommandResponse,
> +}
> +
> +// SAFETY: FspResponse is a packed C struct with only integral fields.
> +unsafe impl FromBytes for FspResponse {}
> +
> /// FSP interface for Hopper/Blackwell GPUs.
> pub(crate) struct Fsp;
All this code seems to be directly or indirectly dead for now - is there
a way to merge this patch with the one that makes use of these? I don't
mind larger patches if they mostly add new code, as it comes down to the
same at the end of the day.