0001
0002
0003
0004
0005
0006 #include <linux/component.h>
0007
0008 #include <drm/i915_pxp_tee_interface.h>
0009 #include <drm/i915_component.h>
0010
0011 #include "i915_drv.h"
0012 #include "intel_pxp.h"
0013 #include "intel_pxp_session.h"
0014 #include "intel_pxp_tee.h"
0015 #include "intel_pxp_tee_interface.h"
0016
0017 static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
0018 {
0019 struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
0020
0021 return &to_gt(i915)->pxp;
0022 }
0023
0024 static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
0025 void *msg_in, u32 msg_in_size,
0026 void *msg_out, u32 msg_out_max_size,
0027 u32 *msg_out_rcv_size)
0028 {
0029 struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
0030 struct i915_pxp_component *pxp_component = pxp->pxp_component;
0031 int ret = 0;
0032
0033 mutex_lock(&pxp->tee_mutex);
0034
0035
0036
0037
0038
0039 if (!pxp_component) {
0040 ret = -ENODEV;
0041 goto unlock;
0042 }
0043
0044 ret = pxp_component->ops->send(pxp_component->tee_dev, msg_in, msg_in_size);
0045 if (ret) {
0046 drm_err(&i915->drm, "Failed to send PXP TEE message\n");
0047 goto unlock;
0048 }
0049
0050 ret = pxp_component->ops->recv(pxp_component->tee_dev, msg_out, msg_out_max_size);
0051 if (ret < 0) {
0052 drm_err(&i915->drm, "Failed to receive PXP TEE message\n");
0053 goto unlock;
0054 }
0055
0056 if (ret > msg_out_max_size) {
0057 drm_err(&i915->drm,
0058 "Failed to receive PXP TEE message due to unexpected output size\n");
0059 ret = -ENOSPC;
0060 goto unlock;
0061 }
0062
0063 if (msg_out_rcv_size)
0064 *msg_out_rcv_size = ret;
0065
0066 ret = 0;
0067 unlock:
0068 mutex_unlock(&pxp->tee_mutex);
0069 return ret;
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 static int i915_pxp_tee_component_bind(struct device *i915_kdev,
0083 struct device *tee_kdev, void *data)
0084 {
0085 struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
0086 struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
0087 intel_wakeref_t wakeref;
0088
0089 mutex_lock(&pxp->tee_mutex);
0090 pxp->pxp_component = data;
0091 pxp->pxp_component->tee_dev = tee_kdev;
0092 mutex_unlock(&pxp->tee_mutex);
0093
0094
0095 wakeref = intel_runtime_pm_get_if_in_use(&i915->runtime_pm);
0096 if (!wakeref)
0097 return 0;
0098
0099
0100 intel_pxp_init_hw(pxp);
0101
0102 intel_runtime_pm_put(&i915->runtime_pm, wakeref);
0103
0104 return 0;
0105 }
0106
0107 static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
0108 struct device *tee_kdev, void *data)
0109 {
0110 struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
0111 struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
0112 intel_wakeref_t wakeref;
0113
0114 with_intel_runtime_pm_if_in_use(&i915->runtime_pm, wakeref)
0115 intel_pxp_fini_hw(pxp);
0116
0117 mutex_lock(&pxp->tee_mutex);
0118 pxp->pxp_component = NULL;
0119 mutex_unlock(&pxp->tee_mutex);
0120 }
0121
0122 static const struct component_ops i915_pxp_tee_component_ops = {
0123 .bind = i915_pxp_tee_component_bind,
0124 .unbind = i915_pxp_tee_component_unbind,
0125 };
0126
0127 int intel_pxp_tee_component_init(struct intel_pxp *pxp)
0128 {
0129 int ret;
0130 struct intel_gt *gt = pxp_to_gt(pxp);
0131 struct drm_i915_private *i915 = gt->i915;
0132
0133 ret = component_add_typed(i915->drm.dev, &i915_pxp_tee_component_ops,
0134 I915_COMPONENT_PXP);
0135 if (ret < 0) {
0136 drm_err(&i915->drm, "Failed to add PXP component (%d)\n", ret);
0137 return ret;
0138 }
0139
0140 pxp->pxp_component_added = true;
0141
0142 return 0;
0143 }
0144
0145 void intel_pxp_tee_component_fini(struct intel_pxp *pxp)
0146 {
0147 struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
0148
0149 if (!pxp->pxp_component_added)
0150 return;
0151
0152 component_del(i915->drm.dev, &i915_pxp_tee_component_ops);
0153 pxp->pxp_component_added = false;
0154 }
0155
0156 int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
0157 int arb_session_id)
0158 {
0159 struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
0160 struct pxp_tee_create_arb_in msg_in = {0};
0161 struct pxp_tee_create_arb_out msg_out = {0};
0162 int ret;
0163
0164 msg_in.header.api_version = PXP_TEE_APIVER;
0165 msg_in.header.command_id = PXP_TEE_ARB_CMDID;
0166 msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
0167 msg_in.protection_mode = PXP_TEE_ARB_PROTECTION_MODE;
0168 msg_in.session_id = arb_session_id;
0169
0170 ret = intel_pxp_tee_io_message(pxp,
0171 &msg_in, sizeof(msg_in),
0172 &msg_out, sizeof(msg_out),
0173 NULL);
0174
0175 if (ret)
0176 drm_err(&i915->drm, "Failed to send tee msg ret=[%d]\n", ret);
0177
0178 return ret;
0179 }