Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Critical] pt_pages_upper_bound incorrectly computes the best-case page table capacity, leading to GPU Use-After-Free via under-allocation. --
commit 48288e6179a4c23329aba38095ea6a337c240c2a Author: Joel Fernandes <[email protected]> gpu: nova-core: mm: pagetable: Add MmuConfig trait This commit introduces the MmuConfig trait to tie entry-operation traits together with version-specific constants and helpers. It provides zero-sized marker structs for MMU v2 and v3 to fully resolve dispatch at compile time without runtime overhead. > diff --git a/drivers/gpu/nova-core/mm/pagetable.rs > b/drivers/gpu/nova-core/mm/pagetable.rs > index 128bfc0d277a8..d88499ed3d563 100644 > --- a/drivers/gpu/nova-core/mm/pagetable.rs > +++ b/drivers/gpu/nova-core/mm/pagetable.rs [ ... ] > @@ -213,6 +214,114 @@ fn write(&self, pramin: &mut pramin::Pramin<'_>, addr: > VramAddress) -> Result { [ ... ] > + /// Compute upper bound on page table pages needed for `num_virt_pages`. > + /// > + /// Walks from PTE level up through PDE levels, accumulating the tree. > + fn pt_pages_upper_bound(num_virt_pages: usize) -> usize { > + let mut total = 0; > + > + // PTE pages at the leaf level. > + let pte_epp = Self::entries_per_page(Self::PTE_LEVEL); > + let mut pages_at_level = num_virt_pages.div_ceil(pte_epp); > + total += pages_at_level; > + > + // Walk PDE levels bottom-up (reverse of PDE_LEVELS). > + for &level in Self::PDE_LEVELS.iter().rev() { > + let epp = Self::entries_per_page(level); > + > + // How many pages at this level do we need to point to > + // the previous pages_at_level? > + pages_at_level = pages_at_level.div_ceil(epp); [Severity: Critical] Does this calculation account for unaligned virtual memory mappings? If a userspace application requests an unaligned virtual memory mapping (e.g., via a BAR1 mapping or DRM VM bind that crosses a 512-page PTE boundary), computing capacity using div_ceil on num_virt_pages and pages_at_level assumes perfect alignment. This propagates the flawed alignment assumption to all higher directory levels, systematically underestimating the maximum pages required. If the capacity is underestimated, when install_mappings allocates PDEs and pushes the newly allocated pages into page_table_allocs, push_within_capacity can fail with ENOMEM. Since this happens after the hardware PDE has already been written, the function bails out and AllocatedBlocks is dropped. This frees the VRAM while the GPU MMU still points to it, which could lead to a use-after-free of GPU VRAM. > + total += pages_at_level; > + } > + > + total > + } -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=9
