Commit 4a7d6a78 authored by Mukesh Ojha's avatar Mukesh Ojha Committed by Bjorn Andersson
Browse files

firmware: qcom_scm: Add a prep version of auth_and_reset function



For memory passed to TrustZone (TZ), it must either be part of a pool
registered with TZ or explicitly registered via SHMbridge SMC calls.
When Gunyah hypervisor is present, PAS SMC calls from Linux running at
EL1 are trapped by Gunyah running @ EL2, which handles SHMbridge
creation for both metadata and remoteproc carveout memory before
invoking the calls to TZ.

On SoCs running with a non-Gunyah-based hypervisor, Linux must take
responsibility for creating the SHM bridge before invoking PAS SMC
calls. For the auth_and_reset() call, the remoteproc carveout memory
must first be registered with TZ via a SHMbridge SMC call and once
authentication and reset are complete, the SHMbridge memory can be
deregistered.

Introduce qcom_scm_pas_prepare_and_auth_reset(), which sets up the SHM
bridge over the remoteproc carveout memory when Linux operates at EL2.
This behavior is indicated by a new field added to the PAS context data
structure. The function then invokes the auth_and_reset SMC call.

Signed-off-by: default avatarMukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-8-022e96815380@oss.qualcomm.com


Signed-off-by: default avatarBjorn Andersson <andersson@kernel.org>
parent 928dbaaa
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -765,6 +765,53 @@ int qcom_scm_pas_auth_and_reset(u32 pas_id)
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset);

/**
 * qcom_scm_pas_prepare_and_auth_reset() - Prepare, authenticate, and reset the
 *					   remote processor
 *
 * @ctx:	Context saved during call to qcom_scm_pas_context_init()
 *
 * This function performs the necessary steps to prepare a PAS subsystem,
 * authenticate it using the provided metadata, and initiate a reset sequence.
 *
 * It should be used when Linux is in control setting up the IOMMU hardware
 * for remote subsystem during secure firmware loading processes. The preparation
 * step sets up a shmbridge over the firmware memory before TrustZone accesses the
 * firmware memory region for authentication. The authentication step verifies
 * the integrity and authenticity of the firmware or configuration using secure
 * metadata. Finally, the reset step ensures the subsystem starts in a clean and
 * sane state.
 *
 * Return: 0 on success, negative errno on failure.
 */
int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx)
{
	u64 handle;
	int ret;

	/*
	 * When Linux running @ EL1, Gunyah hypervisor running @ EL2 traps the
	 * auth_and_reset call and create an shmbridge on the remote subsystem
	 * memory region and then invokes a call to TrustZone to authenticate.
	 */
	if (!ctx->use_tzmem)
		return qcom_scm_pas_auth_and_reset(ctx->pas_id);

	/*
	 * When Linux runs @ EL2 Linux must create the shmbridge itself and then
	 * subsequently call TrustZone for authenticate and reset.
	 */
	ret = qcom_tzmem_shm_bridge_create(ctx->mem_phys, ctx->mem_size, &handle);
	if (ret)
		return ret;

	ret = qcom_scm_pas_auth_and_reset(ctx->pas_id);
	qcom_tzmem_shm_bridge_delete(handle);

	return ret;
}
EXPORT_SYMBOL_GPL(qcom_scm_pas_prepare_and_auth_reset);

/**
 * qcom_scm_pas_shutdown() - Shut down the remote processor
 * @pas_id:	peripheral authentication service id
+2 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ struct qcom_scm_pas_context {
	void *ptr;
	dma_addr_t phys;
	ssize_t size;
	bool use_tzmem;
};

struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
@@ -87,6 +88,7 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
int qcom_scm_pas_auth_and_reset(u32 pas_id);
int qcom_scm_pas_shutdown(u32 pas_id);
bool qcom_scm_pas_supported(u32 pas_id);
int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx);

int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);