Enable userspace to obtain a handle to the kernel-owned MMIO_REMAP
singleton when AMDGPU_GEM_DOMAIN_MMIO_REMAP is requested via
amdgpu_gem_create_ioctl().

Validate the fixed 4K constraint: if PAGE_SIZE > AMDGPU_GPU_PAGE_SIZE
return -EINVAL; when provided, size and alignment must equal
AMDGPU_GPU_PAGE_SIZE.

If the singleton BO is not available, return -ENODEV.

Cc: Christian König <christian.koe...@amd.com>
Suggested-by: Alex Deucher <alexander.deuc...@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmu...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 59 +++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index d8cffd26455b..655281f57a99 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -424,6 +424,38 @@ const struct drm_gem_object_funcs amdgpu_gem_object_funcs 
= {
        .vm_ops = &amdgpu_gem_vm_ops,
 };
 
+/**
+ * amdgpu_gem_get_mmio_remap_handle - Create a GEM handle for the MMIO_REMAP BO
+ * @file_priv: DRM file corresponding to the calling process
+ * @adev: amdgpu device
+ * @handle: returned userspace GEM handle (out)
+ *
+ * Creates a GEM handle to the kernel-owned singleton MMIO_REMAP buffer object
+ * (adev->rmmio_remap.bo). The BO is expected to be allocated during TTM init
+ * when the hardware exposes a remap base and PAGE_SIZE <= 4K.
+ *
+ * drm_gem_handle_create() acquires the handle reference, which will be dropped
+ * by GEM_CLOSE in userspace.
+ *
+ * * Return:
+ * * 0 on success
+ * * -ENODEV if the MMIO_REMAP BO is not available
+ * * A negative errno from drm_gem_handle_create() on failure
+ *
+ */
+static int amdgpu_gem_get_mmio_remap_handle(struct drm_file *file_priv,
+                                           struct amdgpu_device *adev,
+                                           u32 *handle)
+{
+       struct amdgpu_bo *bo = READ_ONCE(adev->rmmio_remap.bo);
+
+       if (!bo)
+               return -ENODEV;
+
+       /* drm_gem_handle_create() gets the ref; GEM_CLOSE drops it */
+       return drm_gem_handle_create(file_priv, &bo->tbo.base, handle);
+}
+
 /*
  * GEM ioctls.
  */
@@ -468,6 +500,33 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void 
*data,
        if (args->in.domains & AMDGPU_GEM_DOMAIN_MMIO_REMAP)
                return -EINVAL;
 
+       /*
+        * === MMIO remap (HDP flush) fast-path ===
+        * If userspace asks for the MMIO_REMAP domain, don't allocate a new BO.
+        * Return a handle to the singleton BO created at ttm init.
+        */
+       if (args->in.domains & AMDGPU_GEM_DOMAIN_MMIO_REMAP) {
+               /*
+                * The MMIO remap page is fixed 4K on the GPU side. Do not
+                * allow use if the system PAGE_SIZE is larger than the GPU
+                * page size.
+                */
+               if (PAGE_SIZE > AMDGPU_GPU_PAGE_SIZE)
+                       return -EINVAL;
+
+               /* Enforce fixed size/alignment when provided by userspace. */
+               if (size && size != AMDGPU_GPU_PAGE_SIZE)
+                       return -EINVAL;
+               if (args->in.alignment && args->in.alignment != 
AMDGPU_GPU_PAGE_SIZE)
+                       return -EINVAL;
+
+               r = amdgpu_gem_get_mmio_remap_handle(filp, adev, &handle);
+               if (r)
+                       return r;
+               args->out.handle = handle;
+               return 0;
+       }
+
        /* 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)) {
-- 
2.34.1

Reply via email to