mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
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: d317e4585f ("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>
This commit is contained in:
parent
44e7e7f7cf
commit
5c9deba557
|
|
@ -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() }>(
|
||||
)
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ fn pmu_reserved_size(&self) -> u32 {
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ fn new<'a>(
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 @@ fn fsp_boot_status(&self, bar: Bar0<'_>) -> u32 {
|
|||
fn cot_version(&self) -> u16 {
|
||||
2
|
||||
}
|
||||
|
||||
fn fb_end_reserved_size(&self) -> u64 {
|
||||
u64::SZ_2M + u64::SZ_128K
|
||||
}
|
||||
}
|
||||
|
||||
const GB100: Gb100 = Gb100;
|
||||
|
|
|
|||
|
|
@ -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 @@ fn fsp_boot_status(&self, bar: Bar0<'_>) -> u32 {
|
|||
fn cot_version(&self) -> u16 {
|
||||
2
|
||||
}
|
||||
|
||||
fn fb_end_reserved_size(&self) -> u64 {
|
||||
u64::SZ_2M + u64::SZ_128K
|
||||
}
|
||||
}
|
||||
|
||||
const GB202: Gb202 = Gb202;
|
||||
|
|
|
|||
|
|
@ -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 @@ fn fsp_boot_status(&self, bar: Bar0<'_>) -> u32 {
|
|||
fn cot_version(&self) -> u16 {
|
||||
1
|
||||
}
|
||||
|
||||
fn fb_end_reserved_size(&self) -> u64 {
|
||||
u64::SZ_2M
|
||||
}
|
||||
}
|
||||
|
||||
const GH100: Gh100 = Gh100;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user