@@ -69,6 +69,7 @@
#include "gt/intel_rc6.h"
#include "pxp/intel_pxp_pm.h"
+#include "pxp/intel_pxp.h"
#include "i915_debugfs.h"
#include "i915_drv.h"
@@ -1026,6 +1027,8 @@ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
/* Catch up with all the deferred frees from "this" client */
i915_gem_flush_free_objects(to_i915(dev));
+
+ intel_pxp_close(&(to_i915(dev)->gt.pxp), file);
}
static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
@@ -320,3 +320,18 @@ int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmf
ret = -EFAULT;
return ret;
}
+
+void intel_pxp_close(struct intel_pxp *pxp, struct drm_file *drmfile)
+{
+ int ret;
+ struct intel_gt *gt = container_of(pxp, typeof(*gt), pxp);
+
+ if (!drmfile)
+ return;
+
+ mutex_lock(&pxp->ctx.mutex);
+ ret = intel_pxp_sm_close(pxp, drmfile);
+ if (ret)
+ drm_err(>->i915->drm, "Failed to %s, ret=[%d]\n", __func__, ret);
+ mutex_unlock(&pxp->ctx.mutex);
+}
@@ -64,6 +64,7 @@ int intel_pxp_init(struct intel_pxp *pxp);
void intel_pxp_uninit(struct intel_pxp *pxp);
bool intel_pxp_gem_object_status(struct drm_i915_private *i915);
int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmfile);
+void intel_pxp_close(struct intel_pxp *pxp, struct drm_file *drmfile);
#else
static inline void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
{
@@ -97,6 +98,10 @@ static inline int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct
{
return 0;
}
+
+static inline void intel_pxp_close(struct intel_pxp *pxp, struct drm_file *drmfile)
+{
+}
#endif
#endif /* __INTEL_PXP_PM_H__ */
@@ -460,3 +460,28 @@ int intel_pxp_sm_ioctl_query_pxp_tag(struct intel_pxp *pxp,
return 0;
}
+
+int intel_pxp_sm_close(struct intel_pxp *pxp, struct drm_file *drmfile)
+{
+ int ret;
+ struct intel_pxp_sm_session *curr;
+
+ list_for_each_entry(curr, session_list(pxp, SESSION_TYPE_TYPE0), list) {
+ if (curr->drmfile && curr->drmfile == drmfile &&
+ curr->pid == pid_nr(drmfile->pid)) {
+ ret = pxp_terminate_hw_session(pxp, curr->type,
+ curr->index);
+ if (ret)
+ return ret;
+
+ ret = pxp_set_pxp_tag(pxp, curr->type, curr->index,
+ PROTECTION_MODE_NONE);
+ if (ret)
+ return ret;
+
+ list_del(&curr->list);
+ kfree(curr);
+ }
+ }
+ return 0;
+}
@@ -50,4 +50,5 @@ int intel_pxp_sm_ioctl_query_pxp_tag(struct intel_pxp *pxp,
bool intel_pxp_sm_is_hw_session_in_play(struct intel_pxp *pxp,
int session_type, int session_index);
int intel_pxp_sm_terminate_all_sessions(struct intel_pxp *pxp, int session_type);
+int intel_pxp_sm_close(struct intel_pxp *pxp, struct drm_file *drmfile);
#endif /* __INTEL_PXP_SM_H__ */
PXP should terminate the hardware session and cleanup the software state gracefully when the application has established the protection session, but doesn't close the session correctly due to some cases like application crash. Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com> --- drivers/gpu/drm/i915/i915_drv.c | 3 +++ drivers/gpu/drm/i915/pxp/intel_pxp.c | 15 +++++++++++++++ drivers/gpu/drm/i915/pxp/intel_pxp.h | 5 +++++ drivers/gpu/drm/i915/pxp/intel_pxp_sm.c | 25 +++++++++++++++++++++++++ drivers/gpu/drm/i915/pxp/intel_pxp_sm.h | 1 + 5 files changed, 49 insertions(+)