On Thu, Jan 22, 2026 at 6:02 AM Lijo Lazar <[email protected]> wrote: > > Add ioctl to set tba/tma of level2 trap handler > > Signed-off-by: Lijo Lazar <[email protected]>
Reviewed-by: Alex Deucher <[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 26b757c95579..c3dfd84c2962 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1575,7 +1575,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 32d9398cd1d1..70f444afece0 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c > @@ -510,3 +510,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_va; > + tba.size = cwsr->in.l2trap.tba_sz; > + tma.addr = cwsr->in.l2trap.tma_va; > + 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 b54240d40a6c..c9f61e393fde 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); > > @@ -85,4 +90,8 @@ static inline bool amdgpu_cwsr_has_dbg_wa(struct > amdgpu_device *adev) > > return gc_ver >= IP_VERSION(11, 0, 0) && gc_ver <= IP_VERSION(11, 0, > 3); > } > + > +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 771c89c84608..7fbd106fff8b 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -53,6 +53,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" > > @@ -3074,6 +3075,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 b7a858365174..a36e3e2e679c 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 > @@ -1680,6 +1683,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_va; > + /* Level 2 trap handler buffer size (in bytes) */ > + __u32 tba_sz; > + /* Level 2 trap memory buffer address */ > + __u64 tma_va; > + /* Level 2 trap memory buffer size (in bytes) */ > + __u32 tma_sz; > + } l2trap; > +}; > + > +union drm_amdgpu_cwsr { > + struct drm_amdgpu_cwsr_in in; > +}; > /* > * Supported GPU families > */ > -- > 2.49.0 >
