Skip to content

Commit ad5f997

Browse files
johnhubbardGnurou
authored andcommitted
gpu: nova-core: add auto-detection of 32-bit, 64-bit firmware images
A firmware image may be either a 32-bit or a 64-bit ELF, and callers should not have to know which. Detect the ELF class from the image header at parse time and dispatch to the matching parser, so a single entry point handles both layouts. Signed-off-by: John Hubbard <jhubbard@nvidia.com> Reviewed-by: Eliot Courtney <ecourtney@nvidia.com> Link: https://patch.msgid.link/20260602032111.224790-10-jhubbard@nvidia.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
1 parent 258a6f9 commit ad5f997

2 files changed

Lines changed: 25 additions & 6 deletions

File tree

drivers/gpu/nova-core/firmware.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -629,14 +629,33 @@ mod elf {
629629
})
630630
}
631631

632-
/// Tries to extract section with name `name` from the ELF64 image `elf`, and returns it.
633-
pub(super) fn elf64_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
632+
/// Extract the section with name `name` from the ELF64 image `elf`.
633+
fn elf64_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
634634
elf_section_generic::<Elf64Format>(elf, name)
635635
}
636636

637637
/// Extract the section with name `name` from the ELF32 image `elf`.
638-
#[expect(dead_code)]
639-
pub(super) fn elf32_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
638+
fn elf32_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
640639
elf_section_generic::<Elf32Format>(elf, name)
641640
}
641+
642+
/// Automatically detects ELF32 vs ELF64 based on the ELF header.
643+
pub(super) fn elf_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
644+
// ELF identification: a 4-byte magic followed by a class byte (32- vs 64-bit).
645+
const ELFMAG: &[u8] = b"\x7fELF";
646+
const SELFMAG: usize = ELFMAG.len();
647+
const EI_CLASS: usize = 4;
648+
const ELFCLASS32: u8 = 1;
649+
const ELFCLASS64: u8 = 2;
650+
651+
if elf.get(0..SELFMAG) != Some(ELFMAG) {
652+
return None;
653+
}
654+
655+
match *elf.get(EI_CLASS)? {
656+
ELFCLASS32 => elf32_section(elf, name),
657+
ELFCLASS64 => elf64_section(elf, name),
658+
_ => None,
659+
}
660+
}
642661
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl GspFirmware {
8888
pin_init::pin_init_scope(move || {
8989
let firmware = super::request_firmware(dev, chipset, "gsp", ver)?;
9090

91-
let fw_section = elf::elf64_section(firmware.data(), ".fwimage").ok_or(EINVAL)?;
91+
let fw_section = elf::elf_section(firmware.data(), ".fwimage").ok_or(EINVAL)?;
9292

9393
let size = fw_section.len();
9494

@@ -148,7 +148,7 @@ impl GspFirmware {
148148
signatures: {
149149
let sigs_section = Self::find_gsp_sigs_section(chipset);
150150

151-
elf::elf64_section(firmware.data(), sigs_section)
151+
elf::elf_section(firmware.data(), sigs_section)
152152
.ok_or(EINVAL)
153153
.and_then(|data| Coherent::from_slice(dev, data, GFP_KERNEL))?
154154
},

0 commit comments

Comments
 (0)