|
5 | 5 |
|
6 | 6 | #include "xe_pxp_submit.h" |
7 | 7 |
|
| 8 | +#include <linux/delay.h> |
8 | 9 | #include <uapi/drm/xe_drm.h> |
9 | 10 |
|
10 | 11 | #include "xe_device_types.h" |
| 12 | +#include "xe_bb.h" |
11 | 13 | #include "xe_bo.h" |
12 | 14 | #include "xe_exec_queue.h" |
13 | 15 | #include "xe_gsc_submit.h" |
14 | 16 | #include "xe_gt.h" |
| 17 | +#include "xe_lrc.h" |
15 | 18 | #include "xe_pxp_types.h" |
| 19 | +#include "xe_sched_job.h" |
16 | 20 | #include "xe_vm.h" |
| 21 | +#include "instructions/xe_mfx_commands.h" |
| 22 | +#include "instructions/xe_mi_commands.h" |
17 | 23 |
|
18 | 24 | /* |
19 | 25 | * The VCS is used for kernel-owned GGTT submissions to issue key termination. |
@@ -197,3 +203,111 @@ void xe_pxp_destroy_execution_resources(struct xe_pxp *pxp) |
197 | 203 | destroy_gsc_client_resources(&pxp->gsc_res); |
198 | 204 | destroy_vcs_execution_resources(pxp); |
199 | 205 | } |
| 206 | + |
| 207 | +#define emit_cmd(xe_, map_, offset_, val_) \ |
| 208 | + xe_map_wr(xe_, map_, (offset_) * sizeof(u32), u32, val_) |
| 209 | + |
| 210 | +/* stall until prior PXP and MFX/HCP/HUC objects are completed */ |
| 211 | +#define MFX_WAIT_PXP (MFX_WAIT | \ |
| 212 | + MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \ |
| 213 | + MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG) |
| 214 | +static u32 pxp_emit_wait(struct xe_device *xe, struct iosys_map *batch, u32 offset) |
| 215 | +{ |
| 216 | + /* wait for cmds to go through */ |
| 217 | + emit_cmd(xe, batch, offset++, MFX_WAIT_PXP); |
| 218 | + emit_cmd(xe, batch, offset++, 0); |
| 219 | + |
| 220 | + return offset; |
| 221 | +} |
| 222 | + |
| 223 | +static u32 pxp_emit_session_selection(struct xe_device *xe, struct iosys_map *batch, |
| 224 | + u32 offset, u32 idx) |
| 225 | +{ |
| 226 | + offset = pxp_emit_wait(xe, batch, offset); |
| 227 | + |
| 228 | + /* pxp off */ |
| 229 | + emit_cmd(xe, batch, offset++, MI_FLUSH_DW | MI_FLUSH_IMM_DW); |
| 230 | + emit_cmd(xe, batch, offset++, 0); |
| 231 | + emit_cmd(xe, batch, offset++, 0); |
| 232 | + emit_cmd(xe, batch, offset++, 0); |
| 233 | + |
| 234 | + /* select session */ |
| 235 | + emit_cmd(xe, batch, offset++, MI_SET_APPID | MI_SET_APPID_SESSION_ID(idx)); |
| 236 | + emit_cmd(xe, batch, offset++, 0); |
| 237 | + |
| 238 | + offset = pxp_emit_wait(xe, batch, offset); |
| 239 | + |
| 240 | + /* pxp on */ |
| 241 | + emit_cmd(xe, batch, offset++, MI_FLUSH_DW | |
| 242 | + MI_FLUSH_DW_PROTECTED_MEM_EN | |
| 243 | + MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX | |
| 244 | + MI_FLUSH_IMM_DW); |
| 245 | + emit_cmd(xe, batch, offset++, LRC_PPHWSP_PXP_INVAL_SCRATCH_ADDR | |
| 246 | + MI_FLUSH_DW_USE_GTT); |
| 247 | + emit_cmd(xe, batch, offset++, 0); |
| 248 | + emit_cmd(xe, batch, offset++, 0); |
| 249 | + |
| 250 | + offset = pxp_emit_wait(xe, batch, offset); |
| 251 | + |
| 252 | + return offset; |
| 253 | +} |
| 254 | + |
| 255 | +static u32 pxp_emit_inline_termination(struct xe_device *xe, |
| 256 | + struct iosys_map *batch, u32 offset) |
| 257 | +{ |
| 258 | + /* session inline termination */ |
| 259 | + emit_cmd(xe, batch, offset++, CRYPTO_KEY_EXCHANGE); |
| 260 | + emit_cmd(xe, batch, offset++, 0); |
| 261 | + |
| 262 | + return offset; |
| 263 | +} |
| 264 | + |
| 265 | +static u32 pxp_emit_session_termination(struct xe_device *xe, struct iosys_map *batch, |
| 266 | + u32 offset, u32 idx) |
| 267 | +{ |
| 268 | + offset = pxp_emit_session_selection(xe, batch, offset, idx); |
| 269 | + offset = pxp_emit_inline_termination(xe, batch, offset); |
| 270 | + |
| 271 | + return offset; |
| 272 | +} |
| 273 | + |
| 274 | +/** |
| 275 | + * xe_pxp_submit_session_termination - submits a PXP inline termination |
| 276 | + * @pxp: the xe_pxp structure |
| 277 | + * @id: the session to terminate |
| 278 | + * |
| 279 | + * Emit an inline termination via the VCS engine to terminate a session. |
| 280 | + * |
| 281 | + * Returns 0 if the submission is successful, an errno value otherwise. |
| 282 | + */ |
| 283 | +int xe_pxp_submit_session_termination(struct xe_pxp *pxp, u32 id) |
| 284 | +{ |
| 285 | + struct xe_sched_job *job; |
| 286 | + struct dma_fence *fence; |
| 287 | + long timeout; |
| 288 | + u32 offset = 0; |
| 289 | + u64 addr = xe_bo_ggtt_addr(pxp->vcs_exec.bo); |
| 290 | + |
| 291 | + offset = pxp_emit_session_termination(pxp->xe, &pxp->vcs_exec.bo->vmap, offset, id); |
| 292 | + offset = pxp_emit_wait(pxp->xe, &pxp->vcs_exec.bo->vmap, offset); |
| 293 | + emit_cmd(pxp->xe, &pxp->vcs_exec.bo->vmap, offset, MI_BATCH_BUFFER_END); |
| 294 | + |
| 295 | + job = xe_sched_job_create(pxp->vcs_exec.q, &addr); |
| 296 | + if (IS_ERR(job)) |
| 297 | + return PTR_ERR(job); |
| 298 | + |
| 299 | + xe_sched_job_arm(job); |
| 300 | + fence = dma_fence_get(&job->drm.s_fence->finished); |
| 301 | + xe_sched_job_push(job); |
| 302 | + |
| 303 | + timeout = dma_fence_wait_timeout(fence, false, HZ); |
| 304 | + |
| 305 | + dma_fence_put(fence); |
| 306 | + |
| 307 | + if (!timeout) |
| 308 | + return -ETIMEDOUT; |
| 309 | + else if (timeout < 0) |
| 310 | + return timeout; |
| 311 | + |
| 312 | + return 0; |
| 313 | +} |
0 commit comments