[Intel-gfx] [RFC-v3 05/26] drm/i915/pxp: Implement ioctl action to set the user space context

Huang, Sean Z sean.z.huang at intel.com
Tue Dec 1 23:57:26 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         | 57 ++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h         | 26 +++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_context.c | 24 +++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_context.h |  3 ++
 4 files changed, 110 insertions(+)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index d74a32b29716..ba473e1f4dde 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -8,6 +8,61 @@
 #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 || !i915->pxp.ctx || !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)
 {
 	/* crypto mask is in bit31-16 (Engine1 Interrupt Mask) */
@@ -35,6 +90,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 eb0ec4a07d3d..132aeccf8447 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 {
@@ -38,6 +58,7 @@ struct intel_gt;
 struct drm_i915_private;
 
 #ifdef CONFIG_DRM_I915_PXP
+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);
@@ -45,6 +66,11 @@ int i915_pxp_global_terminate_complete_callback(struct drm_i915_private *i915);
 int intel_pxp_init(struct drm_i915_private *i915);
 void intel_pxp_uninit(struct drm_i915_private *i915);
 #else
+static inline int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmfile)
+{
+	return 0;
+}
+
 static inline void intel_pxp_irq_handler(struct intel_gt *gt, u16 iir)
 {
 }
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