On Wed, Feb 26, 2020 at 4:29 PM Jason Ekstrand <jason@xxxxxxxxxxxxxx> wrote:
On Wed, Feb 26, 2020 at 4:05 AM Daniel Vetter <daniel@xxxxxxxx> wrote:
On Wed, Feb 26, 2020 at 10:16:05AM +0100, Christian KÃnig wrote:Right. I thought about that but I'm still learning how dma_resv
[SNIP]
Just imagine that you access some DMA-buf with a shader and that operation
is presented as a fence on the DMA-bufs reservation object. And now you can
go ahead and replace that fence and free up the memory.
Tricking the Linux kernel into allocating page tables in that freed memory
is trivial and that's basically it you can overwrite page tables with your
shader and gain access to all of system memory :)
What we could do is to always make sure that the added fences will complete
later than the already existing ones, but that is also rather tricky to get
right. I wouldn't do that if we don't have a rather big use case for this.
works. It'd be easy enough to make a fence array that contains both
the old fence and the new fence and replace the old fence with that.
What I don't know is the proper way to replace the exclusive fence
safely. Some sort of atomic_cpxchg loop, perhaps? I presume there's
some way of doing it properly because DRM drivers are doing it all the
time.
I think for an exclusive fence you may need to create a fence array
that includes the existing exclusive and shared fences in the dma_resv
combined with the added fence.
However, I'm not sure what the best way is to do garbage collection on
that so that we don't get an impossibly list of fence arrays.
(Note
the dma_resv has a lock that needs to be taken before adding an
exclusive fence, might be useful). Some code that does a thing like
this is __dma_resv_make_exclusive in
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
The other piece of the puzzle is that on the submit path this would
need something to ignore implicit fences. And there semantically the
question comes up whether it is safe for a driver to ignore exclusive
fences from another driver. (and then we have amdgpu which has its own
rules on exclusiveness of its shared fences based on the context. e.g.
the current option to ignore implicit fences for a buffer still syncs
on exclusive fences on the buffer).