RE: [PATCH] drm/amdgpu: fix BO placement overflow with four domain bits

"Li, Candice" <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <IA1PR12MB7661DE87F8DE4F6AC41CC84D91CF2@IA1PR12MB7661.namprd12.prod.outlook.com>
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;
+
+       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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.