[PATCH v3 9/9] drm/amdgpu/gem: Return Handle to MMIO_REMAP Singleton in GEM_CREATE

Alex Deucher alexdeucher at gmail.com
Thu Aug 28 15:14:51 UTC 2025


On Thu, Aug 28, 2025 at 5:28 AM Srinivasan Shanmugam
<srinivasan.shanmugam at amd.com> wrote:
>
> 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.
>
> v2:
> - Drop READ_ONCE() on adev->mmio_remap.bo (use a plain pointer load).
>   The pointer is set `bo = adev->mmio_remap.bo;` ie., The pointer is
>   written once during init and not changed while IOCTLs run. There’s no
>   concurrent writer in this execution path, so a normal read is safe.
>   (Alex)
>
> Cc: Christian König <christian.koenig at amd.com>
> Suggested-by: Alex Deucher <alexander.deucher at amd.com>
> Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 59 +++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 18 +++-----
>  2 files changed, 66 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> index d3c369742124..465f9d4a79d7 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 = 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)) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 0e301cab74e0..14af9b0b8673 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1854,14 +1854,13 @@ static void amdgpu_ttm_pools_fini(struct amdgpu_device *adev)
>  }
>
>  /**
> - * amdgpu_ttm_mmio_remap_bo_init - allocate the singleton 4K MMIO_REMAP BO
> + * amdgpu_ttm_mmio_remap_bo_init - Allocate the singleton 4K MMIO_REMAP BO
>   * @adev: amdgpu device
>   *
>   * Allocates a one-page (4K) GEM BO in AMDGPU_GEM_DOMAIN_MMIO_REMAP when the
>   * hardware exposes a remap base (adev->rmmio_remap.bus_addr) and the host
>   * PAGE_SIZE is <= AMDGPU_GPU_PAGE_SIZE (4K). The BO is created as a regular
> - * GEM object (amdgpu_bo_create), then reserved and kmap’ed once to exercise
> - * the io-mem setup path. If prerequisites are not met, this is a no-op.
> + * GEM object (amdgpu_bo_create).
>   *
>   * Return:
>   *  * 0 on success or intentional skip (feature not present/unsupported)
> @@ -1871,16 +1870,13 @@ static int amdgpu_ttm_mmio_remap_bo_init(struct amdgpu_device *adev)
>  {
>         int r;
>         struct amdgpu_bo_param bp = { 0 };
> -       void *kptr;
>
> -       /* Skip if HW doesn’t expose remap or system PAGE > GPU 4K */
> +       /* Skip if HW doesn’t expose remap or
> +        * Hardware remap page is fixed 4K; skip on larger PAGE_SIZE.
> +        */
>         if (!adev->rmmio_remap.bus_addr || PAGE_SIZE > AMDGPU_GPU_PAGE_SIZE)
>                 return 0;
>
> -       /* Hardware remap page is fixed 4K; skip on larger PAGE_SIZE. */
> -       if (PAGE_SIZE > AMDGPU_GPU_PAGE_SIZE)
> -               return 0;
> -
>         /* Create exactly one GEM BO in the MMIO_REMAP domain. */
>         bp.type        = ttm_bo_type_device;          /* userspace-mappable GEM */
>         bp.size        = AMDGPU_GPU_PAGE_SIZE;        /* 4K */
> @@ -1898,7 +1894,7 @@ static int amdgpu_ttm_mmio_remap_bo_init(struct amdgpu_device *adev)
>  }
>
>  /**
> - * amdgpu_ttm_mmio_remap_bo_fini - free the singleton MMIO_REMAP BO
> + * amdgpu_ttm_mmio_remap_bo_fini - Free the singleton MMIO_REMAP BO
>   * @adev: amdgpu device
>   *
>   * Frees the kernel-owned MMIO_REMAP BO if it was allocated by
> @@ -1907,7 +1903,7 @@ static int amdgpu_ttm_mmio_remap_bo_init(struct amdgpu_device *adev)
>  static void amdgpu_ttm_mmio_remap_bo_fini(struct amdgpu_device *adev)
>  {
>         amdgpu_bo_unref(&adev->rmmio_remap.bo);
> -       adev->mmio_remap.bo = NULL;
> +       adev->rmmio_remap.bo = NULL;
>  }

The above cleanups in amdgpu_ttm.c should be folded into the original
patches.  They are unrelated to this patch.

Alex

>
>  /*
> --
> 2.34.1
>


More information about the amd-gfx mailing list