Skip to content

Commit 93296e9

Browse files
committed
gpu: nova-core: vbios: store reference to Device where relevant
Now that the vbios code uses a non-bound `Device` instance, store an `ARef` to it at construction time so we can use it for logging without having to carry an extra argument on every method for that sole purpose. Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20250808-vbios_device-v1-2-834bbbab6471@nvidia.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
1 parent dff1151 commit 93296e9

2 files changed

Lines changed: 46 additions & 31 deletions

File tree

drivers/gpu/nova-core/firmware/fwsec.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ impl FalconFirmware for FwsecFirmware {
246246

247247
impl FirmwareDmaObject<FwsecFirmware, Unsigned> {
248248
fn new_fwsec(dev: &Device<device::Bound>, bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
249-
let desc = bios.fwsec_image().header(dev)?;
250-
let ucode = bios.fwsec_image().ucode(dev, desc)?;
249+
let desc = bios.fwsec_image().header()?;
250+
let ucode = bios.fwsec_image().ucode(desc)?;
251251
let mut dma_object = DmaObject::from_data(dev, ucode)?;
252252

253253
let hdr_offset = (desc.imem_load_size + desc.interface_offset) as usize;
@@ -336,7 +336,7 @@ impl FwsecFirmware {
336336
let ucode_dma = FirmwareDmaObject::<Self, _>::new_fwsec(dev, bios, cmd)?;
337337

338338
// Patch signature if needed.
339-
let desc = bios.fwsec_image().header(dev)?;
339+
let desc = bios.fwsec_image().header()?;
340340
let ucode_signed = if desc.signature_count != 0 {
341341
let sig_base_img = (desc.imem_load_size + desc.pkc_data_offset) as usize;
342342
let desc_sig_versions = u32::from(desc.signature_versions);
@@ -375,7 +375,7 @@ impl FwsecFirmware {
375375
dev_dbg!(dev, "patching signature with index {}\n", signature_idx);
376376
let signature = bios
377377
.fwsec_image()
378-
.sigs(dev, desc)
378+
.sigs(desc)
379379
.and_then(|sigs| sigs.get(signature_idx).ok_or(EINVAL))?;
380380

381381
ucode_dma.patch_signature(signature, sig_base_img)?

drivers/gpu/nova-core/vbios.rs

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use core::convert::TryFrom;
99
use kernel::device;
1010
use kernel::error::Result;
1111
use kernel::prelude::*;
12+
use kernel::types::ARef;
1213

1314
/// The offset of the VBIOS ROM in the BAR0 space.
1415
const ROM_OFFSET: usize = 0x300000;
@@ -230,10 +231,10 @@ impl Vbios {
230231
(second_fwsec_image, first_fwsec_image, pci_at_image)
231232
{
232233
second
233-
.setup_falcon_data(dev, &pci_at, &first)
234+
.setup_falcon_data(&pci_at, &first)
234235
.inspect_err(|e| dev_err!(dev, "Falcon data setup failed: {:?}\n", e))?;
235236
Ok(Vbios {
236-
fwsec_image: second.build(dev)?,
237+
fwsec_image: second.build()?,
237238
})
238239
} else {
239240
dev_err!(
@@ -742,9 +743,10 @@ impl TryFrom<BiosImageBase> for BiosImage {
742743
///
743744
/// Each BiosImage type has a BiosImageBase type along with other image-specific fields. Note that
744745
/// Rust favors composition of types over inheritance.
745-
#[derive(Debug)]
746746
#[expect(dead_code)]
747747
struct BiosImageBase {
748+
/// Used for logging.
749+
dev: ARef<device::Device>,
748750
/// PCI ROM Expansion Header
749751
rom_header: PciRomHeader,
750752
/// PCI Data Structure
@@ -801,6 +803,7 @@ impl BiosImageBase {
801803
data_copy.extend_from_slice(data, GFP_KERNEL)?;
802804

803805
Ok(BiosImageBase {
806+
dev: dev.into(),
804807
rom_header,
805808
pcir,
806809
npde,
@@ -836,7 +839,7 @@ impl PciAtBiosImage {
836839
///
837840
/// This is just a 4 byte structure that contains a pointer to the Falcon data in the FWSEC
838841
/// image.
839-
fn falcon_data_ptr(&self, dev: &device::Device) -> Result<u32> {
842+
fn falcon_data_ptr(&self) -> Result<u32> {
840843
let token = self.get_bit_token(BIT_TOKEN_ID_FALCON_DATA)?;
841844

842845
// Make sure we don't go out of bounds
@@ -847,14 +850,14 @@ impl PciAtBiosImage {
847850
// read the 4 bytes at the offset specified in the token
848851
let offset = token.data_offset as usize;
849852
let bytes: [u8; 4] = self.base.data[offset..offset + 4].try_into().map_err(|_| {
850-
dev_err!(dev, "Failed to convert data slice to array");
853+
dev_err!(self.base.dev, "Failed to convert data slice to array");
851854
EINVAL
852855
})?;
853856

854857
let data_ptr = u32::from_le_bytes(bytes);
855858

856859
if (data_ptr as usize) < self.base.data.len() {
857-
dev_err!(dev, "Falcon data pointer out of bounds\n");
860+
dev_err!(self.base.dev, "Falcon data pointer out of bounds\n");
858861
return Err(EINVAL);
859862
}
860863

@@ -978,11 +981,10 @@ impl PmuLookupTable {
978981
impl FwSecBiosBuilder {
979982
fn setup_falcon_data(
980983
&mut self,
981-
dev: &device::Device,
982984
pci_at_image: &PciAtBiosImage,
983985
first_fwsec: &FwSecBiosBuilder,
984986
) -> Result {
985-
let mut offset = pci_at_image.falcon_data_ptr(dev)? as usize;
987+
let mut offset = pci_at_image.falcon_data_ptr()? as usize;
986988
let mut pmu_in_first_fwsec = false;
987989

988990
// The falcon data pointer assumes that the PciAt and FWSEC images
@@ -1005,10 +1007,15 @@ impl FwSecBiosBuilder {
10051007
self.falcon_data_offset = Some(offset);
10061008

10071009
if pmu_in_first_fwsec {
1008-
self.pmu_lookup_table =
1009-
Some(PmuLookupTable::new(dev, &first_fwsec.base.data[offset..])?);
1010+
self.pmu_lookup_table = Some(PmuLookupTable::new(
1011+
&self.base.dev,
1012+
&first_fwsec.base.data[offset..],
1013+
)?);
10101014
} else {
1011-
self.pmu_lookup_table = Some(PmuLookupTable::new(dev, &self.base.data[offset..])?);
1015+
self.pmu_lookup_table = Some(PmuLookupTable::new(
1016+
&self.base.dev,
1017+
&self.base.data[offset..],
1018+
)?);
10121019
}
10131020

10141021
match self
@@ -1021,31 +1028,35 @@ impl FwSecBiosBuilder {
10211028
let mut ucode_offset = entry.data as usize;
10221029
ucode_offset -= pci_at_image.base.data.len();
10231030
if ucode_offset < first_fwsec.base.data.len() {
1024-
dev_err!(dev, "Falcon Ucode offset not in second Fwsec.\n");
1031+
dev_err!(self.base.dev, "Falcon Ucode offset not in second Fwsec.\n");
10251032
return Err(EINVAL);
10261033
}
10271034
ucode_offset -= first_fwsec.base.data.len();
10281035
self.falcon_ucode_offset = Some(ucode_offset);
10291036
}
10301037
Err(e) => {
1031-
dev_err!(dev, "PmuLookupTableEntry not found, error: {:?}\n", e);
1038+
dev_err!(
1039+
self.base.dev,
1040+
"PmuLookupTableEntry not found, error: {:?}\n",
1041+
e
1042+
);
10321043
return Err(EINVAL);
10331044
}
10341045
}
10351046
Ok(())
10361047
}
10371048

10381049
/// Build the final FwSecBiosImage from this builder
1039-
fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
1050+
fn build(self) -> Result<FwSecBiosImage> {
10401051
let ret = FwSecBiosImage {
10411052
base: self.base,
10421053
falcon_ucode_offset: self.falcon_ucode_offset.ok_or(EINVAL)?,
10431054
};
10441055

10451056
if cfg!(debug_assertions) {
10461057
// Print the desc header for debugging
1047-
let desc = ret.header(dev)?;
1048-
dev_dbg!(dev, "PmuLookupTableEntry desc: {:#?}\n", desc);
1058+
let desc = ret.header()?;
1059+
dev_dbg!(ret.base.dev, "PmuLookupTableEntry desc: {:#?}\n", desc);
10491060
}
10501061

10511062
Ok(ret)
@@ -1054,13 +1065,16 @@ impl FwSecBiosBuilder {
10541065

10551066
impl FwSecBiosImage {
10561067
/// Get the FwSec header ([`FalconUCodeDescV3`]).
1057-
pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3> {
1068+
pub(crate) fn header(&self) -> Result<&FalconUCodeDescV3> {
10581069
// Get the falcon ucode offset that was found in setup_falcon_data.
10591070
let falcon_ucode_offset = self.falcon_ucode_offset;
10601071

10611072
// Make sure the offset is within the data bounds.
10621073
if falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>() > self.base.data.len() {
1063-
dev_err!(dev, "fwsec-frts header not contained within BIOS bounds\n");
1074+
dev_err!(
1075+
self.base.dev,
1076+
"fwsec-frts header not contained within BIOS bounds\n"
1077+
);
10641078
return Err(ERANGE);
10651079
}
10661080

@@ -1072,7 +1086,7 @@ impl FwSecBiosImage {
10721086
let ver = (hdr & 0xff00) >> 8;
10731087

10741088
if ver != 3 {
1075-
dev_err!(dev, "invalid fwsec firmware version: {:?}\n", ver);
1089+
dev_err!(self.base.dev, "invalid fwsec firmware version: {:?}\n", ver);
10761090
return Err(EINVAL);
10771091
}
10781092

@@ -1092,7 +1106,7 @@ impl FwSecBiosImage {
10921106
}
10931107

10941108
/// Get the ucode data as a byte slice
1095-
pub(crate) fn ucode(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Result<&[u8]> {
1109+
pub(crate) fn ucode(&self, desc: &FalconUCodeDescV3) -> Result<&[u8]> {
10961110
let falcon_ucode_offset = self.falcon_ucode_offset;
10971111

10981112
// The ucode data follows the descriptor.
@@ -1104,15 +1118,16 @@ impl FwSecBiosImage {
11041118
.data
11051119
.get(ucode_data_offset..ucode_data_offset + size)
11061120
.ok_or(ERANGE)
1107-
.inspect_err(|_| dev_err!(dev, "fwsec ucode data not contained within BIOS bounds\n"))
1121+
.inspect_err(|_| {
1122+
dev_err!(
1123+
self.base.dev,
1124+
"fwsec ucode data not contained within BIOS bounds\n"
1125+
)
1126+
})
11081127
}
11091128

11101129
/// Get the signatures as a byte slice
1111-
pub(crate) fn sigs(
1112-
&self,
1113-
dev: &device::Device,
1114-
desc: &FalconUCodeDescV3,
1115-
) -> Result<&[Bcrt30Rsa3kSignature]> {
1130+
pub(crate) fn sigs(&self, desc: &FalconUCodeDescV3) -> Result<&[Bcrt30Rsa3kSignature]> {
11161131
// The signatures data follows the descriptor.
11171132
let sigs_data_offset = self.falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>();
11181133
let sigs_size =
@@ -1121,7 +1136,7 @@ impl FwSecBiosImage {
11211136
// Make sure the data is within bounds.
11221137
if sigs_data_offset + sigs_size > self.base.data.len() {
11231138
dev_err!(
1124-
dev,
1139+
self.base.dev,
11251140
"fwsec signatures data not contained within BIOS bounds\n"
11261141
);
11271142
return Err(ERANGE);

0 commit comments

Comments
 (0)