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;
+               /* Level 2 trap handler buffer size */
+               __u32 tba_sz;
+               /* Level 2 trap memory buffer address */
+               __u64 tma;
+               /* 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