Create the irq worker that serves as callback handler, those callback stubs should be called while the hardware key teardown occurs. Signed-off-by: Huang, Sean Z <sean.z.huang@xxxxxxxxx> --- drivers/gpu/drm/i915/gt/intel_gt_irq.c | 4 + drivers/gpu/drm/i915/i915_reg.h | 3 +- drivers/gpu/drm/i915/pxp/intel_pxp.c | 101 +++++++++++++++++++ drivers/gpu/drm/i915/pxp/intel_pxp.h | 27 +++++ drivers/gpu/drm/i915/pxp/intel_pxp_context.c | 2 + drivers/gpu/drm/i915/pxp/intel_pxp_context.h | 1 + 6 files changed, 137 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c index 9830342aa6f4..b92072554ab3 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c @@ -14,6 +14,7 @@ #include "intel_lrc_reg.h" #include "intel_uncore.h" #include "intel_rps.h" +#include "pxp/intel_pxp.h" static void guc_irq_handler(struct intel_guc *guc, u16 iir) { @@ -107,6 +108,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance, if (instance == OTHER_GTPM_INSTANCE) return gen11_rps_irq_handler(>->rps, iir); + if (instance == OTHER_KCR_INSTANCE) + return intel_pxp_irq_handler(>->pxp, iir); + WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n", instance, iir); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0023c023f472..1e8dfe435ca8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7944,6 +7944,7 @@ enum { /* irq instances for OTHER_CLASS */ #define OTHER_GUC_INSTANCE 0 #define OTHER_GTPM_INSTANCE 1 +#define OTHER_KCR_INSTANCE 4 #define GEN11_INTR_IDENTITY_REG(x) _MMIO(0x190060 + ((x) * 4)) @@ -7966,7 +7967,7 @@ enum { #define GEN11_VECS0_VECS1_INTR_MASK _MMIO(0x1900d0) #define GEN11_GUC_SG_INTR_MASK _MMIO(0x1900e8) #define GEN11_GPM_WGBOXPERF_INTR_MASK _MMIO(0x1900ec) -#define GEN11_CRYPTO_RSVD_INTR_MASK _MMIO(0x1900f0) +#define GEN11_CRYPTO_INTR_MASK _MMIO(0x1900f0) /* crypto mask is in bit31-16 (Engine1 Interrupt Mask) */ #define GEN11_GUNIT_CSME_INTR_MASK _MMIO(0x1900f4) #define ENGINE1_MASK REG_GENMASK(31, 16) diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index 67bdaeb79b40..9bcb170b34f1 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -14,6 +14,70 @@ /* Setting KCR Init bit is required after system boot */ #define KCR_INIT_ALLOW_DISPLAY_ME_WRITES (BIT(14) | (BIT(14) << KCR_INIT_MASK_SHIFT)) +static void intel_pxp_write_irq_mask_reg(struct intel_gt *gt, u32 mask) +{ + lockdep_assert_held(>->irq_lock); + + intel_uncore_write(gt->uncore, GEN11_CRYPTO_INTR_MASK, mask << 16); +} + +static int intel_pxp_teardown_required_callback(struct intel_pxp *pxp) +{ + int ret; + + mutex_lock(&pxp->ctx.mutex); + + pxp->ctx.global_state_attacked = true; + + mutex_unlock(&pxp->ctx.mutex); + + return ret; +} + +static int intel_pxp_global_terminate_complete_callback(struct intel_pxp *pxp) +{ + int ret = 0; + struct intel_gt *gt = container_of(pxp, typeof(*gt), pxp); + + mutex_lock(&pxp->ctx.mutex); + + if (pxp->ctx.global_state_attacked) { + pxp->ctx.global_state_attacked = false; + + /* Re-create the arb session after teardown handle complete */ + ret = intel_pxp_arb_create_session(pxp); + if (ret) { + drm_err(>->i915->drm, "Failed to create arb session\n"); + goto end; + } + } +end: + mutex_unlock(&pxp->ctx.mutex); + return ret; +} + +static void intel_pxp_irq_work(struct work_struct *work) +{ + struct intel_pxp *pxp = container_of(work, typeof(*pxp), irq_work); + struct intel_gt *gt = container_of(pxp, typeof(*gt), pxp); + u32 events = 0; + + spin_lock_irq(>->irq_lock); + events = fetch_and_zero(&pxp->current_events); + spin_unlock_irq(>->irq_lock); + + if (events & PXP_IRQ_VECTOR_DISPLAY_PXP_STATE_TERMINATED || + events & PXP_IRQ_VECTOR_DISPLAY_APP_TERM_PER_FW_REQ) + intel_pxp_teardown_required_callback(pxp); + + if (events & PXP_IRQ_VECTOR_PXP_DISP_STATE_RESET_COMPLETE) + intel_pxp_global_terminate_complete_callback(pxp); + + spin_lock_irq(>->irq_lock); + intel_pxp_write_irq_mask_reg(gt, 0); + spin_unlock_irq(>->irq_lock); +} + int intel_pxp_init(struct intel_pxp *pxp) { struct intel_gt *gt = container_of(pxp, struct intel_gt, pxp); @@ -28,6 +92,12 @@ int intel_pxp_init(struct intel_pxp *pxp) intel_pxp_tee_component_init(pxp); + INIT_WORK(&pxp->irq_work, intel_pxp_irq_work); + + pxp->handled_irr = (PXP_IRQ_VECTOR_DISPLAY_PXP_STATE_TERMINATED | + PXP_IRQ_VECTOR_DISPLAY_APP_TERM_PER_FW_REQ | + PXP_IRQ_VECTOR_PXP_DISP_STATE_RESET_COMPLETE); + drm_info(>->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n"); return 0; @@ -39,3 +109,34 @@ void intel_pxp_uninit(struct intel_pxp *pxp) intel_pxp_ctx_fini(&pxp->ctx); } + +/** + * intel_pxp_irq_handler - Proxies KCR interrupts to PXP. + * @pxp: pointer to pxp struct + * @iir: GT interrupt vector associated with the interrupt + * + * Dispatches each vector element into an IRQ to PXP. + */ +void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir) +{ + struct drm_i915_private *i915; + const u32 events = iir & pxp->handled_irr; + struct intel_gt *gt = container_of(pxp, typeof(*gt), pxp); + + if (!gt || !gt->i915 || INTEL_GEN(i915) < 12) + return; + + i915 = gt->i915; + + lockdep_assert_held(>->irq_lock); + + if (unlikely(!events)) { + drm_err(&i915->drm, "%s returned due to iir=[0x%04x]\n", __func__, iir); + return; + } + + intel_pxp_write_irq_mask_reg(gt, pxp->handled_irr); + + pxp->current_events |= events; + schedule_work(&pxp->irq_work); +} diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h index 1841a9aa972d..ddcc3faa4ea3 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h @@ -6,8 +6,13 @@ #ifndef __INTEL_PXP_H__ #define __INTEL_PXP_H__ +#include <linux/workqueue.h> #include "intel_pxp_context.h" +#define PXP_IRQ_VECTOR_DISPLAY_PXP_STATE_TERMINATED BIT(1) +#define PXP_IRQ_VECTOR_DISPLAY_APP_TERM_PER_FW_REQ BIT(2) +#define PXP_IRQ_VECTOR_PXP_DISP_STATE_RESET_COMPLETE BIT(3) + enum pxp_session_types { SESSION_TYPE_TYPE0 = 0, SESSION_TYPE_TYPE1 = 1, @@ -25,13 +30,35 @@ enum pxp_protection_modes { }; struct intel_pxp { + struct work_struct irq_work; + u32 handled_irr; + u32 current_events; + struct pxp_context ctx; }; #ifdef CONFIG_DRM_I915_PXP +void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir); +int i915_pxp_teardown_required_callback(struct intel_pxp *pxp); +int i915_pxp_global_terminate_complete_callback(struct intel_pxp *pxp); + int intel_pxp_init(struct intel_pxp *pxp); void intel_pxp_uninit(struct intel_pxp *pxp); #else +static inline void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir) +{ +} + +static inline int i915_pxp_teardown_required_callback(struct intel_pxp *pxp) +{ + return 0; +} + +static inline int i915_pxp_global_terminate_complete_callback(struct intel_pxp *pxp) +{ + return 0; +} + static inline int intel_pxp_init(struct intel_pxp *pxp) { return 0; diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_context.c b/drivers/gpu/drm/i915/pxp/intel_pxp_context.c index 5ffaf55dc7df..d00f4e0b88ba 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_context.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_context.c @@ -14,6 +14,8 @@ void intel_pxp_ctx_init(struct pxp_context *ctx) { get_random_bytes(&ctx->id, sizeof(ctx->id)); + ctx->global_state_attacked = false; + mutex_init(&ctx->mutex); } diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_context.h b/drivers/gpu/drm/i915/pxp/intel_pxp_context.h index b1d0bc905320..3ba891f9ac26 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_context.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_context.h @@ -19,6 +19,7 @@ struct pxp_context { int id; + bool global_state_attacked; bool flag_display_hm_surface_keys; }; -- 2.17.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx