[PATCH 2/2] drm/amdgpu: Dirty cleared blocks on allocation
Natalie Vock
natalie.vock at gmx.de
Wed May 28 09:29:06 UTC 2025
Hi,
On 5/28/25 09:07, Christian König wrote:
> On 5/27/25 21:43, Natalie Vock wrote:
>> If we hand out cleared blocks to users, they are expected to write
>> at least some non-zero values somewhere. If we keep the CLEAR bit set on
>> the block, amdgpu_fill_buffer will assume there is nothing to do and
>> incorrectly skip clearing the block. Ultimately, the (still dirty) block
>> will be reused as if it were cleared, without any wiping of the memory
>> contents.
>>
>> Most severely, this means that any buffer allocated with
>> AMDGPU_GEM_CREATE_VRAM_CLEARED | AMDGPU_GEM_CREATE_WIPE_ON_RELEASE
>> (which is the case for **all userspace buffers**) are neither
>> guaranteed to contain cleared VRAM, nor are they being wiped on
>> release, potentially leaking application memory to arbitrary other
>> applications.
>>
>> Fixes: a68c7eaa7a8ff ("drm/amdgpu: Enable clear page functionality")
>> Cc: stable at vger.kernel.org
>>
>> Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3812
>>
>> Signed-off-by: Natalie Vock <natalie.vock at gmx.de>
>> ---
>> drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 7 +++++++
>> 1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
>> index 2d7f82e98df9..cecc67d0f0b8 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
>> @@ -591,6 +591,13 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
>> list_for_each_entry(block, &vres->blocks, link) {
>> unsigned long start;
>>
>> + /*
>> + * Allocated blocks may be dirtied as soon as we return.
>> + * Mark all blocks as dirty here, otherwise we might
>> + * incorrectly assume the memory is still zeroed.
>> + */
>> + drm_buddy_block_set_dirty(block);
>
> Exactly that makes no sense.
>
> We need the information if it's dirty or not later while clearing the blocks. Otherwise we will clear all blocks and completely loose the advantage of the clear tracking.
Right, I missed that separate clear on allocation. I was put a bit
off-track by assuming DRM_BUDDY_ALLOCATE_CLEARED would guarantee cleared
pages, when in reality it's more like a preference.
>
> So we should set them dirty as soon as we are done with the clearing.
>
> But the problem rather seems to be that we sometimes don't clear the buffers on release for some reason, but still set it as cleared.
Yes precisely - "some reason" being the aforementioned clear flags. We
do always call amdgpu_clear_buffer on release, but that function will
perform the same checks as the clear on allocation does - that means, if
a block is marked clear then it will skip emitting any actual clears.
If we don't mark the blocks as dirty after allocating, then the
amdgpu_clear_buffer call on release will skip actually performing the
clear like it did during allocation - this is obviously really broken.
After calling amdgpu_clear_buffer, we call amdgpu_vram_mgr_set_cleared
which causes the drm_buddy blocks to be marked as "cleared" when freed.
This part is correct in itself, but obviously breaks if
amdgpu_clear_buffer didn't actually clear the buffer. That's how the
dirty blocks end up in the buddy allocator as cleared ones.
I'm testing a v2 that sets the dirty flags after the initial clear, I'll
send it once I confirmed it works.
Thanks,
Natalie
>
> Regards,
> Christian.
>
>
>> +
>> start = amdgpu_vram_mgr_block_start(block) +
>> amdgpu_vram_mgr_block_size(block);
>> start >>= PAGE_SHIFT;
>
More information about the dri-devel
mailing list