mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 22:54:17 -04:00
gpu: nova-core: gsp: ensure lifetime for FMC boot DMA allocations
Currently, `FmcBootArgs` takes DMA handles directly, rather than references to the `Coherent` for them. This is error prone, so instead store lifetime'd references to the `Coherent` allocation. Signed-off-by: Eliot Courtney <ecourtney@nvidia.com> Link: https://patch.msgid.link/20260703-blackwell-fixes-v2-3-8e3d8bc32bb9@nvidia.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
committed by
Alexandre Courbot
parent
ed33ea9390
commit
d76956f7b7
@@ -40,7 +40,11 @@
|
||||
FIRMWARE_VERSION, //
|
||||
},
|
||||
gpu::Chipset,
|
||||
gsp::GspFmcBootParams,
|
||||
gsp::{
|
||||
GspFmcBootParams,
|
||||
GspFwWprMeta,
|
||||
LibosMemoryRegionInitArgument, //
|
||||
},
|
||||
mctp::{
|
||||
MctpHeader,
|
||||
NvdmHeader,
|
||||
@@ -134,7 +138,7 @@ impl FspCotMessage {
|
||||
fn new<'a>(
|
||||
fb_layout: &FbLayout,
|
||||
fsp_fw: &'a FspFirmware,
|
||||
args: &'a FmcBootArgs,
|
||||
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.
|
||||
@@ -188,35 +192,39 @@ impl MessageToFsp for FspCotMessage {
|
||||
}
|
||||
|
||||
/// Bundled arguments for FMC boot via FSP Chain of Trust.
|
||||
pub(crate) struct FmcBootArgs {
|
||||
pub(crate) struct FmcBootArgs<'a> {
|
||||
chipset: Chipset,
|
||||
fmc_boot_params: Coherent<GspFmcBootParams>,
|
||||
resume: bool,
|
||||
// Additional dependencies required to be kept alive for FMC boot.
|
||||
_wpr_meta: &'a Coherent<GspFwWprMeta>,
|
||||
_libos: &'a Coherent<[LibosMemoryRegionInitArgument]>,
|
||||
}
|
||||
|
||||
impl FmcBootArgs {
|
||||
impl<'a> FmcBootArgs<'a> {
|
||||
/// Builds FMC boot arguments, allocating the DMA-coherent boot parameter
|
||||
/// structure that FSP will read.
|
||||
pub(crate) fn new(
|
||||
dev: &device::Device<device::Bound>,
|
||||
chipset: Chipset,
|
||||
wpr_meta_addr: u64,
|
||||
libos_addr: u64,
|
||||
wpr_meta: &'a Coherent<GspFwWprMeta>,
|
||||
libos: &'a Coherent<[LibosMemoryRegionInitArgument]>,
|
||||
resume: bool,
|
||||
) -> Result<Self> {
|
||||
let init = GspFmcBootParams::new(wpr_meta_addr, libos_addr);
|
||||
let init = GspFmcBootParams::new(wpr_meta.dma_handle(), libos.dma_handle());
|
||||
|
||||
Ok(Self {
|
||||
chipset,
|
||||
fmc_boot_params: Coherent::<GspFmcBootParams>::init(dev, GFP_KERNEL, init)?,
|
||||
resume,
|
||||
_wpr_meta: wpr_meta,
|
||||
_libos: libos,
|
||||
})
|
||||
}
|
||||
|
||||
/// DMA address of the FMC boot parameters, needed after boot for lockdown
|
||||
/// release polling.
|
||||
pub(crate) fn boot_params_dma_handle(&self) -> u64 {
|
||||
self.fmc_boot_params.dma_handle()
|
||||
/// Returns the FMC boot parameters allocation.
|
||||
pub(crate) fn boot_params(&self) -> &Coherent<GspFmcBootParams> {
|
||||
&self.fmc_boot_params
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +358,7 @@ pub(crate) fn boot_fmc(
|
||||
&mut self,
|
||||
dev: &device::Device<device::Bound>,
|
||||
fb_layout: &FbLayout,
|
||||
args: &FmcBootArgs,
|
||||
args: &FmcBootArgs<'_>,
|
||||
) -> Result {
|
||||
dev_dbg!(dev, "Starting FSP boot sequence for {}\n", args.chipset);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
pub(crate) use fw::{
|
||||
GspFmcBootParams,
|
||||
GspFwWprMeta,
|
||||
LibosMemoryRegionInitArgument,
|
||||
LibosParams, //
|
||||
};
|
||||
pub(crate) use hal::boot_firmware_files;
|
||||
@@ -45,10 +46,7 @@
|
||||
gpu::Chipset,
|
||||
gsp::{
|
||||
cmdq::Cmdq,
|
||||
fw::{
|
||||
GspArgumentsPadded,
|
||||
LibosMemoryRegionInitArgument, //
|
||||
},
|
||||
fw::GspArgumentsPadded, //
|
||||
},
|
||||
num,
|
||||
};
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
},
|
||||
Gsp,
|
||||
GspBootContext,
|
||||
GspFmcBootParams,
|
||||
GspFwWprMeta, //
|
||||
},
|
||||
};
|
||||
@@ -56,13 +57,13 @@ fn combined_addr(&self) -> u64 {
|
||||
fn lockdown_released_or_error(
|
||||
&self,
|
||||
gsp_falcon: &Falcon<'_, GspEngine>,
|
||||
fmc_boot_params_addr: u64,
|
||||
fmc_boot_params: &Coherent<GspFmcBootParams>,
|
||||
) -> bool {
|
||||
// GSP-FMC normally clears the boot parameters address from the mailboxes early during
|
||||
// boot. If the address is still there, keep polling rather than treating it as an error.
|
||||
// Any other non-zero mailbox0 value is a GSP-FMC error code.
|
||||
if self.mbox0 != 0 {
|
||||
return self.combined_addr() != fmc_boot_params_addr;
|
||||
return self.combined_addr() != fmc_boot_params.dma_handle();
|
||||
}
|
||||
|
||||
!gsp_falcon.riscv_branch_privilege_lockdown()
|
||||
@@ -73,7 +74,7 @@ fn lockdown_released_or_error(
|
||||
fn wait_for_gsp_lockdown_release(
|
||||
dev: &device::Device<device::Bound>,
|
||||
gsp_falcon: &Falcon<'_, GspEngine>,
|
||||
fmc_boot_params_addr: u64,
|
||||
fmc_boot_params: &Coherent<GspFmcBootParams>,
|
||||
) -> Result {
|
||||
dev_dbg!(dev, "Waiting for GSP lockdown release\n");
|
||||
|
||||
@@ -88,7 +89,7 @@ fn wait_for_gsp_lockdown_release(
|
||||
},
|
||||
|mbox| match mbox {
|
||||
None => false,
|
||||
Some(mbox) => mbox.lockdown_released_or_error(gsp_falcon, fmc_boot_params_addr),
|
||||
Some(mbox) => mbox.lockdown_released_or_error(gsp_falcon, fmc_boot_params),
|
||||
},
|
||||
Delta::from_millis(10),
|
||||
Delta::from_secs(30),
|
||||
@@ -147,13 +148,7 @@ fn boot(
|
||||
KBox::new(FspUnloadBundle, GFP_KERNEL)? as KBox<dyn UnloadBundle>
|
||||
);
|
||||
|
||||
let args = FmcBootArgs::new(
|
||||
dev,
|
||||
chipset,
|
||||
wpr_meta.dma_handle(),
|
||||
gsp.libos.dma_handle(),
|
||||
false,
|
||||
)?;
|
||||
let args = FmcBootArgs::new(dev, chipset, wpr_meta, &gsp.libos, false)?;
|
||||
|
||||
// Wait for the GSP RISC-V core to halt in case of error. We create this guard after `args`
|
||||
// to make sure that boot args are kept alive until halt, in case they are still being
|
||||
@@ -169,7 +164,7 @@ fn boot(
|
||||
|
||||
// Wait for GSP-FMC to release the GSP lockdown, indicating that `args` is not accessed
|
||||
// anymore.
|
||||
wait_for_gsp_lockdown_release(dev, gsp_falcon, args.boot_params_dma_handle())?;
|
||||
wait_for_gsp_lockdown_release(dev, gsp_falcon, args.boot_params())?;
|
||||
|
||||
Ok(Some(unload_guard.dismiss().0))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user