On 5/18/26 7:54 PM, Eliot Courtney wrote:
> 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: 6fda04e7f0cd ("gpu: nova-core: vbios: Add base support for VBIOS
> construction and iteration")
> Signed-off-by: Eliot Courtney <[email protected]>
> ---
> drivers/gpu/nova-core/vbios.rs | 25 +++++++++++--------------
> 1 file changed, 11 insertions(+), 14 deletions(-)
Reviewed-by: John Hubbard <[email protected]>
thanks,
--
John Hubbard
>
> diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs
> index 180928433766..79eb01dabc6f 100644
> --- a/drivers/gpu/nova-core/vbios.rs
> +++ b/drivers/gpu/nova-core/vbios.rs
> @@ -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.
>