mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
gpu: nova-core: vbios: avoid reading too far in read_more_at_offset
Fix bug where `read_more_at_offset` would unnecessarily read more data.
This happens when the window to read has some part cached and some part
not. It would read `len` bytes instead of just the uncached portion,
which could read past `BIOS_MAX_SCAN_LEN`.
Fixes: 6fda04e7f0 ("gpu: nova-core: vbios: Add base support for VBIOS construction and iteration")
Reviewed-by: John Hubbard <jhubbard@nvidia.com>
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260525-fix-vbios-v5-3-e5e455251537@nvidia.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
parent
7a1d09e477
commit
33f1402bcf
|
|
@ -185,8 +185,13 @@ fn new(dev: &'a device::Device, bar0: &'a Bar0) -> Result<Self> {
|
|||
|
||||
/// Read bytes from the ROM at the current end of the data vector.
|
||||
fn read_more(&mut self, len: usize) -> Result {
|
||||
let current_len = self.data.len();
|
||||
let start = ROM_OFFSET + current_len;
|
||||
let start = self.data.len();
|
||||
let end = start + len;
|
||||
|
||||
if end > BIOS_MAX_SCAN_LEN {
|
||||
dev_err!(self.dev, "Error: exceeded BIOS scan limit.\n");
|
||||
return Err(EINVAL);
|
||||
}
|
||||
|
||||
// Ensure length is a multiple of 4 for 32-bit reads
|
||||
if len % core::mem::size_of::<u32>() != 0 {
|
||||
|
|
@ -200,9 +205,9 @@ fn read_more(&mut self, len: usize) -> Result {
|
|||
|
||||
self.data.reserve(len, GFP_KERNEL)?;
|
||||
// Read ROM data bytes and push directly to `data`.
|
||||
for addr in (start..start + len).step_by(core::mem::size_of::<u32>()) {
|
||||
for addr in (start..end).step_by(core::mem::size_of::<u32>()) {
|
||||
// Read 32-bit word from the VBIOS ROM
|
||||
let word = self.bar0.try_read32(addr)?;
|
||||
let word = self.bar0.try_read32(ROM_OFFSET + addr)?;
|
||||
|
||||
// Convert the `u32` to a 4 byte array and push each byte.
|
||||
word.to_ne_bytes()
|
||||
|
|
@ -215,17 +220,9 @@ fn read_more(&mut self, len: usize) -> Result {
|
|||
|
||||
/// Read bytes at a specific offset, filling any gap.
|
||||
fn read_more_at_offset(&mut self, offset: usize, len: usize) -> Result {
|
||||
if offset > BIOS_MAX_SCAN_LEN {
|
||||
dev_err!(self.dev, "Error: exceeded BIOS scan limit.\n");
|
||||
return Err(EINVAL);
|
||||
}
|
||||
let end = offset.checked_add(len).ok_or(EINVAL)?;
|
||||
|
||||
// If `offset` is beyond current data size, fill the gap first.
|
||||
let current_len = self.data.len();
|
||||
let gap_bytes = offset.saturating_sub(current_len);
|
||||
|
||||
// Now read the requested bytes at the offset.
|
||||
self.read_more(gap_bytes + len)
|
||||
self.read_more(end.saturating_sub(self.data.len()))
|
||||
}
|
||||
|
||||
/// Read a BIOS image at a specific offset and create a [`BiosImage`] from it.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user