[Intel-gfx] [RFC-v2 05/26] drm/i915/pxp: Implement ioctl action to set the user space context
Huang, Sean Z
sean.z.huang at intel.com
Sat Nov 21 00:35:19 UTC 2020
Implement one ioctl action to allow user space driver to set its
user space context, so PXP can track the context id through this
user space context list.
Signed-off-by: Huang, Sean Z <sean.z.huang at intel.com>
---
drivers/gpu/drm/i915/pxp/intel_pxp.c | 56 ++++++++++++++++++++
drivers/gpu/drm/i915/pxp/intel_pxp.h | 21 ++++++++
drivers/gpu/drm/i915/pxp/intel_pxp_context.c | 24 +++++++++
drivers/gpu/drm/i915/pxp/intel_pxp_context.h | 3 ++
4 files changed, 104 insertions(+)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index f6b7297ee045..34f6db3f8bd6 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -8,6 +8,60 @@
#include "intel_pxp_context.h"
#include "intel_pxp_sm.h"
+int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmfile)
+{
+ int ret;
+ struct pxp_info pxp_info = {0};
+ struct drm_i915_pxp_ops *pxp_ops = data;
+ struct drm_i915_private *i915 = to_i915(dev);
+
+ if (!i915 || !drmfile || !pxp_ops || pxp_ops->info_size != sizeof(pxp_info))
+ return -EINVAL;
+
+ if (copy_from_user(&pxp_info, pxp_ops->info_ptr, sizeof(pxp_info)) != 0)
+ return -EFAULT;
+
+ mutex_lock(&i915->pxp.ctx->ctx_mutex);
+
+ if (i915->pxp.ctx->global_state_in_suspend) {
+ drm_err(&i915->drm, "Return failure due to state in suspend\n");
+ pxp_info.sm_status = PXP_SM_STATUS_SESSION_NOT_AVAILABLE;
+ ret = 0;
+ goto end;
+ }
+
+ if (i915->pxp.ctx->global_state_attacked) {
+ drm_err(&i915->drm, "Retry required due to state attacked\n");
+ pxp_info.sm_status = PXP_SM_STATUS_RETRY_REQUIRED;
+ ret = 0;
+ goto end;
+ }
+
+ switch (pxp_info.action) {
+ case PXP_ACTION_SET_USER_CONTEXT:
+ {
+ ret = intel_pxp_set_user_ctx(i915, pxp_info.set_user_ctx);
+ break;
+ }
+ default:
+ drm_err(&i915->drm, "Failed to %s due to bad params\n", __func__);
+ ret = -EINVAL;
+ goto end;
+ }
+
+end:
+ mutex_unlock(&i915->pxp.ctx->ctx_mutex);
+
+ if (ret == 0)
+ if (copy_to_user(pxp_ops->info_ptr, &pxp_info, sizeof(pxp_info)) != 0)
+ ret = -EFAULT;
+
+ if (ret)
+ dev_err(&dev->pdev->dev, "pid=%d, ret = %d\n", task_pid_nr(current), ret);
+
+ return ret;
+}
+
static void intel_pxp_write_irq_mask_reg(struct drm_i915_private *i915, u32 mask)
{
WARN_ON(INTEL_GEN(i915) < 11);
@@ -37,6 +91,8 @@ static int intel_pxp_teardown_required_callback(struct drm_i915_private *i915)
i915->pxp.ctx->global_state_attacked = true;
i915->pxp.ctx->flag_display_hm_surface_keys = false;
+ intel_pxp_destroy_user_ctx_list(i915);
+
mutex_unlock(&i915->pxp.ctx->ctx_mutex);
return 0;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 9db4bf6fd3f8..a1e83bbeafb7 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -24,6 +24,26 @@ enum pxp_sm_session_req {
PXP_SM_REQ_SESSION_TERMINATE
};
+#define PXP_ACTION_SET_USER_CONTEXT 5
+
+enum pxp_sm_status {
+ PXP_SM_STATUS_SUCCESS,
+ PXP_SM_STATUS_RETRY_REQUIRED,
+ PXP_SM_STATUS_SESSION_NOT_AVAILABLE,
+ PXP_SM_STATUS_ERROR_UNKNOWN
+};
+
+struct pxp_info {
+ u32 action;
+ u32 sm_status;
+ u32 set_user_ctx;
+} __attribute__((packed));
+
+struct drm_i915_pxp_ops {
+ struct pxp_info __user *info_ptr;
+ __u32 info_size;
+};
+
struct pxp_context;
struct intel_pxp {
@@ -37,6 +57,7 @@ struct intel_pxp {
struct intel_gt;
struct drm_i915_private;
+int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmfile);
void intel_pxp_irq_handler(struct intel_gt *gt, u16 iir);
int i915_pxp_teardown_required_callback(struct drm_i915_private *i915);
int i915_pxp_global_terminate_complete_callback(struct drm_i915_private *i915);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_context.c b/drivers/gpu/drm/i915/pxp/intel_pxp_context.c
index c340c375daac..7fc99567b3ac 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_context.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_context.c
@@ -43,3 +43,27 @@ void intel_pxp_destroy_ctx(struct drm_i915_private *i915)
kfree(i915->pxp.ctx);
i915->pxp.ctx = NULL;
}
+
+int intel_pxp_set_user_ctx(struct drm_i915_private *i915, u32 user_ctx_in)
+{
+ struct pxp_user_ctx *user_ctx;
+
+ user_ctx = kzalloc(sizeof(*user_ctx), GFP_KERNEL);
+ if (!user_ctx)
+ return -ENOMEM;
+
+ user_ctx->user_ctx = user_ctx_in;
+
+ list_add(&user_ctx->listhead, &i915->pxp.ctx->user_ctx_list);
+ return 0;
+}
+
+void intel_pxp_destroy_user_ctx_list(struct drm_i915_private *i915)
+{
+ struct pxp_user_ctx *user_ctx, *n;
+
+ list_for_each_entry_safe(user_ctx, n, &i915->pxp.ctx->user_ctx_list, listhead) {
+ list_del(&user_ctx->listhead);
+ kfree(user_ctx);
+ }
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_context.h b/drivers/gpu/drm/i915/pxp/intel_pxp_context.h
index e0794dfb548d..c8b2d89e6548 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_context.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_context.h
@@ -41,4 +41,7 @@ struct pxp_user_ctx {
struct pxp_context *intel_pxp_create_ctx(struct drm_i915_private *i915);
void intel_pxp_destroy_ctx(struct drm_i915_private *i915);
+int intel_pxp_set_user_ctx(struct drm_i915_private *i915, u32 user_ctx);
+void intel_pxp_destroy_user_ctx_list(struct drm_i915_private *i915);
+
#endif /* __INTEL_PXP_CONTEXT_H__ */
--
2.17.1
More information about the Intel-gfx
mailing list