From: Sumit Garg <sumit.garg@kernel.org>
To: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Cc: linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org,
dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org,
linux-media@vger.kernel.org, netdev@vger.kernel.org,
linux-wireless@vger.kernel.org, ath12k@lists.infradead.org,
linux-remoteproc@vger.kernel.org, andersson@kernel.org,
konradybcio@kernel.org, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, robin.clark@oss.qualcomm.com,
sean@poorly.run, akhilpo@oss.qualcomm.com, lumag@kernel.org,
abhinav.kumar@linux.dev, jesszhan0024@gmail.com,
marijn.suijten@somainline.org, airlied@gmail.com,
simona@ffwll.ch, vikash.garodia@oss.qualcomm.com,
dikshita.agarwal@oss.qualcomm.com, bod@kernel.org,
mchehab@kernel.org, elder@kernel.org, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, jjohnson@kernel.org,
mathieu.poirier@linaro.org, trilokkumar.soni@oss.qualcomm.com,
pavan.kondeti@oss.qualcomm.com, jorge.ramirez@oss.qualcomm.com,
tonyh@qti.qualcomm.com, vignesh.viswanathan@oss.qualcomm.com,
srinivas.kandagatla@oss.qualcomm.com,
amirreza.zarrabi@oss.qualcomm.com, jens.wiklander@linaro.org,
op-tee@lists.trustedfirmware.org, apurupa@qti.qualcomm.com,
skare@qti.qualcomm.com, linux-kernel@vger.kernel.org,
Sumit Garg <sumit.garg@oss.qualcomm.com>
Subject: Re: [PATCH v2 04/15] firmware: qcom: Add a PAS TEE service
Date: Mon, 23 Mar 2026 19:08:52 +0530 [thread overview]
Message-ID: <acFCbLZNOvhrm0Wh@sumit-xelite> (raw)
In-Reply-To: <20260313110747.v5bx2snpbtyja3ur@hu-mojha-hyd.qualcomm.com>
On Fri, Mar 13, 2026 at 04:37:47PM +0530, Mukesh Ojha wrote:
> On Thu, Mar 12, 2026 at 11:57:45AM +0530, Sumit Garg wrote:
> > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> >
> > Add support for Peripheral Authentication Service (PAS) driver based
> > on TEE bus with OP-TEE providing the backend PAS service implementation.
> >
> > The TEE PAS service ABI is designed to be extensible with additional API
> > as PTA_QCOM_PAS_CAPABILITIES. This allows to accommodate any future
> > extensions of the PAS service needed while still maintaining backwards
> > compatibility.
> >
> > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/Kconfig | 9 +
> > drivers/firmware/qcom/Makefile | 1 +
> > drivers/firmware/qcom/qcom_pas_tee.c | 477 +++++++++++++++++++++++++++
> > 3 files changed, 487 insertions(+)
> > create mode 100644 drivers/firmware/qcom/qcom_pas_tee.c
> >
> > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > index 9a12ae2b639d..fff47abdaafd 100644
> > --- a/drivers/firmware/qcom/Kconfig
> > +++ b/drivers/firmware/qcom/Kconfig
> > @@ -14,6 +14,15 @@ config QCOM_PAS
> > backends plugged in whether it's an SCM implementation or a proper
> > TEE bus based PAS service implementation.
> >
> > +config QCOM_PAS_TEE
> > + tristate
> > + select QCOM_PAS
> > + depends on TEE
> > + depends on !CPU_BIG_ENDIAN
> > + help
> > + Enable the generic Peripheral Authentication Service (PAS) provided
> > + by the firmware TEE implementation as the backend.
> > +
> > config QCOM_SCM
> > select QCOM_PAS
> > select QCOM_TZMEM
> > diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
> > index dc5ab45f906a..48801d18f37b 100644
> > --- a/drivers/firmware/qcom/Makefile
> > +++ b/drivers/firmware/qcom/Makefile
> > @@ -9,3 +9,4 @@ obj-$(CONFIG_QCOM_TZMEM) += qcom_tzmem.o
> > obj-$(CONFIG_QCOM_QSEECOM) += qcom_qseecom.o
> > obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
> > obj-$(CONFIG_QCOM_PAS) += qcom_pas.o
> > +obj-$(CONFIG_QCOM_PAS_TEE) += qcom_pas_tee.o
> > diff --git a/drivers/firmware/qcom/qcom_pas_tee.c b/drivers/firmware/qcom/qcom_pas_tee.c
> > new file mode 100644
> > index 000000000000..7db9fd736369
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_pas_tee.c
> > @@ -0,0 +1,477 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/firmware/qcom/qcom_pas.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/slab.h>
> > +#include <linux/tee_drv.h>
> > +#include <linux/uuid.h>
> > +
> > +#include "qcom_pas.h"
> > +
> > +/*
> > + * Peripheral Authentication Service (PAS) supported.
> > + *
> > + * [in] params[0].value.a: Unique 32bit remote processor identifier
> > + */
> > +#define PTA_QCOM_PAS_IS_SUPPORTED 1
> > +
> > +/*
> > + * PAS capabilities.
> > + *
> > + * [in] params[0].value.a: Unique 32bit remote processor identifier
> > + * [out] params[1].value.a: PAS capability flags
> > + */
> > +#define PTA_QCOM_PAS_CAPABILITIES 2
> > +
> > +/*
> > + * PAS image initialization.
> > + *
> > + * [in] params[0].value.a: Unique 32bit remote processor identifier
> > + * [in] params[1].memref: Loadable firmware metadata
> > + */
> > +#define PTA_QCOM_PAS_INIT_IMAGE 3
> > +
> > +/*
> > + * PAS memory setup.
> > + *
> > + * [in] params[0].value.a: Unique 32bit remote processor identifier
> > + * [in] params[0].value.b: Relocatable firmware size
> > + * [in] params[1].value.a: 32bit LSB relocatable firmware memory address
> > + * [in] params[1].value.b: 32bit MSB relocatable firmware memory address
> > + */
> > +#define PTA_QCOM_PAS_MEM_SETUP 4
> > +
> > +/*
> > + * PAS get resource table.
> > + *
> > + * [in] params[0].value.a: Unique 32bit remote processor identifier
> > + * [inout] params[1].memref: Resource table config
> > + */
> > +#define PTA_QCOM_PAS_GET_RESOURCE_TABLE 5
> > +
> > +/*
> > + * PAS image authentication and co-processor reset.
> > + *
> > + * [in] params[0].value.a: Unique 32bit remote processor identifier
> > + * [in] params[0].value.b: Firmware size
> > + * [in] params[1].value.a: 32bit LSB firmware memory address
> > + * [in] params[1].value.b: 32bit MSB firmware memory address
> > + * [in] params[2].memref: Optional fw memory space shared/lent
> > + */
> > +#define PTA_QCOM_PAS_AUTH_AND_RESET 6
> > +
> > +/*
> > + * PAS co-processor set suspend/resume state.
> > + *
> > + * [in] params[0].value.a: Unique 32bit remote processor identifier
> > + * [in] params[0].value.b: Co-processor state identifier
> > + */
> > +#define PTA_QCOM_PAS_SET_REMOTE_STATE 7
> > +
> > +/*
> > + * PAS co-processor shutdown.
> > + *
> > + * [in] params[0].value.a: Unique 32bit remote processor identifier
> > + */
> > +#define PTA_QCOM_PAS_SHUTDOWN 8
> > +
> > +#define TEE_NUM_PARAMS 4
> > +
> > +/**
> > + * struct qcom_pas_tee_private - PAS service private data
> > + * @dev: PAS service device.
> > + * @ctx: TEE context handler.
> > + * @session_id: PAS TA session identifier.
> > + */
> > +struct qcom_pas_tee_private {
> > + struct device *dev;
> > + struct tee_context *ctx;
> > + u32 session_id;
> > +};
> > +
> > +static bool qcom_pas_tee_supported(struct device *dev, u32 pas_id)
> > +{
> > + struct qcom_pas_tee_private *data = dev_get_drvdata(dev);
> > + struct tee_ioctl_invoke_arg inv_arg = {
> > + .func = PTA_QCOM_PAS_IS_SUPPORTED,
> > + .session = data->session_id,
> > + .num_params = TEE_NUM_PARAMS
> > + };
> > + struct tee_param param[4] = {
> > + [0] = {
> > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> > + .u.value.a = pas_id
> > + }
> > + };
> > + int ret;
> > +
> > + ret = tee_client_invoke_func(data->ctx, &inv_arg, param);
> > + if (ret < 0 || inv_arg.ret != 0) {
> > + dev_err(dev, "PAS not supported, pas_id: %d, err: %x\n",
> > + pas_id, inv_arg.ret);
> > + return false;
> > + }
> > +
> > + return true;
> > +}
> > +
> > +static int qcom_pas_tee_init_image(struct device *dev, u32 pas_id,
> > + const void *metadata, size_t size,
> > + struct qcom_pas_context *ctx)
> > +{
> > + struct qcom_pas_tee_private *data = dev_get_drvdata(dev);
> > + struct tee_ioctl_invoke_arg inv_arg = {
> > + .func = PTA_QCOM_PAS_INIT_IMAGE,
> > + .session = data->session_id,
> > + .num_params = TEE_NUM_PARAMS
> > + };
> > + struct tee_param param[4] = {
> > + [0] = {
> > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> > + .u.value.a = pas_id
> > + },
> > + [1] = {
> > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
> > + }
> > + };
> > + struct tee_shm *mdata_shm;
> > + u8 *mdata_buf = NULL;
> > + int ret;
> > +
> > + mdata_shm = tee_shm_alloc_kernel_buf(data->ctx, size);
> > + if (IS_ERR(mdata_shm)) {
> > + dev_err(dev, "mdata_shm allocation failed\n");
> > + return PTR_ERR(mdata_shm);
> > + }
> > +
> > + mdata_buf = tee_shm_get_va(mdata_shm, 0);
> > + if (IS_ERR(mdata_buf)) {
> > + dev_err(dev, "mdata_buf get VA failed\n");
> > + tee_shm_free(mdata_shm);
> > + return PTR_ERR(mdata_buf);
> > + }
> > + memcpy(mdata_buf, metadata, size);
> > +
> > + param[1].u.memref.shm = mdata_shm;
> > + param[1].u.memref.size = size;
> > +
> > + ret = tee_client_invoke_func(data->ctx, &inv_arg, param);
> > + if (ret < 0 || inv_arg.ret != 0) {
> > + dev_err(dev, "PAS init image failed, pas_id: %d, err: %x\n",
> > + pas_id, inv_arg.ret);
> > + tee_shm_free(mdata_shm);
> > + return -EINVAL;
> > + }
> > + ctx->ptr = (void *)mdata_shm;
> > +
> > + return 0;
> > +}
> > +
> > +static int qcom_pas_tee_mem_setup(struct device *dev, u32 pas_id,
> > + phys_addr_t addr, phys_addr_t size)
> > +{
> > + struct qcom_pas_tee_private *data = dev_get_drvdata(dev);
> > + struct tee_ioctl_invoke_arg inv_arg = {
> > + .func = PTA_QCOM_PAS_MEM_SETUP,
> > + .session = data->session_id,
> > + .num_params = TEE_NUM_PARAMS
> > + };
> > + struct tee_param param[4] = {
> > + [0] = {
> > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> > + .u.value.a = pas_id,
> > + .u.value.b = size,
> > + },
> > + [1] = {
> > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> > + .u.value.a = lower_32_bits(addr),
> > + .u.value.b = upper_32_bits(addr),
> > + }
> > + };
> > + int ret;
> > +
> > + ret = tee_client_invoke_func(data->ctx, &inv_arg, param);
> > + if (ret < 0 || inv_arg.ret != 0) {
> > + dev_err(dev, "PAS mem setup failed, pas_id: %d, err: %x\n",
> > + pas_id, inv_arg.ret);
> > + return -EINVAL;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +DEFINE_FREE(shm_free, struct tee_shm *, tee_shm_free(_T))
> > +
> > +static void *qcom_pas_tee_get_rsc_table(struct device *dev,
> > + struct qcom_pas_context *ctx,
> > + void *input_rt, size_t input_rt_size,
> > + size_t *output_rt_size)
> > +{
> > + struct qcom_pas_tee_private *data = dev_get_drvdata(dev);
> > + struct tee_ioctl_invoke_arg inv_arg = {
> > + .func = PTA_QCOM_PAS_GET_RESOURCE_TABLE,
> > + .session = data->session_id,
> > + .num_params = TEE_NUM_PARAMS
> > + };
> > + struct tee_param param[4] = {
> > + [0] = {
> > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
> > + .u.value.a = ctx->pas_id,
> > + },
> > + [1] = {
> > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
> > + .u.memref.size = input_rt_size,
> > + }
> > + };
> > + void *rt_buf = NULL;
> > + int ret;
> > +
> > + ret = tee_client_invoke_func(data->ctx, &inv_arg, param);
>
> What is the purpose of this function ? looks like, this is for, how
> much Linux need to allocate for output buffer ?
That's right.
>
> > + if (ret < 0 || inv_arg.ret != 0) {
> > + dev_err(dev, "PAS get RT failed, pas_id: %d, err: %x\n",
> > + ctx->pas_id, inv_arg.ret);
> > + return ERR_PTR(-EINVAL);
> > + }
> > +
> > + if (param[1].u.memref.size) {
> > + struct tee_shm *rt_shm __free(shm_free) =
> > + tee_shm_alloc_kernel_buf(data->ctx,
> > + param[1].u.memref.size);
> > + void *rt_shm_va;
> > +
> > + if (IS_ERR(rt_shm)) {
> > + dev_err(dev, "rt_shm allocation failed\n");
> > + return rt_shm;
> > + }
> > +
> > + rt_shm_va = tee_shm_get_va(rt_shm, 0);
> > + if (IS_ERR_OR_NULL(rt_shm_va)) {
> > + dev_err(dev, "rt_shm get VA failed\n");
> > + return ERR_PTR(-EINVAL);
> > + }
> > + memcpy(rt_shm_va, input_rt, input_rt_size);
> > +
> > + param[1].u.memref.shm = rt_shm;
>
> Here, you are passing only one buffer for both input and output ?
>
> Like, you are allocating of buffer of size returned from qtee which I
s/qtee/optee/
> assume includes both input + output rt size and copying the input_rt
> and calling invoke and in return you will get combine table in return ?
That's right.
>
> > + ret = tee_client_invoke_func(data->ctx, &inv_arg, param);
> > + if (ret < 0 || inv_arg.ret != 0) {
> > + dev_err(dev, "PAS get RT failed, pas_id: %d, err: %x\n",
> > + ctx->pas_id, inv_arg.ret);
> > + return ERR_PTR(-EINVAL);
> > + }
> > +
> > + if (param[1].u.memref.size) {
> > + *output_rt_size = param[1].u.memref.size;
> > + rt_buf = kmalloc(param[1].u.memref.size, GFP_KERNEL);
> > + if (!rt_buf)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + memcpy(rt_buf, rt_shm_va, *output_rt_size);
>
> rt_buf = kmemdup(rt_shm_va, *output_rt_size, GFP_KERNEL);
>
> https://lore.kernel.org/lkml/20260310140255.2520230-1-mukesh.ojha@oss.qualcomm.com/
>
Sure, I will use that instead.
-Sumit
next prev parent reply other threads:[~2026-03-23 13:39 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-12 6:27 [PATCH v2 00/15] firmware: qcom: Add OP-TEE PAS service support Sumit Garg
2026-03-12 6:27 ` [PATCH v2 01/15] arm64: dts: qcom: kodiak: Add EL2 overlay Sumit Garg
2026-03-13 6:04 ` Mukesh Ojha
2026-03-23 12:35 ` Sumit Garg
2026-03-12 6:27 ` [PATCH v2 02/15] firmware: qcom: Add a generic PAS service Sumit Garg
2026-03-13 7:24 ` Mukesh Ojha
2026-03-13 7:31 ` Mukesh Ojha
2026-03-23 12:55 ` Sumit Garg
2026-03-23 12:50 ` Sumit Garg
2026-03-13 7:59 ` Mukesh Ojha
2026-03-23 13:01 ` Sumit Garg
2026-03-15 16:33 ` Harshal Dev
2026-03-23 13:12 ` Sumit Garg
2026-03-16 7:51 ` Krzysztof Kozlowski
2026-03-16 23:02 ` Trilok Soni
2026-03-23 13:22 ` Sumit Garg
2026-03-23 14:19 ` Krzysztof Kozlowski
2026-03-23 14:26 ` Konrad Dybcio
2026-03-12 6:27 ` [PATCH v2 03/15] firmware: qcom_scm: Migrate to " Sumit Garg
2026-03-13 7:56 ` Mukesh Ojha
2026-03-23 13:33 ` Sumit Garg
2026-03-12 6:27 ` [PATCH v2 04/15] firmware: qcom: Add a PAS TEE service Sumit Garg
2026-03-13 11:07 ` Mukesh Ojha
2026-03-23 13:38 ` Sumit Garg [this message]
2026-03-12 6:27 ` [PATCH v2 05/15] remoteproc: qcom_q6v5_pas: Switch over to generic PAS TZ APIs Sumit Garg
2026-03-12 6:27 ` [PATCH v2 06/15] remoteproc: qcom_q6v5_mss: Switch " Sumit Garg
2026-03-12 6:27 ` [PATCH v2 07/15] soc: qcom: mdtloader: " Sumit Garg
2026-03-12 6:27 ` [PATCH v2 08/15] remoteproc: qcom_wcnss: " Sumit Garg
2026-03-12 6:27 ` [PATCH v2 09/15] remoteproc: qcom: Select QCOM_PAS_TEE service backend Sumit Garg
2026-03-12 6:27 ` [PATCH v2 10/15] drm/msm: Switch to generic PAS TZ APIs Sumit Garg
2026-03-12 6:27 ` [PATCH v2 11/15] media: qcom: " Sumit Garg
2026-03-12 6:27 ` [PATCH v2 12/15] net: ipa: " Sumit Garg
2026-03-12 6:27 ` [PATCH v2 13/15] wifi: ath12k: " Sumit Garg
2026-03-12 6:27 ` [PATCH v2 14/15] firmware: qcom_scm: Remove SCM PAS wrappers Sumit Garg
2026-03-12 6:27 ` [PATCH v2 15/15] MAINTAINERS: Add maintainer entry for Qualcomm PAS TZ service Sumit Garg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=acFCbLZNOvhrm0Wh@sumit-xelite \
--to=sumit.garg@kernel.org \
--cc=abhinav.kumar@linux.dev \
--cc=airlied@gmail.com \
--cc=akhilpo@oss.qualcomm.com \
--cc=amirreza.zarrabi@oss.qualcomm.com \
--cc=andersson@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=apurupa@qti.qualcomm.com \
--cc=ath12k@lists.infradead.org \
--cc=bod@kernel.org \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=dikshita.agarwal@oss.qualcomm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=edumazet@google.com \
--cc=elder@kernel.org \
--cc=freedreno@lists.freedesktop.org \
--cc=jens.wiklander@linaro.org \
--cc=jesszhan0024@gmail.com \
--cc=jjohnson@kernel.org \
--cc=jorge.ramirez@oss.qualcomm.com \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-remoteproc@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=lumag@kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=mathieu.poirier@linaro.org \
--cc=mchehab@kernel.org \
--cc=mukesh.ojha@oss.qualcomm.com \
--cc=netdev@vger.kernel.org \
--cc=op-tee@lists.trustedfirmware.org \
--cc=pabeni@redhat.com \
--cc=pavan.kondeti@oss.qualcomm.com \
--cc=robh@kernel.org \
--cc=robin.clark@oss.qualcomm.com \
--cc=sean@poorly.run \
--cc=simona@ffwll.ch \
--cc=skare@qti.qualcomm.com \
--cc=srinivas.kandagatla@oss.qualcomm.com \
--cc=sumit.garg@oss.qualcomm.com \
--cc=tonyh@qti.qualcomm.com \
--cc=trilokkumar.soni@oss.qualcomm.com \
--cc=vignesh.viswanathan@oss.qualcomm.com \
--cc=vikash.garodia@oss.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox