Rust for Linux List
 help / color / mirror / Atom feed
From: "Danilo Krummrich" <dakr@kernel.org>
To: "Timur Tabi" <ttabi@nvidia.com>, "Miguel Ojeda" <ojeda@kernel.org>
Cc: "Luis Chamberlain" <mcgrof@kernel.org>,
	"Russ Weight" <russ.weight@linux.dev>,
	"Gary Guo" <gary@garyguo.net>,
	"Alexandre Courbot" <acourbot@nvidia.com>,
	"Eliot Courtney" <ecourtney@nvidia.com>,
	"John Hubbard" <jhubbard@nvidia.com>, <zhiw@nvidia.com>,
	<rust-for-linux@vger.kernel.org>, <driver-core@lists.linux.dev>,
	<nova-gpu@lists.linux.dev>
Subject: Re: [PATCH v7 3/8] gpu: nova-core: add TLV parser for firmware files
Date: Mon, 03 Aug 2026 23:38:57 +0200	[thread overview]
Message-ID: <DKFMU1XNJYZN.63NOEFLYN9XU@kernel.org> (raw)
In-Reply-To: <DKFMSHHGF3DE.2SUUP3FB7WXTK@kernel.org>

On Mon Aug 3, 2026 at 11:36 PM CEST, Danilo Krummrich wrote:
> @Miguel: One consideration for you below.
>
> On Fri Jul 31, 2026 at 10:10 PM CEST, Timur Tabi wrote:
>> +impl<'a> Tlv<'a> {
>> +    const MAGIC: &'static [u8; 4] = b"NVFW";
>> +
>> +    /// Parses `data` as a TLV firmware image, returning [`EINVAL`] if the image is malformed.
>> +    pub(crate) fn new(data: &'a [u8]) -> Result<Self> {
>> +        // Verify that the magic bytes exist and are the correct value
>> +        let magic_len = Self::MAGIC.len();
>> +        if data
>> +            .get(..magic_len)
>> +            .is_none_or(|magic| magic != Self::MAGIC)
>> +        {
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        // The payload is the contiguous sequence of TLV blocks after the magic.
>> +        let payload = data.get(magic_len..).ok_or(EINVAL)?;
>> +
>> +        if payload.is_empty() {
>> +            // Reject empty TLV files
>> +            return Err(ENODATA);
>> +        }
>
> This seems redundant, if payload is empty the below loop wouldn't execute and
> the !has_vers check would return EINVAL. Which seems consistent, since empty
> data is kinda invalid.
>
>> +
>> +        // The spec says every TLV must have a VERS tag.
>> +        let mut has_vers = false;
>> +
>> +        let mut rest = payload;
>> +        while !rest.is_empty() {
>> +            // Validate and extract the header (type, length).
>> +            let Some(header): Option<TlvBlockHeader> = rest
>> +                .get(..TlvBlockHeader::SIZE)
>> +                .and_then(TlvBlockHeader::parse)
>> +            else {
>> +                return Err(EINVAL);
>> +            };
>> +
>> +            has_vers |= header.tag == *b"VERS";
>> +
>> +            // The `length` field of a TLV block contains the actual byte length of the
>> +            // value, but each TLV block is aligned to a 4-byte boundary.
>> +            let Some(stored_size) = header.length.checked_next_multiple_of(4) else {
>> +                return Err(EINVAL);
>> +            };
>> +
>> +            let length = TlvBlockHeader::SIZE
>> +                .checked_add(stored_size)
>> +                .ok_or(EINVAL)?;
>> +
>> +            rest = rest.split_at_checked(length).ok_or(EINVAL)?.1;
>> +        }
>> +
>> +        if !has_vers {
>> +            return Err(EINVAL);
>> +        }
>
> [...]
>
>> +    fn find(&self, tag: &[u8; 4]) -> Result<TlvBlock<'a>> {
>> +        self.iter().find(|b| b.tag == *tag).ok_or(EINVAL)
>> +    }
>
> NIT: Do we really know the tag is invalid just because it wasn't found?
>
>> +    /// Return a slice of bytes.  Returns ENODATA if the value is empty.
>> +    pub(crate) fn get_bytes(&self, tag: &[u8; 4]) -> Result<&'a [u8]> {
>> +        let tlv = self.find(tag)?;
>> +
>> +        // Treat empty value as an error, to avoid trying to parse nothing.
>> +        if tlv.value.is_empty() {
>> +            return Err(ENODATA);
>> +        }
>
> This one seems resonable; but we don't have the error code in place. The commit
> message says the series depends on [1], but this likely goes through the Rust
> tree.
>
> Either we just add this single error code in a separate patch or Miguel provides
> a signed tag for [1].
>
> Since this is a perfectly trivial conflict, I'd go for the former.
>
> Miguel, let me know if you want to provide a signed tag, otherwise it would be
> good if Timur (or myself) could send a patch for ENODATA only.
>
> @Timur: In any case, no need to resend the series for this or the other two nits
> in this reply.
>
> Thanks,
> Danilo

[1] https://lore.kernel.org/all/20260629183022.2709524-1-ttabi@nvidia.com/

  reply	other threads:[~2026-08-03 21:39 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31 20:10 [PATCH v7 0/8] Transition Nova Core to TLV firmware images Timur Tabi
2026-07-31 20:10 ` [PATCH v7 1/8] rust: alloc: add Vec::zeroed method Timur Tabi
2026-08-03 21:22   ` Danilo Krummrich
2026-07-31 20:10 ` [PATCH v7 2/8] rust: firmware: add request_into_buf() Timur Tabi
2026-07-31 20:10 ` [PATCH v7 3/8] gpu: nova-core: add TLV parser for firmware files Timur Tabi
2026-08-03 21:36   ` Danilo Krummrich
2026-08-03 21:38     ` Danilo Krummrich [this message]
2026-08-03 22:05     ` Timur Tabi
2026-08-03 22:21       ` Danilo Krummrich
2026-08-04 17:10         ` Timur Tabi
2026-07-31 20:10 ` [PATCH v7 4/8] gpu: nova-core: transition booter to TLV images Timur Tabi
2026-07-31 20:10 ` [PATCH v7 5/8] gpu: nova-core: transition gsp " Timur Tabi
2026-07-31 20:10 ` [PATCH v7 6/8] gpu: nova-core: transition gen_bootloader " Timur Tabi
2026-07-31 20:10 ` [PATCH v7 7/8] gpu: nova-core: transition fsp " Timur Tabi
2026-07-31 20:10 ` [PATCH v7 8/8] gpu: nova-core: update firmware module info for " Timur Tabi
2026-08-03 13:51 ` [PATCH v7 0/8] Transition Nova Core to TLV firmware images Alexandre Courbot
2026-08-06  0:12 ` Danilo Krummrich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DKFMU1XNJYZN.63NOEFLYN9XU@kernel.org \
    --to=dakr@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=driver-core@lists.linux.dev \
    --cc=ecourtney@nvidia.com \
    --cc=gary@garyguo.net \
    --cc=jhubbard@nvidia.com \
    --cc=mcgrof@kernel.org \
    --cc=nova-gpu@lists.linux.dev \
    --cc=ojeda@kernel.org \
    --cc=russ.weight@linux.dev \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=ttabi@nvidia.com \
    --cc=zhiw@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox