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.
> 

Reply via email to