diff options
| author | Eliot Courtney <ecourtney@nvidia.com> | 2026-08-04 14:41:12 +0900 |
|---|---|---|
| committer | Alexandre Courbot <acourbot@nvidia.com> | 2026-08-05 14:20:36 +0900 |
| commit | 5c9deba5578db5a3ea05be8a3e4a59ecb08ee76f (patch) | |
| tree | b92c27dadf226db1140bcb37a36aac6e42cb174c /drivers/gpu | |
| parent | 44e7e7f7cffb10a93bb88e7cb59b7b8b3e2deb1c (diff) | |
| download | linux-5c9deba5578db5a3ea05be8a3e4a59ecb08ee76f.tar.gz linux-5c9deba5578db5a3ea05be8a3e4a59ecb08ee76f.zip | |
gpu: nova-core: correct FRTS vidmem offset calculation
Currently, the frts vidmem offset is calculated based on the non-wpr
heap size and pmu reservation size, but this is not right. The layout
actually looks like this:
| non-wpr heap | WPR2 .. FRTS | PMU reserved | ... | VGA workspace |
It's just by coincidence + generous alignment that the values happened
to match. Instead, define a per-architecture reserved size at the end of
the framebuffer and use this plus the PMU reserved size to calculate the
frts vidmem offset.
Fixes: d317e4585fa3 ("gpu: nova-core: Hopper/Blackwell: add FSP Chain of Trust boot")
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260804-blackwell-fixes-v4-1-ac858b6a1935@nvidia.com
[acourbot: add comment clarifying reason for testing pmu_reserved_size.]
[acourbot: make fb_end_reserved_size() return u64.]
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/nova-core/fb/hal/gb100.rs | 1 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/fb/hal/gb202.rs | 1 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/fsp.rs | 28 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/fsp/hal.rs | 4 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/fsp/hal/gb100.rs | 6 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/fsp/hal/gb202.rs | 9 | ||||
| -rw-r--r-- | drivers/gpu/nova-core/fsp/hal/gh100.rs | 9 |
7 files changed, 48 insertions, 10 deletions
diff --git a/drivers/gpu/nova-core/fb/hal/gb100.rs b/drivers/gpu/nova-core/fb/hal/gb100.rs index ec55ec3fc7e1..7e5b0e3ffc67 100644 --- a/drivers/gpu/nova-core/fb/hal/gb100.rs +++ b/drivers/gpu/nova-core/fb/hal/gb100.rs @@ -80,6 +80,7 @@ fn write_sysmem_flush_page_gb100(bar: Bar0<'_>, addr: Bounded<u64, 52>) { ); } +// This PMU reservation size is r570-specific. pub(super) const fn pmu_reserved_size_gb100() -> u32 { usize_into_u32::<{ const_align_up(SZ_8M + SZ_16M + SZ_4K, Alignment::new::<SZ_128K>()).unwrap() }>( ) diff --git a/drivers/gpu/nova-core/fb/hal/gb202.rs b/drivers/gpu/nova-core/fb/hal/gb202.rs index 69ba35d2ea08..c590e5b1269c 100644 --- a/drivers/gpu/nova-core/fb/hal/gb202.rs +++ b/drivers/gpu/nova-core/fb/hal/gb202.rs @@ -73,6 +73,7 @@ impl FbHal for Gb202 { fn non_wpr_heap_size(&self) -> u32 { // Non-WPR heap for GB20x (see Open RM: kgspGetNonWprHeapSize, GB202+). + // This size is r570-specific. u32::SZ_2M + u32::SZ_128K } diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs index ba4544210e40..17d100a085f0 100644 --- a/drivers/gpu/nova-core/fsp.rs +++ b/drivers/gpu/nova-core/fsp.rs @@ -251,20 +251,32 @@ struct FspCotMessage { } impl FspCotMessage { + /// Computes the FRTS vidmem offset for the Chain-of-Trust message. It is measured backwards + /// from the end of the framebuffer. + fn frts_vidmem_offset(hal: &dyn hal::FspHal, fb_layout: &FbLayout) -> Result<u64> { + let mut offset = hal.fb_end_reserved_size(); + + // As per OpenRM's `kfspPrepareBootCommands_GH100`. + if fb_layout.pmu_reserved_size != 0 { + offset = (offset + u64::from(fb_layout.pmu_reserved_size)) + // The 2 MiB alignment is r570-specific. + .align_up(Alignment::new::<SZ_2M>()) + .ok_or(EINVAL)?; + } + + Ok(offset) + } + /// Returns an in-place initializer for [`FspCotMessage`]. fn new<'a>( fb_layout: &FbLayout, fsp_fw: &'a FspFirmware, args: &'a FmcBootArgs<'_>, ) -> Result<impl Init<Self> + 'a> { - // frts_vidmem_offset is measured from the end of FB, so FRTS sits at - // (end of FB) - frts_vidmem_offset. - let frts_vidmem_offset = if !args.resume { - let frts_reserved_size = fb_layout.heap.len() + u64::from(fb_layout.pmu_reserved_size); + let hal = hal::fsp_hal(args.chipset).ok_or(ENOTSUPP)?; - frts_reserved_size - .align_up(Alignment::new::<SZ_2M>()) - .ok_or(EINVAL)? + let frts_vidmem_offset = if !args.resume { + Self::frts_vidmem_offset(hal, fb_layout)? } else { 0 }; @@ -275,7 +287,7 @@ impl FspCotMessage { 0 }; - let version = hal::fsp_hal(args.chipset).ok_or(ENOTSUPP)?.cot_version(); + let version = hal.cot_version(); let size = num::usize_into_u16::<{ core::mem::size_of::<NvdmPayloadCot>() }>(); Ok(init!(Self { diff --git a/drivers/gpu/nova-core/fsp/hal.rs b/drivers/gpu/nova-core/fsp/hal.rs index b6f2624bb13d..eaf5837ac5a8 100644 --- a/drivers/gpu/nova-core/fsp/hal.rs +++ b/drivers/gpu/nova-core/fsp/hal.rs @@ -19,6 +19,10 @@ pub(super) trait FspHal { /// Returns the FSP Chain of Trust protocol version this chipset advertises. fn cot_version(&self) -> u16; + + // TODO: consider moving this into the TLV firmware metadata when ready + /// Returns the size reserved at the end of the framebuffer, in bytes. + fn fb_end_reserved_size(&self) -> u64; } /// Returns the FSP HAL, or `None` if the architecture doesn't support FSP. diff --git a/drivers/gpu/nova-core/fsp/hal/gb100.rs b/drivers/gpu/nova-core/fsp/hal/gb100.rs index 42f5ecfc6400..7cf53aa3d1ff 100644 --- a/drivers/gpu/nova-core/fsp/hal/gb100.rs +++ b/drivers/gpu/nova-core/fsp/hal/gb100.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +use kernel::sizes::SizeConstants; + use crate::{ driver::Bar0, fsp::hal::FspHal, // @@ -17,6 +19,10 @@ impl FspHal for Gb100 { fn cot_version(&self) -> u16 { 2 } + + fn fb_end_reserved_size(&self) -> u64 { + u64::SZ_2M + u64::SZ_128K + } } const GB100: Gb100 = Gb100; diff --git a/drivers/gpu/nova-core/fsp/hal/gb202.rs b/drivers/gpu/nova-core/fsp/hal/gb202.rs index 1091b169a645..e380bbc5d58d 100644 --- a/drivers/gpu/nova-core/fsp/hal/gb202.rs +++ b/drivers/gpu/nova-core/fsp/hal/gb202.rs @@ -1,7 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -use kernel::io::Io; +use kernel::{ + io::Io, + sizes::SizeConstants, // +}; use crate::{ driver::Bar0, @@ -21,6 +24,10 @@ impl FspHal for Gb202 { fn cot_version(&self) -> u16 { 2 } + + fn fb_end_reserved_size(&self) -> u64 { + u64::SZ_2M + u64::SZ_128K + } } const GB202: Gb202 = Gb202; diff --git a/drivers/gpu/nova-core/fsp/hal/gh100.rs b/drivers/gpu/nova-core/fsp/hal/gh100.rs index 291acaf2845a..9a8563799da8 100644 --- a/drivers/gpu/nova-core/fsp/hal/gh100.rs +++ b/drivers/gpu/nova-core/fsp/hal/gh100.rs @@ -1,7 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -use kernel::io::Io; +use kernel::{ + io::Io, + sizes::SizeConstants, // +}; use crate::{ driver::Bar0, @@ -26,6 +29,10 @@ impl FspHal for Gh100 { fn cot_version(&self) -> u16 { 1 } + + fn fb_end_reserved_size(&self) -> u64 { + u64::SZ_2M + } } const GH100: Gh100 = Gh100; |
