Re: [PATCH v2 06/31] gpu: nova-core: zero-pad radix3 page table levels to page boundary

From: Alexandre Courbot

Date: Sun Sep 06 2026 - 23:12:01 EST


On Sat Aug 22, 2026 at 10:54 AM JST, John Hubbard wrote:
> GSP-RM allocates the whole radix3 page table region in one block and
> zeroes it before writing entries. The booter reads each level a full
> page at a time when it walks the table, so every byte of a level page is
> firmware-visible whether or not it holds a valid entry.
>
> The driver allocates each level separately and writes only the valid
> entries, so the last page of each level is only partly written. The
> booter reads the whole page regardless, and a non-zero word in the
> unwritten remainder is indistinguishable from an entry.
>
> Allocate each level zeroed, sized to a whole number of GSP pages, and
> write the entries into it.
>
> Assisted-by: Cursor:claude-opus-5
> Reviewed-by: Timur Tabi <ttabi@xxxxxxxxxx>
> Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx>
> ---
> drivers/gpu/nova-core/firmware/radix3.rs | 50 ++++++++++++++++--------
> 1 file changed, 33 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/firmware/radix3.rs b/drivers/gpu/nova-core/firmware/radix3.rs
> index b60611c7bea0..b0630fd96c01 100644
> --- a/drivers/gpu/nova-core/firmware/radix3.rs
> +++ b/drivers/gpu/nova-core/firmware/radix3.rs
> @@ -67,22 +67,14 @@ pub(crate) fn new<'a>(
> Ok(try_pin_init!(Self {
> data <- SGTable::new(dev, data, DataDirection::ToDevice, GFP_KERNEL),
> level2 <- {
> - VVec::<u8>::with_capacity(
> - data.iter().count() * core::mem::size_of::<u64>(),
> - GFP_KERNEL,
> - )
> - .map_err(|_| ENOMEM)
> - .and_then(|level2| map_into_lvl(&data, level2))
> - .map(|level2| SGTable::new(dev, level2, DataDirection::ToDevice, GFP_KERNEL))?
> + let level2 = build_lvl(&data)?;
> +
> + SGTable::new(dev, level2, DataDirection::ToDevice, GFP_KERNEL)

Or alternatively:

level2 <- {
build_lvl(&data)
.map(|l2| SGTable::new(dev, l2, DataDirection::ToDevice, GFP_KERNEL))
},

I don't feel strongly about this, I just think it describes the flow a
bit better when there are no fleeting local variables. Feel free to keep
your version if you prefer it.

(also applicable to `level1` below)