Re: [PATCH] drm/etnaviv: Cycle through the MMUv1 address space again

From: Christian Gmeiner

Date: Wed Nov 04 2026 - 07:21:29 EST


Hi Lucas,

> Am Montag, dem 02.11.2026 um 13:22 +0100 schrieb Christian Gmeiner:
> > From: Christian Gmeiner <cgmeiner@xxxxxxxxxx>
> >
> > On MMUv1, all clients share one address space and the allocator
> > always picks the lowest free IOVA. When a process frees a range,
> > it can immediately be reused by another process.
> >
> > The GL.FLUSH_MMU write before the next submit does not reliably
> > invalidate stale TLB entries for that range. The GPU may therefore
> > continue translating accesses to the old pages. Writes through
> > these stale entries are lost for the new owner and may corrupt
> > memory that has already been freed.
> >
> > The vendor driver works around this in a similar way. It does not
> > return freed MMUv1 ranges to its free list until the address space
> > is exhausted.
> >
> Do you have more info on which engine inside the GPU causes those
> issues? If the TLB flush doesn't work reliably we have a much bigger
> issue than just address space reuse. If the TLB entries of freed memory
> are not properly shot down the GPU may write to memory that has been
> reused for something other than GPU buffers with a malicious command
> stream. That would be a security issue that is not currently checked by
> our command stream validation.
>
> Can you help me understand this a bit better? Which circumstances do
> trigger this issue?
>

I found this while looking into the flaky GC2000 tests in Mesa CI.

Reproducer: Run piglit "copyteximage RECT" in a loop, one run right
after the other. 20 out of 21 runs fail. With a 1s pause between
runs, the GPU goes into runtime suspend and all runs pass. Some of
the flaky GC2000 dEQP tests (for example fbo.render.color_clear.tex2d_rgb)
fail for the same reason.

In the failing runs, the first part of the texture is correct, but
from some page onwards, all pages still contain their old content.
The GPU either did not write to them or the writes went somewhere
else. The border between good and bad data is always on a 4K page
boundary. The command stream is identical in good and bad runs.

The bug only shows up when a new process gets IOVAs that were just
freed by the previous process. If the allocator does not reuse them
right away, the failures disappear.

So GL.FLUSH_MMU does not always drop the old translations on this
GPU. You are right: the GPU can then write to pages that have
already been freed, and my patch does not fix that. It only makes
it much less likely to happen.

Galcore writes GL.FLUSH_MMU in the same way. It does not run into
this problem because its allocator only reuses freed ranges when
the address space is full.

With this patch, I managed to run 20 rounds of piglit in CI
successfully, with an empty flakes file:

https://gitlab.freedesktop.org/austriancoder/mesa/-/jobs/113663487

Is this the proper fix? I don't know. Maybe we need some special
handling for MMUv1 to make the flush work 100%. I could try playing
with some of the MC_MMU_*_PAGE_TABLE registers to see if
that helps.

Maybe you have a good idea or a gut feeling about how we could fix
this?

--
greets
--
Christian Gmeiner, MSc

https://christian-gmeiner.info/privacypolicy