Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-8-022e96815380@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Mukesh Ojha and committed by
Bjorn Andersson
4a7d6a78 928dbaaa

+49
+47
drivers/firmware/qcom/qcom_scm.c
··· 766 766 EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset); 767 767 768 768 /** 769 + * qcom_scm_pas_prepare_and_auth_reset() - Prepare, authenticate, and reset the 770 + * remote processor 771 + * 772 + * @ctx: Context saved during call to qcom_scm_pas_context_init() 773 + * 774 + * This function performs the necessary steps to prepare a PAS subsystem, 775 + * authenticate it using the provided metadata, and initiate a reset sequence. 776 + * 777 + * It should be used when Linux is in control setting up the IOMMU hardware 778 + * for remote subsystem during secure firmware loading processes. The preparation 779 + * step sets up a shmbridge over the firmware memory before TrustZone accesses the 780 + * firmware memory region for authentication. The authentication step verifies 781 + * the integrity and authenticity of the firmware or configuration using secure 782 + * metadata. Finally, the reset step ensures the subsystem starts in a clean and 783 + * sane state. 784 + * 785 + * Return: 0 on success, negative errno on failure. 786 + */ 787 + int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx) 788 + { 789 + u64 handle; 790 + int ret; 791 + 792 + /* 793 + * When Linux running @ EL1, Gunyah hypervisor running @ EL2 traps the 794 + * auth_and_reset call and create an shmbridge on the remote subsystem 795 + * memory region and then invokes a call to TrustZone to authenticate. 796 + */ 797 + if (!ctx->use_tzmem) 798 + return qcom_scm_pas_auth_and_reset(ctx->pas_id); 799 + 800 + /* 801 + * When Linux runs @ EL2 Linux must create the shmbridge itself and then 802 + * subsequently call TrustZone for authenticate and reset. 803 + */ 804 + ret = qcom_tzmem_shm_bridge_create(ctx->mem_phys, ctx->mem_size, &handle); 805 + if (ret) 806 + return ret; 807 + 808 + ret = qcom_scm_pas_auth_and_reset(ctx->pas_id); 809 + qcom_tzmem_shm_bridge_delete(handle); 810 + 811 + return ret; 812 + } 813 + EXPORT_SYMBOL_GPL(qcom_scm_pas_prepare_and_auth_reset); 814 + 815 + /** 769 816 * qcom_scm_pas_shutdown() - Shut down the remote processor 770 817 * @pas_id: peripheral authentication service id 771 818 *
+2
include/linux/firmware/qcom/qcom_scm.h
··· 74 74 void *ptr; 75 75 dma_addr_t phys; 76 76 ssize_t size; 77 + bool use_tzmem; 77 78 }; 78 79 79 80 struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, ··· 88 87 int qcom_scm_pas_auth_and_reset(u32 pas_id); 89 88 int qcom_scm_pas_shutdown(u32 pas_id); 90 89 bool qcom_scm_pas_supported(u32 pas_id); 90 + int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx); 91 91 92 92 int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); 93 93 int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);