0001
0002
0003
0004
0005
0006 #include "intel_pxp.h"
0007 #include "intel_pxp_cmd.h"
0008 #include "intel_pxp_session.h"
0009 #include "gt/intel_context.h"
0010 #include "gt/intel_engine_pm.h"
0011 #include "gt/intel_gpu_commands.h"
0012 #include "gt/intel_ring.h"
0013
0014 #include "i915_trace.h"
0015
0016
0017 #define MFX_WAIT_PXP (MFX_WAIT | \
0018 MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \
0019 MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG)
0020
0021 static u32 *pxp_emit_session_selection(u32 *cs, u32 idx)
0022 {
0023 *cs++ = MFX_WAIT_PXP;
0024
0025
0026 *cs++ = MI_FLUSH_DW;
0027 *cs++ = 0;
0028 *cs++ = 0;
0029
0030
0031 *cs++ = MI_SET_APPID | MI_SET_APPID_SESSION_ID(idx);
0032
0033 *cs++ = MFX_WAIT_PXP;
0034
0035
0036 *cs++ = MI_FLUSH_DW | MI_FLUSH_DW_PROTECTED_MEM_EN |
0037 MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
0038 *cs++ = I915_GEM_HWS_PXP_ADDR | MI_FLUSH_DW_USE_GTT;
0039 *cs++ = 0;
0040
0041 *cs++ = MFX_WAIT_PXP;
0042
0043 return cs;
0044 }
0045
0046 static u32 *pxp_emit_inline_termination(u32 *cs)
0047 {
0048
0049 *cs++ = CRYPTO_KEY_EXCHANGE;
0050 *cs++ = 0;
0051
0052 return cs;
0053 }
0054
0055 static u32 *pxp_emit_session_termination(u32 *cs, u32 idx)
0056 {
0057 cs = pxp_emit_session_selection(cs, idx);
0058 cs = pxp_emit_inline_termination(cs);
0059
0060 return cs;
0061 }
0062
0063 static u32 *pxp_emit_wait(u32 *cs)
0064 {
0065
0066 *cs++ = MFX_WAIT_PXP;
0067 *cs++ = 0;
0068
0069 return cs;
0070 }
0071
0072
0073
0074
0075
0076 #define SELECTION_LEN 10
0077 #define TERMINATION_LEN 2
0078 #define SESSION_TERMINATION_LEN(x) ((SELECTION_LEN + TERMINATION_LEN) * (x))
0079 #define WAIT_LEN 2
0080
0081 static void pxp_request_commit(struct i915_request *rq)
0082 {
0083 struct i915_sched_attr attr = { .priority = I915_PRIORITY_MAX };
0084 struct intel_timeline * const tl = i915_request_timeline(rq);
0085
0086 lockdep_unpin_lock(&tl->mutex, rq->cookie);
0087
0088 trace_i915_request_add(rq);
0089 __i915_request_commit(rq);
0090 __i915_request_queue(rq, &attr);
0091
0092 mutex_unlock(&tl->mutex);
0093 }
0094
0095 int intel_pxp_terminate_session(struct intel_pxp *pxp, u32 id)
0096 {
0097 struct i915_request *rq;
0098 struct intel_context *ce = pxp->ce;
0099 u32 *cs;
0100 int err = 0;
0101
0102 if (!intel_pxp_is_enabled(pxp))
0103 return 0;
0104
0105 rq = i915_request_create(ce);
0106 if (IS_ERR(rq))
0107 return PTR_ERR(rq);
0108
0109 if (ce->engine->emit_init_breadcrumb) {
0110 err = ce->engine->emit_init_breadcrumb(rq);
0111 if (err)
0112 goto out_rq;
0113 }
0114
0115 cs = intel_ring_begin(rq, SESSION_TERMINATION_LEN(1) + WAIT_LEN);
0116 if (IS_ERR(cs)) {
0117 err = PTR_ERR(cs);
0118 goto out_rq;
0119 }
0120
0121 cs = pxp_emit_session_termination(cs, id);
0122 cs = pxp_emit_wait(cs);
0123
0124 intel_ring_advance(rq, cs);
0125
0126 out_rq:
0127 i915_request_get(rq);
0128
0129 if (unlikely(err))
0130 i915_request_set_error_once(rq, err);
0131
0132 pxp_request_commit(rq);
0133
0134 if (!err && i915_request_wait(rq, 0, HZ / 5) < 0)
0135 err = -ETIME;
0136
0137 i915_request_put(rq);
0138
0139 return err;
0140 }
0141