Re: [PATCH] drm/amdgpu: fix BO placement overflow with four domain bits
Christian König <[email protected]> Mon, 3 Aug 2026 16:21:16 +0200
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
That change doesn't make any sense. Only CPU|GTT|VRAM can be combined together, that's why AMDGPU_BO_MAX_PLACEMENTS is 3. DOORBELL, GDS, GWS, OA are special resources without alternatives and can only be specified one at a time. On 7/24/26 05:12, Li, Candice wrote: > AMD General > > Ping. > > Cc @Koenig, Christian and @Deucher, Alexander > > > Thanks, > Candice > > -----Original Message----- > From: Li, Candice <[email protected]> > Sent: Tuesday, July 21, 2026 5:21 PM > To: [email protected] > Cc: Li, Candice <[email protected]> > Subject: [PATCH] drm/amdgpu: fix BO placement overflow with four domain bits > > AMDGPU_BO_MAX_PLACEMENTS was 3 but amdgpu_bo_placement_from_domain() > can emit up to four entries for CPU|GTT|VRAM|DOORBELL. Unprivileged > GEM_CREATE with domains=0x47 writes past placements[] and triggers > BUG_ON(). > > Increase the array to four and normalize mixed GDS/GWS/OA domain > masks to CPU-only placement on all rebuild paths. > > Signed-off-by: Candice Li <[email protected]> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 3 +-- > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h | 2 ++ > drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 18 ++++++++++++++++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 3 ++- > 4 files changed, 21 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c > index 6a0699746fbcd6..bcf81aba942842 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c > @@ -431,8 +431,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data, > flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED; > > /* create a gem object to contain this object in */ > - if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | > - AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) { > + if (args->in.domains & AMDGPU_GEM_DOMAIN_GDS_GWS_OA) { > if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) { > /* if gds bo is created from user space, it must be > * passed to bo list > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h > index b558336bc4c6ca..321db2ca29f4a3 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h > @@ -31,6 +31,8 @@ > */ > > #define AMDGPU_GEM_DOMAIN_MAX 0x3 > +#define AMDGPU_GEM_DOMAIN_GDS_GWS_OA \ > + (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA) > #define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, tbo.base) > > extern const struct drm_gem_object_funcs amdgpu_gem_object_funcs; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > index d4a9d5e8fb429a..bb02858cbebf0d 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > @@ -99,6 +99,19 @@ bool amdgpu_bo_is_amdgpu_bo(struct ttm_buffer_object *bo) > return false; > } > > +static u32 amdgpu_bo_filter_placement_domain(u32 domain) > +{ > + /* > + * GDS/GWS/OA are not normal fallback placement domains. When mixed > + * with CPU/GTT/VRAM/DOORBELL, fall back to CPU like amdgpu_bo_create(). > + */ > + if ((domain & AMDGPU_GEM_DOMAIN_GDS_GWS_OA) && > + (domain & ~AMDGPU_GEM_DOMAIN_GDS_GWS_OA)) > + return AMDGPU_GEM_DOMAIN_CPU; Absolutely clear NAK to that! That is simply a complete misunderstanding how things work here. Regards, Christian. > + > + return domain; > +} > + > /** > * amdgpu_bo_placement_from_domain - set buffer's placement > * @abo: &amdgpu_bo buffer object whose placement is to be set > @@ -115,6 +128,8 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain) > u64 flags = abo->flags; > u32 c = 0; > > + domain = amdgpu_bo_filter_placement_domain(domain); > + > if (domain & AMDGPU_GEM_DOMAIN_VRAM) { > unsigned int visible_pfn = adev->gmc.visible_vram_size >> PAGE_SHIFT; > int8_t mem_id = KFD_XCP_MEM_ID(adev, abo->xcp_id); > @@ -690,8 +705,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev, > bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC; > > bo->tbo.bdev = &adev->mman.bdev; > - if (bp->domain & (AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA | > - AMDGPU_GEM_DOMAIN_GDS)) > + if (bp->domain & AMDGPU_GEM_DOMAIN_GDS_GWS_OA) > amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU); > else > amdgpu_bo_placement_from_domain(bo, bp->domain); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h > index ff11a09034997e..20f4d8c243afdd 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h > @@ -37,7 +37,8 @@ > #endif > > #define AMDGPU_BO_INVALID_OFFSET LONG_MAX > -#define AMDGPU_BO_MAX_PLACEMENTS 3 > +/* Covers CPU | GTT | VRAM | DOORBELL placement candidates */ > +#define AMDGPU_BO_MAX_PLACEMENTS 4 > > /* BO flag to indicate a KFD userptr BO */ > #define AMDGPU_AMDKFD_CREATE_USERPTR_BO (1ULL << 63) > -- > 2.25.1 >