]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/xe/pxp: Add VCS inline termination support
authorDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Wed, 29 Jan 2025 17:41:27 +0000 (09:41 -0800)
committerDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Mon, 3 Feb 2025 19:51:09 +0000 (11:51 -0800)
The key termination is done with a specific submission to the VCS
engine. This flow will be triggered in response to a termination
interrupt, whose handling is coming in a follow-up patch in the series.

v2: clean up defines and command emission code. (John)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250129174140.948829-4-daniele.ceraolospurio@intel.com
drivers/gpu/drm/xe/instructions/xe_instr_defs.h
drivers/gpu/drm/xe/instructions/xe_mfx_commands.h [new file with mode: 0644]
drivers/gpu/drm/xe/instructions/xe_mi_commands.h
drivers/gpu/drm/xe/xe_lrc.h
drivers/gpu/drm/xe/xe_pxp_submit.c
drivers/gpu/drm/xe/xe_pxp_submit.h
drivers/gpu/drm/xe/xe_ring_ops.c

index fd2ce7ace5108f68e61387241a6ef75310fcf4ac..e559969468c443832371351ca49a86a123fd9eeb 100644 (file)
@@ -16,6 +16,7 @@
 #define XE_INSTR_CMD_TYPE              GENMASK(31, 29)
 #define   XE_INSTR_MI                  REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x0)
 #define   XE_INSTR_GSC                 REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x2)
+#define   XE_INSTR_VIDEOPIPE           REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x3)
 #define   XE_INSTR_GFXPIPE             REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x3)
 #define   XE_INSTR_GFX_STATE           REG_FIELD_PREP(XE_INSTR_CMD_TYPE, 0x4)
 
diff --git a/drivers/gpu/drm/xe/instructions/xe_mfx_commands.h b/drivers/gpu/drm/xe/instructions/xe_mfx_commands.h
new file mode 100644 (file)
index 0000000..3c0c97f
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef _XE_MFX_COMMANDS_H_
+#define _XE_MFX_COMMANDS_H_
+
+#include "instructions/xe_instr_defs.h"
+
+#define MFX_CMD_SUBTYPE                REG_GENMASK(28, 27) /* A.K.A cmd pipe */
+#define MFX_CMD_OPCODE         REG_GENMASK(26, 24)
+#define MFX_CMD_SUB_OPCODE     REG_GENMASK(23, 16)
+#define MFX_FLAGS_AND_LEN      REG_GENMASK(15, 0)
+
+#define XE_MFX_INSTR(subtype, op, sub_op) \
+       (XE_INSTR_VIDEOPIPE | \
+        REG_FIELD_PREP(MFX_CMD_SUBTYPE, subtype) | \
+        REG_FIELD_PREP(MFX_CMD_OPCODE, op) | \
+        REG_FIELD_PREP(MFX_CMD_SUB_OPCODE, sub_op))
+
+#define MFX_WAIT                               XE_MFX_INSTR(1, 0, 0)
+#define MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG     REG_BIT(9)
+#define MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG     REG_BIT(8)
+
+#define CRYPTO_KEY_EXCHANGE                    XE_MFX_INSTR(2, 6, 9)
+
+#endif
index 10ec2920d31b34cee9f7e175d4f9dcd16a9c7b20..167fb0f742de7b15062989cf485ddeaf0a4db801 100644 (file)
@@ -48,6 +48,7 @@
 #define   MI_LRI_LEN(x)                        (((x) & 0xff) + 1)
 
 #define MI_FLUSH_DW                    __MI_INSTR(0x26)
+#define   MI_FLUSH_DW_PROTECTED_MEM_EN REG_BIT(22)
 #define   MI_FLUSH_DW_STORE_INDEX      REG_BIT(21)
 #define   MI_INVALIDATE_TLB            REG_BIT(18)
 #define   MI_FLUSH_DW_CCS              REG_BIT(16)
@@ -66,4 +67,8 @@
 
 #define MI_BATCH_BUFFER_START          __MI_INSTR(0x31)
 
+#define MI_SET_APPID                   __MI_INSTR(0x0e)
+#define MI_SET_APPID_SESSION_ID_MASK   REG_GENMASK(6, 0)
+#define MI_SET_APPID_SESSION_ID(x)     REG_FIELD_PREP(MI_SET_APPID_SESSION_ID_MASK, x)
+
 #endif
index 4206e6a8b50a04e1c6b8a2434fa69e9fa23f64b4..b27e80cd842acefc8a96876c9ffa8eb6ac5a5c5a 100644 (file)
@@ -39,7 +39,8 @@ struct xe_lrc_snapshot {
        u32 ctx_job_timestamp;
 };
 
-#define LRC_PPHWSP_SCRATCH_ADDR (0x34 * 4)
+#define LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR (0x34 * 4)
+#define LRC_PPHWSP_PXP_INVAL_SCRATCH_ADDR (0x40 * 4)
 
 struct xe_lrc *xe_lrc_create(struct xe_hw_engine *hwe, struct xe_vm *vm,
                             u32 ring_size, u16 msix_vec);
index 52a6143b5ebe82d5bb238da012a88def32341b24..326baea679a35093c344391d07a9591530f5e751 100644 (file)
@@ -5,15 +5,21 @@
 
 #include "xe_pxp_submit.h"
 
+#include <linux/delay.h>
 #include <uapi/drm/xe_drm.h>
 
 #include "xe_device_types.h"
+#include "xe_bb.h"
 #include "xe_bo.h"
 #include "xe_exec_queue.h"
 #include "xe_gsc_submit.h"
 #include "xe_gt.h"
+#include "xe_lrc.h"
 #include "xe_pxp_types.h"
+#include "xe_sched_job.h"
 #include "xe_vm.h"
+#include "instructions/xe_mfx_commands.h"
+#include "instructions/xe_mi_commands.h"
 
 /*
  * 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)
        destroy_gsc_client_resources(&pxp->gsc_res);
        destroy_vcs_execution_resources(pxp);
 }
+
+#define emit_cmd(xe_, map_, offset_, val_) \
+       xe_map_wr(xe_, map_, (offset_) * sizeof(u32), u32, val_)
+
+/* stall until prior PXP and MFX/HCP/HUC objects are completed */
+#define MFX_WAIT_PXP (MFX_WAIT | \
+                     MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \
+                     MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG)
+static u32 pxp_emit_wait(struct xe_device *xe, struct iosys_map *batch, u32 offset)
+{
+       /* wait for cmds to go through */
+       emit_cmd(xe, batch, offset++, MFX_WAIT_PXP);
+       emit_cmd(xe, batch, offset++, 0);
+
+       return offset;
+}
+
+static u32 pxp_emit_session_selection(struct xe_device *xe, struct iosys_map *batch,
+                                     u32 offset, u32 idx)
+{
+       offset = pxp_emit_wait(xe, batch, offset);
+
+       /* pxp off */
+       emit_cmd(xe, batch, offset++, MI_FLUSH_DW | MI_FLUSH_IMM_DW);
+       emit_cmd(xe, batch, offset++, 0);
+       emit_cmd(xe, batch, offset++, 0);
+       emit_cmd(xe, batch, offset++, 0);
+
+       /* select session */
+       emit_cmd(xe, batch, offset++, MI_SET_APPID | MI_SET_APPID_SESSION_ID(idx));
+       emit_cmd(xe, batch, offset++, 0);
+
+       offset = pxp_emit_wait(xe, batch, offset);
+
+       /* pxp on */
+       emit_cmd(xe, batch, offset++, MI_FLUSH_DW |
+                                     MI_FLUSH_DW_PROTECTED_MEM_EN |
+                                     MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX |
+                                     MI_FLUSH_IMM_DW);
+       emit_cmd(xe, batch, offset++, LRC_PPHWSP_PXP_INVAL_SCRATCH_ADDR |
+                                     MI_FLUSH_DW_USE_GTT);
+       emit_cmd(xe, batch, offset++, 0);
+       emit_cmd(xe, batch, offset++, 0);
+
+       offset = pxp_emit_wait(xe, batch, offset);
+
+       return offset;
+}
+
+static u32 pxp_emit_inline_termination(struct xe_device *xe,
+                                      struct iosys_map *batch, u32 offset)
+{
+       /* session inline termination */
+       emit_cmd(xe, batch, offset++, CRYPTO_KEY_EXCHANGE);
+       emit_cmd(xe, batch, offset++, 0);
+
+       return offset;
+}
+
+static u32 pxp_emit_session_termination(struct xe_device *xe, struct iosys_map *batch,
+                                       u32 offset, u32 idx)
+{
+       offset = pxp_emit_session_selection(xe, batch, offset, idx);
+       offset = pxp_emit_inline_termination(xe, batch, offset);
+
+       return offset;
+}
+
+/**
+ * xe_pxp_submit_session_termination - submits a PXP inline termination
+ * @pxp: the xe_pxp structure
+ * @id: the session to terminate
+ *
+ * Emit an inline termination via the VCS engine to terminate a session.
+ *
+ * Returns 0 if the submission is successful, an errno value otherwise.
+ */
+int xe_pxp_submit_session_termination(struct xe_pxp *pxp, u32 id)
+{
+       struct xe_sched_job *job;
+       struct dma_fence *fence;
+       long timeout;
+       u32 offset = 0;
+       u64 addr = xe_bo_ggtt_addr(pxp->vcs_exec.bo);
+
+       offset = pxp_emit_session_termination(pxp->xe, &pxp->vcs_exec.bo->vmap, offset, id);
+       offset = pxp_emit_wait(pxp->xe, &pxp->vcs_exec.bo->vmap, offset);
+       emit_cmd(pxp->xe, &pxp->vcs_exec.bo->vmap, offset, MI_BATCH_BUFFER_END);
+
+       job = xe_sched_job_create(pxp->vcs_exec.q, &addr);
+       if (IS_ERR(job))
+               return PTR_ERR(job);
+
+       xe_sched_job_arm(job);
+       fence = dma_fence_get(&job->drm.s_fence->finished);
+       xe_sched_job_push(job);
+
+       timeout = dma_fence_wait_timeout(fence, false, HZ);
+
+       dma_fence_put(fence);
+
+       if (!timeout)
+               return -ETIMEDOUT;
+       else if (timeout < 0)
+               return timeout;
+
+       return 0;
+}
index fd21ac935be1588c5729ec2f437e4a47128cdece..4ee8c0acfed99defab3821811531d1f6fa183b0a 100644 (file)
@@ -6,9 +6,13 @@
 #ifndef __XE_PXP_SUBMIT_H__
 #define __XE_PXP_SUBMIT_H__
 
+#include <linux/types.h>
+
 struct xe_pxp;
 
 int xe_pxp_allocate_execution_resources(struct xe_pxp *pxp);
 void xe_pxp_destroy_execution_resources(struct xe_pxp *pxp);
 
+int xe_pxp_submit_session_termination(struct xe_pxp *pxp, u32 id);
+
 #endif /* __XE_PXP_SUBMIT_H__ */
index 9f327f27c0726ea84139b354f54a108c99932aa4..0c230ee53bba5d74478d5a5ea14da7a91ecc63ce 100644 (file)
@@ -118,7 +118,7 @@ static int emit_flush_invalidate(u32 flag, u32 *dw, int i)
        dw[i++] |= MI_INVALIDATE_TLB | MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_IMM_DW |
                MI_FLUSH_DW_STORE_INDEX;
 
-       dw[i++] = LRC_PPHWSP_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT;
+       dw[i++] = LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT;
        dw[i++] = 0;
        dw[i++] = ~0U;
 
@@ -156,7 +156,7 @@ static int emit_pipe_invalidate(u32 mask_flags, bool invalidate_tlb, u32 *dw,
 
        flags &= ~mask_flags;
 
-       return emit_pipe_control(dw, i, 0, flags, LRC_PPHWSP_SCRATCH_ADDR, 0);
+       return emit_pipe_control(dw, i, 0, flags, LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR, 0);
 }
 
 static int emit_store_imm_ppgtt_posted(u64 addr, u64 value,