cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel_pxp_tee.c (4665B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright(c) 2020 Intel Corporation.
      4 */
      5
      6#include <linux/component.h>
      7
      8#include <drm/i915_pxp_tee_interface.h>
      9#include <drm/i915_component.h>
     10
     11#include "i915_drv.h"
     12#include "intel_pxp.h"
     13#include "intel_pxp_session.h"
     14#include "intel_pxp_tee.h"
     15#include "intel_pxp_tee_interface.h"
     16
     17static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
     18{
     19	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
     20
     21	return &to_gt(i915)->pxp;
     22}
     23
     24static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
     25				    void *msg_in, u32 msg_in_size,
     26				    void *msg_out, u32 msg_out_max_size,
     27				    u32 *msg_out_rcv_size)
     28{
     29	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
     30	struct i915_pxp_component *pxp_component = pxp->pxp_component;
     31	int ret = 0;
     32
     33	mutex_lock(&pxp->tee_mutex);
     34
     35	/*
     36	 * The binding of the component is asynchronous from i915 probe, so we
     37	 * can't be sure it has happened.
     38	 */
     39	if (!pxp_component) {
     40		ret = -ENODEV;
     41		goto unlock;
     42	}
     43
     44	ret = pxp_component->ops->send(pxp_component->tee_dev, msg_in, msg_in_size);
     45	if (ret) {
     46		drm_err(&i915->drm, "Failed to send PXP TEE message\n");
     47		goto unlock;
     48	}
     49
     50	ret = pxp_component->ops->recv(pxp_component->tee_dev, msg_out, msg_out_max_size);
     51	if (ret < 0) {
     52		drm_err(&i915->drm, "Failed to receive PXP TEE message\n");
     53		goto unlock;
     54	}
     55
     56	if (ret > msg_out_max_size) {
     57		drm_err(&i915->drm,
     58			"Failed to receive PXP TEE message due to unexpected output size\n");
     59		ret = -ENOSPC;
     60		goto unlock;
     61	}
     62
     63	if (msg_out_rcv_size)
     64		*msg_out_rcv_size = ret;
     65
     66	ret = 0;
     67unlock:
     68	mutex_unlock(&pxp->tee_mutex);
     69	return ret;
     70}
     71
     72/**
     73 * i915_pxp_tee_component_bind - bind function to pass the function pointers to pxp_tee
     74 * @i915_kdev: pointer to i915 kernel device
     75 * @tee_kdev: pointer to tee kernel device
     76 * @data: pointer to pxp_tee_master containing the function pointers
     77 *
     78 * This bind function is called during the system boot or resume from system sleep.
     79 *
     80 * Return: return 0 if successful.
     81 */
     82static int i915_pxp_tee_component_bind(struct device *i915_kdev,
     83				       struct device *tee_kdev, void *data)
     84{
     85	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
     86	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
     87	intel_wakeref_t wakeref;
     88
     89	mutex_lock(&pxp->tee_mutex);
     90	pxp->pxp_component = data;
     91	pxp->pxp_component->tee_dev = tee_kdev;
     92	mutex_unlock(&pxp->tee_mutex);
     93
     94	/* if we are suspended, the HW will be re-initialized on resume */
     95	wakeref = intel_runtime_pm_get_if_in_use(&i915->runtime_pm);
     96	if (!wakeref)
     97		return 0;
     98
     99	/* the component is required to fully start the PXP HW */
    100	intel_pxp_init_hw(pxp);
    101
    102	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
    103
    104	return 0;
    105}
    106
    107static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
    108					  struct device *tee_kdev, void *data)
    109{
    110	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
    111	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
    112	intel_wakeref_t wakeref;
    113
    114	with_intel_runtime_pm_if_in_use(&i915->runtime_pm, wakeref)
    115		intel_pxp_fini_hw(pxp);
    116
    117	mutex_lock(&pxp->tee_mutex);
    118	pxp->pxp_component = NULL;
    119	mutex_unlock(&pxp->tee_mutex);
    120}
    121
    122static const struct component_ops i915_pxp_tee_component_ops = {
    123	.bind   = i915_pxp_tee_component_bind,
    124	.unbind = i915_pxp_tee_component_unbind,
    125};
    126
    127int intel_pxp_tee_component_init(struct intel_pxp *pxp)
    128{
    129	int ret;
    130	struct intel_gt *gt = pxp_to_gt(pxp);
    131	struct drm_i915_private *i915 = gt->i915;
    132
    133	ret = component_add_typed(i915->drm.dev, &i915_pxp_tee_component_ops,
    134				  I915_COMPONENT_PXP);
    135	if (ret < 0) {
    136		drm_err(&i915->drm, "Failed to add PXP component (%d)\n", ret);
    137		return ret;
    138	}
    139
    140	pxp->pxp_component_added = true;
    141
    142	return 0;
    143}
    144
    145void intel_pxp_tee_component_fini(struct intel_pxp *pxp)
    146{
    147	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
    148
    149	if (!pxp->pxp_component_added)
    150		return;
    151
    152	component_del(i915->drm.dev, &i915_pxp_tee_component_ops);
    153	pxp->pxp_component_added = false;
    154}
    155
    156int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
    157					 int arb_session_id)
    158{
    159	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
    160	struct pxp_tee_create_arb_in msg_in = {0};
    161	struct pxp_tee_create_arb_out msg_out = {0};
    162	int ret;
    163
    164	msg_in.header.api_version = PXP_TEE_APIVER;
    165	msg_in.header.command_id = PXP_TEE_ARB_CMDID;
    166	msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
    167	msg_in.protection_mode = PXP_TEE_ARB_PROTECTION_MODE;
    168	msg_in.session_id = arb_session_id;
    169
    170	ret = intel_pxp_tee_io_message(pxp,
    171				       &msg_in, sizeof(msg_in),
    172				       &msg_out, sizeof(msg_out),
    173				       NULL);
    174
    175	if (ret)
    176		drm_err(&i915->drm, "Failed to send tee msg ret=[%d]\n", ret);
    177
    178	return ret;
    179}