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