From: Lijo Lazar <[email protected]> Add ioctl to set tba/tma of level2 trap handler
Signed-off-by: Lijo Lazar <[email protected]> Reviewed-by: Alex Deucher <[email protected]> Change-Id: I6e3d326b6772e1e6ca4355ce82743e1714449713 --- 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 | 23 +++++ 4 files changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c index 6b6c11bb5fd7..1db74e1fc97d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cwsr.c @@ -532,3 +532,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 5717e1d662fc..2cf485111e8f 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 */ @@ -62,6 +62,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); @@ -84,4 +89,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 b2a8a8b37006..7a2b97d9f51a 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" #include "amdgpu_ualink.h" @@ -3122,6 +3123,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 9317018330ec..eed8a7f7e88b 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -60,6 +60,7 @@ extern "C" { #define DRM_AMDGPU_GEM_LIST_HANDLES 0x19 #define DRM_AMDGPU_PROC_OPTIONS 0x1A #define DRM_AMDGPU_UALINK_HANDLE 0x1B +#define DRM_AMDGPU_CWSR 0x1C #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) @@ -83,6 +84,7 @@ extern "C" { #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_PROC_OPTIONS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_PROC_OPTIONS, struct drm_amdgpu_proc_options) #define DRM_IOCTL_AMDGPU_UALINK_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_UALINK_HANDLE, union drm_amdgpu_ualink_handle) +#define DRM_IOCTL_AMDGPU_CWSR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CWSR, union drm_amdgpu_cwsr) /** * DOC: memory domains @@ -1695,6 +1697,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.34.1
