// SPDX-License-Identifier: MIT
/*
 * Copyright(c) 2020 Intel Corporation.
 */
#include <linux/workqueue.h>

#include "gem/i915_gem_context.h"

#include "gt/intel_context.h"
#include "gt/intel_gt.h"

#include "i915_drv.h"

#include "intel_pxp.h"
#include "intel_pxp_gsccs.h"
#include "intel_pxp_irq.h"
#include "intel_pxp_regs.h"
#include "intel_pxp_session.h"
#include "intel_pxp_tee.h"
#include "intel_pxp_types.h"

/**
 * DOC: PXP
 *
 * PXP (Protected Xe Path) is a feature available in Gen12 and newer platforms.
 * It allows execution and flip to display of protected (i.e. encrypted)
 * objects. The SW support is enabled via the CONFIG_DRM_I915_PXP kconfig.
 *
 * Objects can opt-in to PXP encryption at creation time via the
 * I915_GEM_CREATE_EXT_PROTECTED_CONTENT create_ext flag. For objects to be
 * correctly protected they must be used in conjunction with a context created
 * with the I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. See the documentation
 * of those two uapi flags for details and restrictions.
 *
 * Protected objects are tied to a pxp session; currently we only support one
 * session, which i915 manages and whose index is available in the uapi
 * (I915_PROTECTED_CONTENT_DEFAULT_SESSION) for use in instructions targeting
 * protected objects.
 * The session is invalidated by the HW when certain events occur (e.g.
 * suspend/resume). When this happens, all the objects that were used with the
 * session are marked as invalid and all contexts marked as using protected
 * content are banned. Any further attempt at using them in an execbuf call is
 * rejected, while flips are converted to black frames.
 *
 * Some of the PXP setup operations are performed by the Management Engine,
 * which is handled by the mei driver; communication between i915 and mei is
 * performed via the mei_pxp component module.
 */

bool intel_pxp_is_supported(const struct intel_pxp *pxp)
{
	return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp;
}

bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
{
	return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->ce;
}

bool intel_pxp_is_active(const struct intel_pxp *pxp)
{
	return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->arb_is_valid;
}

static void kcr_pxp_set_status(const struct intel_pxp *pxp, bool enable)
{
	u32 val = enable ? _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES) :
		  _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES);

	intel_uncore_write(pxp->ctrl_gt->uncore, KCR_INIT(pxp->kcr_base), val);
}

static void kcr_pxp_enable(const struct intel_pxp *pxp)
{
	kcr_pxp_set_status(pxp, true);
}

static void kcr_pxp_disable(const struct intel_pxp *pxp)
{
	kcr_pxp_set_status(pxp, false);
}

static int create_vcs_context(struct intel_pxp *pxp)
{
	static struct lock_class_key pxp_lock;
	struct intel_gt *gt = pxp->ctrl_gt;
	struct intel_engine_cs *engine;
	struct intel_context *ce;
	int i;

	/*
	 * Find the first VCS engine present. We're guaranteed there is one
	 * if we're in this function due to the check in has_pxp
	 */
	for (i = 0, engine = NULL; !engine; i++)
		engine = gt->engine_class[VIDEO_DECODE_CLASS][i];

	GEM_BUG_ON(!engine || engine->class != VIDEO_DECODE_CLASS);

	ce = intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_4K,
						I915_GEM_HWS_PXP_ADDR,
						&pxp_lock, "pxp_context");
	if (IS_ERR(ce)) {
		drm_err(&gt->i915->drm, "failed to create VCS ctx for PXP\n");
		return PTR_ERR(ce);
	}

	pxp->ce = ce;

	return 0;
}

static void destroy_vcs_context(struct intel_pxp *pxp)
{
	if (pxp->ce)
		intel_engine_destroy_pinned_context(fetch_and_zero(&pxp->ce));
}

static void pxp_init_full(struct intel_pxp *pxp)
{
	struct intel_gt *gt = pxp->ctrl_gt;
	int ret;

	/*
	 * we'll use the completion to check if there is a termination pending,
	 * so we start it as completed and we reinit it when a termination
	 * is triggered.
	 */
	init_completion(&pxp->termination);
	complete_all(&pxp->termination);

	if (pxp->ctrl_gt->type == GT_MEDIA)
		pxp->kcr_base = MTL_KCR_BASE;
	else
		pxp->kcr_base = GEN12_KCR_BASE;

	intel_pxp_session_management_init(pxp);

	ret = create_vcs_context(pxp);
	if (ret)
		return;

	if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
		ret = intel_pxp_gsccs_init(pxp);
	else
		ret = intel_pxp_tee_component_init(pxp);
	if (ret)
		goto out_context;

	drm_info(&gt->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");

	return;

out_context:
	destroy_vcs_context(pxp);
}

static struct intel_gt *find_gt_for_required_teelink(struct drm_i915_private *i915)
{
	/*
	 * NOTE: Only certain platforms require PXP-tee-backend dependencies
	 * for HuC authentication. For now, its limited to DG2.
	 */
	if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC) &&
	    intel_huc_is_loaded_by_gsc(&to_gt(i915)->uc.huc) && intel_uc_uses_huc(&to_gt(i915)->uc))
		return to_gt(i915);

	return NULL;
}

static struct intel_gt *find_gt_for_required_protected_content(struct drm_i915_private *i915)
{
	if (!IS_ENABLED(CONFIG_DRM_I915_PXP) || !INTEL_INFO(i915)->has_pxp)
		return NULL;

	/*
	 * For MTL onwards, PXP-controller-GT needs to have a valid GSC engine
	 * on the media GT. NOTE: if we have a media-tile with a GSC-engine,
	 * the VDBOX is already present so skip that check. We also have to
	 * ensure the GSC and HUC firmware are coming online
	 */
	if (i915->media_gt && HAS_ENGINE(i915->media_gt, GSC0) &&
	    intel_uc_fw_is_loadable(&i915->media_gt->uc.gsc.fw) &&
	    intel_uc_fw_is_loadable(&i915->media_gt->uc.huc.fw))
		return i915->media_gt;

	/*
	 * Else we rely on mei-pxp module but only on legacy platforms
	 * prior to having separate media GTs and has a valid VDBOX.
	 */
	if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && !i915->media_gt && VDBOX_MASK(to_gt(i915)))
		return to_gt(i915);

	return NULL;
}

int intel_pxp_init(struct drm_i915_private *i915)
{
	struct intel_gt *gt;
	bool is_full_feature = false;

	if (intel_gt_is_wedged(to_gt(i915)))
		return -ENOTCONN;

	/*
	 * NOTE: Get the ctrl_gt before checking intel_pxp_is_supported since
	 * we still need it if PXP's backend tee transport is needed.
	 */
	gt = find_gt_for_required_protected_content(i915);
	if (gt)
		is_full_feature = true;
	else
		gt = find_gt_for_required_teelink(i915);

	if (!gt)
		return -ENODEV;

	/*
	 * At this point, we will either enable full featured PXP capabilities
	 * including session and object management, or we will init the backend tee
	 * channel for internal users such as HuC loading by GSC
	 */
	i915->pxp = kzalloc(sizeof(*i915->pxp), GFP_KERNEL);
	if (!i915->pxp)
		return -ENOMEM;

	/* init common info used by all feature-mode usages*/
	i915->pxp->ctrl_gt = gt;
	mutex_init(&i915->pxp->tee_mutex);

	/*
	 * If full PXP feature is not available but HuC is loaded by GSC on pre-MTL
	 * such as DG2, we can skip the init of the full PXP session/object management
	 * and just init the tee channel.
	 */
	if (is_full_feature)
		pxp_init_full(i915->pxp);
	else
		intel_pxp_tee_component_init(i915->pxp);

	return 0;
}

void intel_pxp_fini(struct drm_i915_private *i915)
{
	if (!i915->pxp)
		return;

	i915->pxp->arb_is_valid = false;

	if (HAS_ENGINE(i915->pxp->ctrl_gt, GSC0))
		intel_pxp_gsccs_fini(i915->pxp);
	else
		intel_pxp_tee_component_fini(i915->pxp);

	destroy_vcs_context(i915->pxp);

	kfree(i915->pxp);
	i915->pxp = NULL;
}

void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
{
	pxp->arb_is_valid = false;
	reinit_completion(&pxp->termination);
}

static void pxp_queue_termination(struct intel_pxp *pxp)
{
	struct intel_gt *gt = pxp->ctrl_gt;

	/*
	 * We want to get the same effect as if we received a termination
	 * interrupt, so just pretend that we did.
	 */
	spin_lock_irq(gt->irq_lock);
	intel_pxp_mark_termination_in_progress(pxp);
	pxp->session_events |= PXP_TERMINATION_REQUEST;
	queue_work(system_unbound_wq, &pxp->session_work);
	spin_unlock_irq(gt->irq_lock);
}

static bool pxp_component_bound(struct intel_pxp *pxp)
{
	bool bound = false;

	mutex_lock(&pxp->tee_mutex);
	if (pxp->pxp_component)
		bound = true;
	mutex_unlock(&pxp->tee_mutex);

	return bound;
}

int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp)
{
	if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
		return GSCFW_MAX_ROUND_TRIP_LATENCY_MS;
	else
		return 250;
}

static int __pxp_global_teardown_final(struct intel_pxp *pxp)
{
	int timeout;

	if (!pxp->arb_is_valid)
		return 0;

	drm_dbg(&pxp->ctrl_gt->i915->drm, "PXP: teardown for suspend/fini");
	/*
	 * To ensure synchronous and coherent session teardown completion
	 * in response to suspend or shutdown triggers, don't use a worker.
	 */
	intel_pxp_mark_termination_in_progress(pxp);
	intel_pxp_terminate(pxp, false);

	timeout = intel_pxp_get_backend_timeout_ms(pxp);

	if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout)))
		return -ETIMEDOUT;

	return 0;
}

static int __pxp_global_teardown_restart(struct intel_pxp *pxp)
{
	int timeout;

	if (pxp->arb_is_valid)
		return 0;

	drm_dbg(&pxp->ctrl_gt->i915->drm, "PXP: teardown for restart");
	/*
	 * The arb-session is currently inactive and we are doing a reset and restart
	 * due to a runtime event. Use the worker that was designed for this.
	 */
	pxp_queue_termination(pxp);

	timeout = intel_pxp_get_backend_timeout_ms(pxp);

	if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout))) {
		drm_dbg(&pxp->ctrl_gt->i915->drm, "PXP: restart backend timed out (%d ms)",
			timeout);
		return -ETIMEDOUT;
	}

	return 0;
}

void intel_pxp_end(struct intel_pxp *pxp)
{
	struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
	intel_wakeref_t wakeref;

	if (!intel_pxp_is_enabled(pxp))
		return;

	wakeref = intel_runtime_pm_get(&i915->runtime_pm);

	mutex_lock(&pxp->arb_mutex);

	if (__pxp_global_teardown_final(pxp))
		drm_dbg(&i915->drm, "PXP end timed out\n");

	mutex_unlock(&pxp->arb_mutex);

	intel_pxp_fini_hw(pxp);
	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
}

static bool pxp_required_fw_failed(struct intel_pxp *pxp)
{
	if (__intel_uc_fw_status(&pxp->ctrl_gt->uc.huc.fw) == INTEL_UC_FIRMWARE_LOAD_FAIL)
		return true;
	if (HAS_ENGINE(pxp->ctrl_gt, GSC0) &&
	    __intel_uc_fw_status(&pxp->ctrl_gt->uc.gsc.fw) == INTEL_UC_FIRMWARE_LOAD_FAIL)
		return true;

	return false;
}

static bool pxp_fw_dependencies_completed(struct intel_pxp *pxp)
{
	if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
		return intel_pxp_gsccs_is_ready_for_sessions(pxp);

	return pxp_component_bound(pxp);
}

/*
 * this helper is used by both intel_pxp_start and by
 * the GET_PARAM IOCTL that user space calls. Thus, the
 * return values here should match the UAPI spec.
 */
int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int timeout_ms)
{
	if (!intel_pxp_is_enabled(pxp))
		return -ENODEV;

	if (pxp_required_fw_failed(pxp))
		return -ENODEV;

	if (pxp->platform_cfg_is_bad)
		return -ENODEV;

	if (timeout_ms) {
		if (wait_for(pxp_fw_dependencies_completed(pxp), timeout_ms))
			return 2;
	} else if (!pxp_fw_dependencies_completed(pxp)) {
		return 2;
	}
	return 1;
}

/*
 * the arb session is restarted from the irq work when we receive the
 * termination completion interrupt
 */
#define PXP_READINESS_TIMEOUT 250

int intel_pxp_start(struct intel_pxp *pxp)
{
	int ret = 0;

	ret = intel_pxp_get_readiness_status(pxp, PXP_READINESS_TIMEOUT);
	if (ret < 0) {
		drm_dbg(&pxp->ctrl_gt->i915->drm, "PXP: tried but not-avail (%d)", ret);
		return ret;
	} else if (ret > 1) {
		return -EIO; /* per UAPI spec, user may retry later */
	}

	mutex_lock(&pxp->arb_mutex);

	ret = __pxp_global_teardown_restart(pxp);
	if (ret)
		goto unlock;

	/* make sure the compiler doesn't optimize the double access */
	barrier();

	if (!pxp->arb_is_valid)
		ret = -EIO;

unlock:
	mutex_unlock(&pxp->arb_mutex);
	return ret;
}

void intel_pxp_init_hw(struct intel_pxp *pxp)
{
	kcr_pxp_enable(pxp);
	intel_pxp_irq_enable(pxp);
}

void intel_pxp_fini_hw(struct intel_pxp *pxp)
{
	kcr_pxp_disable(pxp);
	intel_pxp_irq_disable(pxp);
}

int intel_pxp_key_check(struct intel_pxp *pxp,
			struct drm_i915_gem_object *obj,
			bool assign)
{
	if (!intel_pxp_is_active(pxp))
		return -ENODEV;

	if (!i915_gem_object_is_protected(obj))
		return -EINVAL;

	GEM_BUG_ON(!pxp->key_instance);

	/*
	 * If this is the first time we're using this object, it's not
	 * encrypted yet; it will be encrypted with the current key, so mark it
	 * as such. If the object is already encrypted, check instead if the
	 * used key is still valid.
	 */
	if (!obj->pxp_key_instance && assign)
		obj->pxp_key_instance = pxp->key_instance;

	if (obj->pxp_key_instance != pxp->key_instance)
		return -ENOEXEC;

	return 0;
}

void intel_pxp_invalidate(struct intel_pxp *pxp)
{
	struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
	struct i915_gem_context *ctx, *cn;

	/* ban all contexts marked as protected */
	spin_lock_irq(&i915->gem.contexts.lock);
	list_for_each_entry_safe(ctx, cn, &i915->gem.contexts.list, link) {
		struct i915_gem_engines_iter it;
		struct intel_context *ce;

		if (!kref_get_unless_zero(&ctx->ref))
			continue;

		if (likely(!i915_gem_context_uses_protected_content(ctx))) {
			i915_gem_context_put(ctx);
			continue;
		}

		spin_unlock_irq(&i915->gem.contexts.lock);

		/*
		 * By the time we get here we are either going to suspend with
		 * quiesced execution or the HW keys are already long gone and
		 * in this case it is worthless to attempt to close the context
		 * and wait for its execution. It will hang the GPU if it has
		 * not already. So, as a fast mitigation, we can ban the
		 * context as quick as we can. That might race with the
		 * execbuffer, but currently this is the best that can be done.
		 */
		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it)
			intel_context_ban(ce, NULL);
		i915_gem_context_unlock_engines(ctx);

		/*
		 * The context has been banned, no need to keep the wakeref.
		 * This is safe from races because the only other place this
		 * is touched is context_release and we're holding a ctx ref
		 */
		if (ctx->pxp_wakeref) {
			intel_runtime_pm_put(&i915->runtime_pm,
					     ctx->pxp_wakeref);
			ctx->pxp_wakeref = 0;
		}

		spin_lock_irq(&i915->gem.contexts.lock);
		list_safe_reset_next(ctx, cn, link);
		i915_gem_context_put(ctx);
	}
	spin_unlock_irq(&i915->gem.contexts.lock);
}
