On Wed, Dec 3, 2025 at 8:44 AM Lijo Lazar <[email protected]> wrote:
>
> Add ioctl to set tba/tma of level2 trap handler
>
> Signed-off-by: Lijo Lazar <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h      |   1 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c | 105 +++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h |  11 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  |   2 +
>  include/uapi/drm/amdgpu_drm.h            |  24 ++++++
>  5 files changed, 141 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 1fb9539f8aca..ed50e4d6e308 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1663,7 +1663,6 @@ int amdgpu_enable_vblank_kms(struct drm_crtc *crtc);
>  void amdgpu_disable_vblank_kms(struct drm_crtc *crtc);
>  int amdgpu_info_ioctl(struct drm_device *dev, void *data,
>                       struct drm_file *filp);
> -
>  /*
>   * functions used by amdgpu_encoder.c
>   */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c
> index 1b4483b5d5a7..531be17aab1b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c
> @@ -491,3 +491,108 @@ void amdgpu_cwsr_free(struct amdgpu_device *adev, 
> struct amdgpu_vm *vm,
>         kfree(*trap_obj);
>         *trap_obj = NULL;
>  }
> +
> +static int amdgpu_cwsr_validate_user_addr(struct amdgpu_device *adev,
> +                                         struct amdgpu_vm *vm,
> +                                         struct amdgpu_cwsr_usr_addr 
> *usr_addr)
> +{
> +       struct amdgpu_bo_va_mapping *va_map;
> +       uint64_t addr;
> +       uint32_t size;
> +       int r;
> +
> +       addr = (usr_addr->addr & AMDGPU_GMC_HOLE_MASK) >> 
> AMDGPU_GPU_PAGE_SHIFT;
> +       size = usr_addr->size >> AMDGPU_GPU_PAGE_SHIFT;
> +
> +       r = amdgpu_bo_reserve(vm->root.bo, false);
> +       if (r)
> +               return r;
> +
> +       va_map = amdgpu_vm_bo_lookup_mapping(vm, addr);
> +       if (!va_map) {
> +               r = -EINVAL;
> +               goto err;
> +       }
> +       /* validate whether resident in the VM mapping range */
> +       if (addr >= va_map->start && va_map->last - addr + 1 >= size) {
> +               amdgpu_bo_unreserve(vm->root.bo);
> +               return 0;
> +       }
> +
> +       r = -EINVAL;
> +err:
> +       amdgpu_bo_unreserve(vm->root.bo);
> +
> +       return r;
> +}
> +
> +static int amdgpu_cwsr_set_l2_trap_handler(
> +       struct amdgpu_device *adev, struct amdgpu_vm *vm,
> +       struct amdgpu_cwsr_trap_obj *cwsr_obj, struct amdgpu_cwsr_usr_addr 
> *tma,
> +       struct amdgpu_cwsr_usr_addr *tba)
> +{
> +       uint64_t *l1tma;
> +       int r;
> +
> +       if (!amdgpu_cwsr_is_enabled(adev))
> +               return -EOPNOTSUPP;
> +
> +       if (!cwsr_obj || !cwsr_obj->tma_cpu_addr || !tma || !tba)
> +               return -EINVAL;
> +       r = amdgpu_cwsr_validate_user_addr(adev, vm, tma);
> +       if (r)
> +               return r;
> +       r = amdgpu_cwsr_validate_user_addr(adev, vm, tba);
> +       if (r)
> +               return r;
> +
> +       l1tma = (uint64_t *)(cwsr_obj->tma_cpu_addr);
> +       l1tma[0] = tma->addr;
> +       l1tma[1] = tba->addr;
> +
> +       return 0;
> +}
> +
> +/*
> + * Userspace cwsr related ioctl
> + */
> +/**
> + * amdgpu_cwsr_ioctl - Handle cwsr specific requests.
> + *
> + * @dev: drm device pointer
> + * @data: request object
> + * @filp: drm filp
> + *
> + * This function is used to perform cwsr and trap handler related operations
> + * Returns 0 on success, error code on failure.
> + */
> +int amdgpu_cwsr_ioctl(struct drm_device *dev, void *data, struct drm_file 
> *filp)
> +{
> +       struct amdgpu_device *adev = drm_to_adev(dev);
> +       union drm_amdgpu_cwsr *cwsr = data;
> +       struct amdgpu_fpriv *fpriv;
> +       int r;
> +
> +       fpriv = (struct amdgpu_fpriv *)filp->driver_priv;
> +
> +       if (!fpriv->cwsr_trap)
> +               return -EOPNOTSUPP;
> +
> +       switch (cwsr->in.op) {
> +       case AMDGPU_CWSR_OP_SET_L2_TRAP: {
> +               struct amdgpu_cwsr_usr_addr tba;
> +               struct amdgpu_cwsr_usr_addr tma;
> +
> +               tba.addr = cwsr->in.l2trap.tba;
> +               tba.size = cwsr->in.l2trap.tba_sz;
> +               tma.addr = cwsr->in.l2trap.tma;
> +               tma.size = cwsr->in.l2trap.tma_sz;
> +               r = amdgpu_cwsr_set_l2_trap_handler(
> +                       adev, &fpriv->vm, fpriv->cwsr_trap, &tma, &tba);
> +       } break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return r;
> +}
> \ No newline at end of file
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h
> index 96b03a8ed99b..32f3f23abd79 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.h
> @@ -31,7 +31,7 @@ struct amdgpu_device;
>  struct amdgpu_vm;
>
>  /**
> - * struct amdgpu_cwsr_obj - CWSR (Compute Wave Save Restore) buffer tracking
> + * struct amdgpu_cwsr_trap_obj - CWSR (Compute Wave Save Restore) buffer 
> tracking
>   * @bo: Buffer object for CWSR area
>   * @bo_va: Buffer object virtual address mapping
>   */
> @@ -63,6 +63,11 @@ struct amdgpu_cwsr_params {
>         uint32_t cwsr_sz;
>  };
>
> +struct amdgpu_cwsr_usr_addr {
> +       uint64_t addr;
> +       uint32_t size;
> +};
> +
>  int amdgpu_cwsr_init(struct amdgpu_device *adev);
>  void amdgpu_cwsr_fini(struct amdgpu_device *adev);
>
> @@ -79,4 +84,8 @@ uint32_t amdgpu_cwsr_size_needed(struct amdgpu_device 
> *adev, int num_xcc);
>  int amdgpu_cwsr_validate_params(struct amdgpu_device *adev,
>                                 struct amdgpu_cwsr_params *cwsr_params,
>                                 int num_xcc);
> +
> +int amdgpu_cwsr_ioctl(struct drm_device *dev, void *data,
> +                     struct drm_file *filp);
> +
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 16adeba4d7e6..8f5fcbe48a28 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -52,6 +52,7 @@
>  #include "amdgpu_sched.h"
>  #include "amdgpu_xgmi.h"
>  #include "amdgpu_userq.h"
> +#include "amdgpu_cwsr.h"
>  #include "amdgpu_userq_fence.h"
>  #include "../amdxcp/amdgpu_xcp_drv.h"
>
> @@ -3060,6 +3061,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
>         DRM_IOCTL_DEF_DRV(AMDGPU_SCHED, amdgpu_sched_ioctl, DRM_MASTER),
>         DRM_IOCTL_DEF_DRV(AMDGPU_BO_LIST, amdgpu_bo_list_ioctl, 
> DRM_AUTH|DRM_RENDER_ALLOW),
>         DRM_IOCTL_DEF_DRV(AMDGPU_FENCE_TO_HANDLE, 
> amdgpu_cs_fence_to_handle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
> +       DRM_IOCTL_DEF_DRV(AMDGPU_CWSR, amdgpu_cwsr_ioctl, 
> DRM_AUTH|DRM_RENDER_ALLOW),
>         /* KMS */
>         DRM_IOCTL_DEF_DRV(AMDGPU_GEM_MMAP, amdgpu_gem_mmap_ioctl, 
> DRM_AUTH|DRM_RENDER_ALLOW),
>         DRM_IOCTL_DEF_DRV(AMDGPU_GEM_WAIT_IDLE, amdgpu_gem_wait_idle_ioctl, 
> DRM_AUTH|DRM_RENDER_ALLOW),
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 1a27e218d4ea..f3b3c238d6d9 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -58,6 +58,7 @@ extern "C" {
>  #define DRM_AMDGPU_USERQ_SIGNAL                0x17
>  #define DRM_AMDGPU_USERQ_WAIT          0x18
>  #define DRM_AMDGPU_GEM_LIST_HANDLES    0x19
> +#define DRM_AMDGPU_CWSR 0x20
>
>  #define DRM_IOCTL_AMDGPU_GEM_CREATE    DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
>  #define DRM_IOCTL_AMDGPU_GEM_MMAP      DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
> @@ -79,6 +80,8 @@ extern "C" {
>  #define DRM_IOCTL_AMDGPU_USERQ_SIGNAL  DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_AMDGPU_USERQ_SIGNAL, struct drm_amdgpu_userq_signal)
>  #define DRM_IOCTL_AMDGPU_USERQ_WAIT    DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_AMDGPU_USERQ_WAIT, struct drm_amdgpu_userq_wait)
>  #define DRM_IOCTL_AMDGPU_GEM_LIST_HANDLES DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_AMDGPU_GEM_LIST_HANDLES, struct drm_amdgpu_gem_list_handles)
> +#define DRM_IOCTL_AMDGPU_CWSR \
> +       DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CWSR, union drm_amdgpu_cwsr)
>
>  /**
>   * DOC: memory domains
> @@ -1668,6 +1671,27 @@ struct drm_amdgpu_info_cwsr {
>         __u32 min_save_area_size;
>  };
>
> +/* cwsr ioctl */
> +#define AMDGPU_CWSR_OP_SET_L2_TRAP 1
> +
> +struct drm_amdgpu_cwsr_in {
> +       /* AMDGPU_CWSR_OP_* */
> +       __u32 op;
> +       struct {
> +               /* Level 2 trap handler base address */
> +               __u64 tba;

Maybe add _va so it's clear this is a gpu virtual address.

> +               /* Level 2 trap handler buffer size */
> +               __u32 tba_sz;
> +               /* Level 2 trap memory buffer address */
> +               __u64 tma;

Same here.

Alex

> +               /* Level 2 trap memory buffer size */
> +               __u32 tma_sz;
> +       } l2trap;
> +};
> +
> +union drm_amdgpu_cwsr {
> +       struct drm_amdgpu_cwsr_in in;
> +};
>  /*
>   * Supported GPU families
>   */
> --
> 2.49.0
>

Reply via email to