* Re: [PATCH v2 01/15] arm64: dts: qcom: kodiak: Add EL2 overlay
[not found] ` <20260313060451.hswg6snnnexchmzs@hu-mojha-hyd.qualcomm.com>
@ 2026-03-23 12:35 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-23 12:35 UTC (permalink / raw)
To: Mukesh Ojha
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
On Fri, Mar 13, 2026 at 11:34:51AM +0530, Mukesh Ojha wrote:
> On Thu, Mar 12, 2026 at 11:57:42AM +0530, Sumit Garg wrote:
> > From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> >
> > All the existing variants Kodiak boards are using Gunyah hypervisor
> > which means that, so far, Linux-based OS could only boot in EL1 on those
> > devices. However, it is possible for us to boot Linux at EL2 on these
> > devices [1].
> >
> > When running under Gunyah, the remote processor firmware IOMMU
> > streams are controlled by Gunyah. However, without Gunyah, the IOMMU is
> > managed by the consumer of this DeviceTree. Therefore, describe the
> > firmware streams for each remote processor.
> >
> > Add a EL2-specific DT overlay and apply it to Kodiak IOT variant
> > devices to create -el2.dtb for each of them alongside "normal" dtb.
> >
> > [1]
> > https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-4/boot-developer-touchpoints.html#uefi
> >
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > [SG: watchdog fixup]
> > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > ---
> > arch/arm64/boot/dts/qcom/Makefile | 2 ++
> > arch/arm64/boot/dts/qcom/kodiak-el2.dtso | 35 ++++++++++++++++++++++++
> > 2 files changed, 37 insertions(+)
> > create mode 100644 arch/arm64/boot/dts/qcom/kodiak-el2.dtso
> >
> > diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
> > index f80b5d9cf1e8..09a7f943190e 100644
> > --- a/arch/arm64/boot/dts/qcom/Makefile
> > +++ b/arch/arm64/boot/dts/qcom/Makefile
> > @@ -139,6 +139,8 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs404-evb-4000.dtb
> > dtb-$(CONFIG_ARCH_QCOM) += qcs615-ride.dtb
> > dtb-$(CONFIG_ARCH_QCOM) += qcs6490-radxa-dragon-q6a.dtb
> > dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2.dtb
> > +qcs6490-rb3gen2-el2-dtbs := qcs6490-rb3gen2.dtb kodiak-el2.dtbo
> > +dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-el2.dtb
>
> We may need to add for couple of more variants..
Sure, those can be follow up patches if Bjorn is happy to pick this one
independently.
>
> >
> > qcs6490-rb3gen2-vision-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-vision-mezzanine.dtbo
> > qcs6490-rb3gen2-industrial-mezzanine-dtbs := qcs6490-rb3gen2.dtb qcs6490-rb3gen2-industrial-mezzanine.dtbo
> > diff --git a/arch/arm64/boot/dts/qcom/kodiak-el2.dtso b/arch/arm64/boot/dts/qcom/kodiak-el2.dtso
> > new file mode 100644
> > index 000000000000..0b3a69a0d765
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/qcom/kodiak-el2.dtso
> > @@ -0,0 +1,35 @@
> > +// SPDX-License-Identifier: BSD-3-Clause
> > +/*
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > + *
> > + * Kodiak specific modifications required to boot in EL2.
> > + */
> > +
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +&gpu_zap_shader {
> > + status = "disabled";
> > +};
> > +
> > +&remoteproc_adsp {
> > + iommus = <&apps_smmu 0x1800 0x0>;
> > +};
> > +
> > +&remoteproc_cdsp {
> > + iommus = <&apps_smmu 0x11a0 0x0400>;
> > +};
> > +
> > +&remoteproc_wpss {
> > + iommus = <&apps_smmu 0x1c03 0x1>,
> > + <&apps_smmu 0x1c83 0x1>;
> > +};
> > +
> > +&venus {
> > + status = "disabled";
> > +};
> > +
> > +&watchdog {
> > + status = "okay";
> > +};
>
>
> rb3gen2 has modem as well, did we test that as well ?
OP-TEE don't have access to modem, it's locked down in XBL-SEC.
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
[not found] ` <20260313072450.sx7vqtvh62nflhff@hu-mojha-hyd.qualcomm.com>
@ 2026-03-23 12:50 ` Sumit Garg
2026-03-27 13:39 ` Krzysztof Kozlowski
[not found] ` <20260313073121.qb7yq7tcga3sshcr@hu-mojha-hyd.qualcomm.com>
1 sibling, 1 reply; 16+ messages in thread
From: Sumit Garg @ 2026-03-23 12:50 UTC (permalink / raw)
To: Mukesh Ojha
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
On Fri, Mar 13, 2026 at 12:54:50PM +0530, Mukesh Ojha wrote:
> On Thu, Mar 12, 2026 at 11:57:43AM +0530, Sumit Garg wrote:
> > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> >
> > Qcom platforms has the legacy of using non-standard SCM calls
> > splintered over the various kernel drivers. These SCM calls aren't
> > compliant with the standard SMC calling conventions which is a
> > prerequisite to enable migration to the FF-A specifications from Arm.
> >
> > OP-TEE as an alternative trusted OS to Qualcomm TEE (QTEE) can't
> > support these non-standard SCM calls. And even for newer architectures
> > with S-EL2 and Hafnium support, QTEE won't be able to support SCM
>
> using S‑EL2 with Hafnium
Ack.
>
> > calls either with FF-A requirements coming in. And with both OP-TEE
> > and QTEE drivers well integrated in the TEE subsystem, it makes further
> > sense to reuse the TEE bus client drivers infrastructure.
> >
> > The added benefit of TEE bus infrastructure is that there is support
> > for discoverable/enumerable services. With that client drivers don't
> > have to manually invoke a special SCM call to know the service status.
> >
> > So enable the generic Peripheral Authentication Service (PAS) provided
> > by the firmware. It acts as the common layer with different TZ
> > backends plugged in whether it's an SCM implementation or a proper
> > TEE bus based PAS service implementation.
> >
> > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/Kconfig | 8 +
> > drivers/firmware/qcom/Makefile | 1 +
> > drivers/firmware/qcom/qcom_pas.c | 298 +++++++++++++++++++++++++
> > drivers/firmware/qcom/qcom_pas.h | 53 +++++
> > include/linux/firmware/qcom/qcom_pas.h | 41 ++++
> > 5 files changed, 401 insertions(+)
> > create mode 100644 drivers/firmware/qcom/qcom_pas.c
> > create mode 100644 drivers/firmware/qcom/qcom_pas.h
> > create mode 100644 include/linux/firmware/qcom/qcom_pas.h
> >
> > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > index b477d54b495a..8653639d06db 100644
> > --- a/drivers/firmware/qcom/Kconfig
> > +++ b/drivers/firmware/qcom/Kconfig
> > @@ -6,6 +6,14 @@
> >
> > menu "Qualcomm firmware drivers"
> >
> > +config QCOM_PAS
> > + tristate
> > + help
> > + Enable the generic Peripheral Authentication Service (PAS) provided
> > + by the firmware. It acts as the common layer with different TZ
> > + backends plugged in whether it's an SCM implementation or a proper
> > + TEE bus based PAS service implementation.
> > +
> > config QCOM_SCM
> > select QCOM_TZMEM
> > tristate
> > diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
> > index 0be40a1abc13..dc5ab45f906a 100644
> > --- a/drivers/firmware/qcom/Makefile
> > +++ b/drivers/firmware/qcom/Makefile
> > @@ -8,3 +8,4 @@ qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
> > 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
> > diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
> > new file mode 100644
> > index 000000000000..beb1bae55546
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_pas.c
> > @@ -0,0 +1,298 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > + */
> > +
> > +#include <linux/device/devres.h>
> > +#include <linux/firmware/qcom/qcom_pas.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +
> > +#include "qcom_pas.h"
> > +
> > +struct qcom_pas_ops *ops_ptr;
>
> Should this be static ?
It was static earlier in v1. I dropped it based on earlier v1 discussion
with Krzysztof. Let me conclude that discussion on the other thread
again.
>
> > +
> > +/**
> > + * devm_qcom_pas_context_alloc() - Allocate peripheral authentication service
> > + * context for a given peripheral
> > + *
> > + * PAS context is device-resource managed, so the caller does not need
> > + * to worry about freeing the context memory.
> > + *
> > + * @dev: PAS firmware device
> > + * @pas_id: peripheral authentication service id
> > + * @mem_phys: Subsystem reserve memory start address
> > + * @mem_size: Subsystem reserve memory size
> > + *
> > + * Return: The new PAS context, or ERR_PTR() on failure.
> > + */
> > +struct qcom_pas_context *devm_qcom_pas_context_alloc(struct device *dev,
> > + u32 pas_id,
> > + phys_addr_t mem_phys,
> > + size_t mem_size)
> > +{
> > + struct qcom_pas_context *ctx;
> > +
> > + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> > + if (!ctx)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + ctx->dev = dev;
> > + ctx->pas_id = pas_id;
> > + ctx->mem_phys = mem_phys;
> > + ctx->mem_size = mem_size;
> > +
> > + return ctx;
> > +}
> > +EXPORT_SYMBOL_GPL(devm_qcom_pas_context_alloc);
> > +
> > +/**
> > + * qcom_pas_init_image() - Initialize peripheral authentication service state
> > + * machine for a given peripheral, using the metadata
> > + * @pas_id: peripheral authentication service id
> > + * @metadata: pointer to memory containing ELF header, program header table
> > + * and optional blob of data used for authenticating the metadata
> > + * and the rest of the firmware
> > + * @size: size of the metadata
> > + * @ctx: optional pas context
> > + *
> > + * Return: 0 on success.
> > + *
> > + * Upon successful return, the PAS metadata context (@ctx) will be used to
> > + * track the metadata allocation, this needs to be released by invoking
> > + * qcom_pas_metadata_release() by the caller.
> > + */
> > +int qcom_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > + struct qcom_pas_context *ctx)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->init_image(ops_ptr->dev, pas_id,
> > + metadata, size, ctx);
> > +
> > + return -ENODEV;
>
>
> if (!ops_ptr)
> return -ENODEV;
>
> return ops_ptr->init_image(ops_ptr->dev, pas_id, metadata, size, ctx);
>
I think it's a matter of taste here, I usually prefer to check for the
positive scenarios until there is benefit to make an early return.
>
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_init_image);
> > +
> > +/**
> > + * qcom_pas_metadata_release() - release metadata context
> > + * @ctx: pas context
> > + */
> > +void qcom_pas_metadata_release(struct qcom_pas_context *ctx)
> > +{
> > + if (!ctx || !ctx->ptr)
> > + return;
> > +
> > + if (ops_ptr)
> > + ops_ptr->metadata_release(ops_ptr->dev, ctx);
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_metadata_release);
> > +
> > +/**
> > + * qcom_pas_mem_setup() - Prepare the memory related to a given peripheral
> > + * for firmware loading
> > + * @pas_id: peripheral authentication service id
> > + * @addr: start address of memory area to prepare
> > + * @size: size of the memory area to prepare
> > + *
> > + * Return: 0 on success.
> > + */
> > +int qcom_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->mem_setup(ops_ptr->dev, pas_id, addr, size);
> > +
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_mem_setup);
> > +
> > +/**
> > + * qcom_pas_get_rsc_table() - Retrieve the resource table in passed output buffer
> > + * for a given peripheral.
> > + *
> > + * Qualcomm remote processor may rely on both static and dynamic resources for
> > + * its functionality. Static resources typically refer to memory-mapped
> > + * addresses required by the subsystem and are often embedded within the
> > + * firmware binary and dynamic resources, such as shared memory in DDR etc.,
> > + * are determined at runtime during the boot process.
> > + *
> > + * On Qualcomm Technologies devices, it's possible that static resources are
> > + * not embedded in the firmware binary and instead are provided by TrustZone.
> > + * However, dynamic resources are always expected to come from TrustZone. This
> > + * indicates that for Qualcomm devices, all resources (static and dynamic) will
> > + * be provided by TrustZone PAS service.
> > + *
> > + * If the remote processor firmware binary does contain static resources, they
> > + * should be passed in input_rt. These will be forwarded to TrustZone for
> > + * authentication. TrustZone will then append the dynamic resources and return
> > + * the complete resource table in output_rt_tzm.
> > + *
> > + * If the remote processor firmware binary does not include a resource table,
> > + * the caller of this function should set input_rt as NULL and input_rt_size
> > + * as zero respectively.
> > + *
> > + * More about documentation on resource table data structures can be found in
> > + * include/linux/remoteproc.h
> > + *
> > + * @ctx: PAS context
> > + * @pas_id: peripheral authentication service id
> > + * @input_rt: resource table buffer which is present in firmware binary
> > + * @input_rt_size: size of the resource table present in firmware binary
> > + * @output_rt_size: TrustZone expects caller should pass worst case size for
> > + * the output_rt_tzm.
> > + *
> > + * Return:
> > + * On success, returns a pointer to the allocated buffer containing the final
> > + * resource table and output_rt_size will have actual resource table size from
> > + * TrustZone. The caller is responsible for freeing the buffer. On failure,
> > + * returns ERR_PTR(-errno).
> > + */
> > +struct resource_table *qcom_pas_get_rsc_table(struct qcom_pas_context *ctx,
> > + void *input_rt,
> > + size_t input_rt_size,
> > + size_t *output_rt_size)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->get_rsc_table(ops_ptr->dev, ctx, input_rt,
> > + input_rt_size, output_rt_size);
> > +
> > + return ERR_PTR(-ENODEV);
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_get_rsc_table);
> > +
> > +/**
> > + * qcom_pas_auth_and_reset() - Authenticate the given peripheral firmware
> > + * and reset the remote processor
> > + * @pas_id: peripheral authentication service id
> > + *
> > + * Return: 0 on success.
> > + */
> > +int qcom_pas_auth_and_reset(u32 pas_id)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->auth_and_reset(ops_ptr->dev, pas_id);
> > +
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_auth_and_reset);
> > +
> > +/**
> > + * qcom_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_pas_prepare_and_auth_reset(struct qcom_pas_context *ctx)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->prepare_and_auth_reset(ops_ptr->dev, ctx);
> > +
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_prepare_and_auth_reset);
> > +
> > +/**
> > + * qcom_pas_set_remote_state() - Set the remote processor state
> > + * @state: peripheral state
> > + * @pas_id: peripheral authentication service id
> > + *
> > + * Return: 0 on success.
> > + */
> > +int qcom_pas_set_remote_state(u32 state, u32 pas_id)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->set_remote_state(ops_ptr->dev, state, pas_id);
> > +
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_set_remote_state);
> > +
> > +/**
> > + * qcom_pas_shutdown() - Shut down the remote processor
> > + * @pas_id: peripheral authentication service id
> > + *
> > + * Return: 0 on success.
> > + */
> > +int qcom_pas_shutdown(u32 pas_id)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->shutdown(ops_ptr->dev, pas_id);
> > +
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_shutdown);
> > +
> > +/**
> > + * qcom_pas_supported() - Check if the peripheral authentication service is
> > + * available for the given peripheral
> > + * @pas_id: peripheral authentication service id
> > + *
> > + * Return: true if PAS is supported for this peripheral, otherwise false.
> > + */
> > +bool qcom_pas_supported(u32 pas_id)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->supported(ops_ptr->dev, pas_id);
> > +
> > + return false;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_supported);
> > +
> > +/**
> > + * qcom_pas_is_available() - Check for PAS service
> > + *
>
> Name of the function is self sufficient, we can avoid for one liner
> documentation.
The documentation here is for the sake of completeness for all the APIs.
Sure, I can drop it if it doesn't add any value.
>
> > + * Return: true on success.
> > + */
> > +bool qcom_pas_is_available(void)
> > +{
> > + /*
> > + * The barrier for ops_ptr is intended to synchronize the data stores
> > + * for the ops data structure when client drivers are in parallel
> > + * checking for PAS service availability.
> > + *
> > + * Once the PAS backend becomes available, it is allowed for multiple
> > + * threads to enter TZ for parallel bringup of co-processors during
> > + * boot.
> > + */
> > + return !!smp_load_acquire(&ops_ptr);
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_is_available);
> > +
> > +/**
> > + * qcom_pas_ops_register() - Register PAS service ops
> > + * @ops: PAS service ops pointer
> > + */
>
> same here..
>
> > +void qcom_pas_ops_register(struct qcom_pas_ops *ops)
> > +{
> > + if (!qcom_pas_is_available())
> > + /* Paired with smp_load_acquire() in qcom_pas_is_available() */
> > + smp_store_release(&ops_ptr, ops);
> > + else
> > + pr_err("qcom_pas: ops already registered\n");
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_ops_register);
> > +
> > +/**
> > + * qcom_pas_ops_unregister() - Unregister PAS service ops
> > + */
>
> same here to avoid verbose..
>
> > +void qcom_pas_ops_unregister(void)
> > +{
> > + /* Paired with smp_load_acquire() in qcom_pas_is_available() */
> > + smp_store_release(&ops_ptr, NULL);
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_ops_unregister);
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_DESCRIPTION("Qualcomm common TZ PAS driver");
> > diff --git a/drivers/firmware/qcom/qcom_pas.h b/drivers/firmware/qcom/qcom_pas.h
> > new file mode 100644
> > index 000000000000..4ebed22178f8
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_pas.h
> > @@ -0,0 +1,53 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > + */
> > +
> > +#ifndef __QCOM_PAS_INT_H
> > +#define __QCOM_PAS_INT_H
> > +
> > +struct device;
> > +
> > +/**
> > + * struct qcom_pas_ops - Qcom Peripheral Authentication Service (PAS) ops
> > + * @drv_name: PAS driver name.
> > + * @dev: PAS device pointer.
> > + * @supported: Peripheral supported callback.
> > + * @init_image: Peripheral image initialization callback.
> > + * @mem_setup: Peripheral memory setup callback.
> > + * @get_rsc_table: Peripheral get resource table callback.
> > + * @prepare_and_auth_reset: Peripheral prepare firmware authentication and
> > + * reset callback.
> > + * @auth_and_reset: Peripheral firmware authentication and reset
> > + * callback.
> > + * @set_remote_state: Peripheral set remote state callback.
> > + * @shutdown: Peripheral shutdown callback.
> > + * @metadata_release: Image metadata release callback.
> > + */
> > +struct qcom_pas_ops {
> > + const char *drv_name;
> > + struct device *dev;
> > + bool (*supported)(struct device *dev, u32 pas_id);
> > + int (*init_image)(struct device *dev, u32 pas_id,
> > + const void *metadata, size_t size,
> > + struct qcom_pas_context *ctx);
> > + int (*mem_setup)(struct device *dev, u32 pas_id,
> > + phys_addr_t addr, phys_addr_t size);
> > + void *(*get_rsc_table)(struct device *dev,
> > + struct qcom_pas_context *ctx,
> > + void *input_rt,
> > + size_t input_rt_size,
> > + size_t *output_rt_size);
> > + int (*prepare_and_auth_reset)(struct device *dev,
> > + struct qcom_pas_context *ctx);
> > + int (*auth_and_reset)(struct device *dev, u32 pas_id);
> > + int (*set_remote_state)(struct device *dev, u32 state, u32 pas_id);
> > + int (*shutdown)(struct device *dev, u32 pas_id);
> > + void (*metadata_release)(struct device *dev,
> > + struct qcom_pas_context *ctx);
>
> I think, some of them can be unwrapped to look cleaner..
Not sure if I understand what you meant by unwrap here, can you
ellaborate a bit?
>
> > +};
> > +
> > +void qcom_pas_ops_register(struct qcom_pas_ops *ops);
> > +void qcom_pas_ops_unregister(void);
> > +
> > +#endif /* __QCOM_PAS_INT_H */
> > diff --git a/include/linux/firmware/qcom/qcom_pas.h b/include/linux/firmware/qcom/qcom_pas.h
> > new file mode 100644
> > index 000000000000..ef7328ecfa47
> > --- /dev/null
> > +++ b/include/linux/firmware/qcom/qcom_pas.h
> > @@ -0,0 +1,41 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>
>
> Should this not carry all copyright coming from qcom_scm.h
These are all new wrapper APIs for the generic PAS service. However, the
API design is influenced by the SCM APIs only since we don't want to
break client drivers API contract in this patch-set. I will carry those
copyrights here.
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
[not found] ` <20260313073121.qb7yq7tcga3sshcr@hu-mojha-hyd.qualcomm.com>
@ 2026-03-23 12:55 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-23 12:55 UTC (permalink / raw)
To: Mukesh Ojha
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
On Fri, Mar 13, 2026 at 01:01:21PM +0530, Mukesh Ojha wrote:
> On Fri, Mar 13, 2026 at 12:54:50PM +0530, Mukesh Ojha wrote:
> > On Thu, Mar 12, 2026 at 11:57:43AM +0530, Sumit Garg wrote:
> > > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > >
> > > Qcom platforms has the legacy of using non-standard SCM calls
> > > splintered over the various kernel drivers. These SCM calls aren't
> > > compliant with the standard SMC calling conventions which is a
> > > prerequisite to enable migration to the FF-A specifications from Arm.
> > >
> > > OP-TEE as an alternative trusted OS to Qualcomm TEE (QTEE) can't
> > > support these non-standard SCM calls. And even for newer architectures
> > > with S-EL2 and Hafnium support, QTEE won't be able to support SCM
> >
> > using S‑EL2 with Hafnium
> >
> > > calls either with FF-A requirements coming in. And with both OP-TEE
> > > and QTEE drivers well integrated in the TEE subsystem, it makes further
> > > sense to reuse the TEE bus client drivers infrastructure.
> > >
> > > The added benefit of TEE bus infrastructure is that there is support
> > > for discoverable/enumerable services. With that client drivers don't
> > > have to manually invoke a special SCM call to know the service status.
> > >
> > > So enable the generic Peripheral Authentication Service (PAS) provided
> > > by the firmware. It acts as the common layer with different TZ
> > > backends plugged in whether it's an SCM implementation or a proper
> > > TEE bus based PAS service implementation.
> > >
> > > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > > ---
> > > drivers/firmware/qcom/Kconfig | 8 +
> > > drivers/firmware/qcom/Makefile | 1 +
> > > drivers/firmware/qcom/qcom_pas.c | 298 +++++++++++++++++++++++++
> > > drivers/firmware/qcom/qcom_pas.h | 53 +++++
> > > include/linux/firmware/qcom/qcom_pas.h | 41 ++++
> > > 5 files changed, 401 insertions(+)
> > > create mode 100644 drivers/firmware/qcom/qcom_pas.c
> > > create mode 100644 drivers/firmware/qcom/qcom_pas.h
> > > create mode 100644 include/linux/firmware/qcom/qcom_pas.h
> > >
<snip>
> > > diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
> > > new file mode 100644
> > > index 000000000000..beb1bae55546
> > > --- /dev/null
> > > +++ b/drivers/firmware/qcom/qcom_pas.c
> > > @@ -0,0 +1,298 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > > + */
> > > +
> > > +#include <linux/device/devres.h>
> > > +#include <linux/firmware/qcom/qcom_pas.h>
> > > +#include <linux/kernel.h>
> > > +#include <linux/module.h>
> > > +
> > > +#include "qcom_pas.h"
> > > +
> > > +struct qcom_pas_ops *ops_ptr;
> >
> > Should this be static ?
> >
> > > +
> > > +/**
> > > + * devm_qcom_pas_context_alloc() - Allocate peripheral authentication service
> > > + * context for a given peripheral
> > > + *
> > > + * PAS context is device-resource managed, so the caller does not need
> > > + * to worry about freeing the context memory.
> > > + *
> > > + * @dev: PAS firmware device
> > > + * @pas_id: peripheral authentication service id
> > > + * @mem_phys: Subsystem reserve memory start address
> > > + * @mem_size: Subsystem reserve memory size
> > > + *
> > > + * Return: The new PAS context, or ERR_PTR() on failure.
> > > + */
> > > +struct qcom_pas_context *devm_qcom_pas_context_alloc(struct device *dev,
> > > + u32 pas_id,
> > > + phys_addr_t mem_phys,
> > > + size_t mem_size)
> > > +{
> > > + struct qcom_pas_context *ctx;
> > > +
> > > + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> > > + if (!ctx)
> > > + return ERR_PTR(-ENOMEM);
> > > +
> > > + ctx->dev = dev;
> > > + ctx->pas_id = pas_id;
> > > + ctx->mem_phys = mem_phys;
> > > + ctx->mem_size = mem_size;
> > > +
> > > + return ctx;
> > > +}
> > > +EXPORT_SYMBOL_GPL(devm_qcom_pas_context_alloc);
> > > +
> > > +/**
> > > + * qcom_pas_init_image() - Initialize peripheral authentication service state
> > > + * machine for a given peripheral, using the metadata
> > > + * @pas_id: peripheral authentication service id
> > > + * @metadata: pointer to memory containing ELF header, program header table
> > > + * and optional blob of data used for authenticating the metadata
> > > + * and the rest of the firmware
> > > + * @size: size of the metadata
> > > + * @ctx: optional pas context
> > > + *
> > > + * Return: 0 on success.
> > > + *
> > > + * Upon successful return, the PAS metadata context (@ctx) will be used to
> > > + * track the metadata allocation, this needs to be released by invoking
> > > + * qcom_pas_metadata_release() by the caller.
> > > + */
> > > +int qcom_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > > + struct qcom_pas_context *ctx)
>
> please, align this with previous line '(' for all the functions.
>
The alignment is fine here, not sure why the plain text replies show
them as not aligned.
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
[not found] ` <20260313075948.nbopdkctdcvzlj3f@hu-mojha-hyd.qualcomm.com>
@ 2026-03-23 13:01 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-23 13:01 UTC (permalink / raw)
To: Mukesh Ojha
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
On Fri, Mar 13, 2026 at 01:29:48PM +0530, Mukesh Ojha wrote:
> On Thu, Mar 12, 2026 at 11:57:43AM +0530, Sumit Garg wrote:
> > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> >
> > Qcom platforms has the legacy of using non-standard SCM calls
> > splintered over the various kernel drivers. These SCM calls aren't
> > compliant with the standard SMC calling conventions which is a
> > prerequisite to enable migration to the FF-A specifications from Arm.
> >
> > OP-TEE as an alternative trusted OS to Qualcomm TEE (QTEE) can't
> > support these non-standard SCM calls. And even for newer architectures
> > with S-EL2 and Hafnium support, QTEE won't be able to support SCM
> > calls either with FF-A requirements coming in. And with both OP-TEE
> > and QTEE drivers well integrated in the TEE subsystem, it makes further
> > sense to reuse the TEE bus client drivers infrastructure.
> >
> > The added benefit of TEE bus infrastructure is that there is support
> > for discoverable/enumerable services. With that client drivers don't
> > have to manually invoke a special SCM call to know the service status.
> >
> > So enable the generic Peripheral Authentication Service (PAS) provided
> > by the firmware. It acts as the common layer with different TZ
> > backends plugged in whether it's an SCM implementation or a proper
> > TEE bus based PAS service implementation.
> >
> > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/Kconfig | 8 +
> > drivers/firmware/qcom/Makefile | 1 +
> > drivers/firmware/qcom/qcom_pas.c | 298 +++++++++++++++++++++++++
> > drivers/firmware/qcom/qcom_pas.h | 53 +++++
> > include/linux/firmware/qcom/qcom_pas.h | 41 ++++
> > 5 files changed, 401 insertions(+)
> > create mode 100644 drivers/firmware/qcom/qcom_pas.c
> > create mode 100644 drivers/firmware/qcom/qcom_pas.h
> > create mode 100644 include/linux/firmware/qcom/qcom_pas.h
> >
<snip>
> > diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
> > new file mode 100644
> > index 000000000000..beb1bae55546
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_pas.c
> > @@ -0,0 +1,298 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > + */
>
> I know, this is new file but most of the documentation and some of the
> function are rename to reflect pas service.
>
> Should this carry original file copyright ? Not sure..
>
This file only contains the wrapper generic PAS APIs which aren't
re-used from any other file. Carrying copyrights solely based on moving
API documentation in not very clear to me. Any other thoughts?
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
[not found] ` <124f5a78-a3be-4906-bea0-a82bb74b2f96@oss.qualcomm.com>
@ 2026-03-23 13:12 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-23 13:12 UTC (permalink / raw)
To: Harshal Dev
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
linux-kernel, Sumit Garg
On Sun, Mar 15, 2026 at 10:03:16PM +0530, Harshal Dev wrote:
>
>
> On 3/12/2026 11:57 AM, Sumit Garg wrote:
> > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> >
> > Qcom platforms has the legacy of using non-standard SCM calls
> > splintered over the various kernel drivers. These SCM calls aren't
> > compliant with the standard SMC calling conventions which is a
> > prerequisite to enable migration to the FF-A specifications from Arm.
> >
> > OP-TEE as an alternative trusted OS to Qualcomm TEE (QTEE) can't
> > support these non-standard SCM calls. And even for newer architectures
> > with S-EL2 and Hafnium support, QTEE won't be able to support SCM
> > calls either with FF-A requirements coming in. And with both OP-TEE
> > and QTEE drivers well integrated in the TEE subsystem, it makes further
> > sense to reuse the TEE bus client drivers infrastructure.
> >
> > The added benefit of TEE bus infrastructure is that there is support
> > for discoverable/enumerable services. With that client drivers don't
> > have to manually invoke a special SCM call to know the service status.
> >
> > So enable the generic Peripheral Authentication Service (PAS) provided
> > by the firmware. It acts as the common layer with different TZ
> > backends plugged in whether it's an SCM implementation or a proper
> > TEE bus based PAS service implementation.
> >
> > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/Kconfig | 8 +
> > drivers/firmware/qcom/Makefile | 1 +
> > drivers/firmware/qcom/qcom_pas.c | 298 +++++++++++++++++++++++++
> > drivers/firmware/qcom/qcom_pas.h | 53 +++++
> > include/linux/firmware/qcom/qcom_pas.h | 41 ++++
> > 5 files changed, 401 insertions(+)
> > create mode 100644 drivers/firmware/qcom/qcom_pas.c
> > create mode 100644 drivers/firmware/qcom/qcom_pas.h
> > create mode 100644 include/linux/firmware/qcom/qcom_pas.h
> >
> > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > index b477d54b495a..8653639d06db 100644
> > --- a/drivers/firmware/qcom/Kconfig
> > +++ b/drivers/firmware/qcom/Kconfig
> > @@ -6,6 +6,14 @@
> >
> > menu "Qualcomm firmware drivers"
> >
> > +config QCOM_PAS
> > + tristate
> > + help
> > + Enable the generic Peripheral Authentication Service (PAS) provided
> > + by the firmware. It acts as the common layer with different TZ
> > + backends plugged in whether it's an SCM implementation or a proper
> > + TEE bus based PAS service implementation.
> > +
> > config QCOM_SCM
> > select QCOM_TZMEM
> > tristate
> > diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
> > index 0be40a1abc13..dc5ab45f906a 100644
> > --- a/drivers/firmware/qcom/Makefile
> > +++ b/drivers/firmware/qcom/Makefile
> > @@ -8,3 +8,4 @@ qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
> > 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
> > diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
> > new file mode 100644
> > index 000000000000..beb1bae55546
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_pas.c
> > @@ -0,0 +1,298 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > + */
> > +
> > +#include <linux/device/devres.h>
> > +#include <linux/firmware/qcom/qcom_pas.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +
> > +#include "qcom_pas.h"
> > +
> > +struct qcom_pas_ops *ops_ptr;
> > +
> > +/**
> > + * devm_qcom_pas_context_alloc() - Allocate peripheral authentication service
> > + * context for a given peripheral
> > + *
> > + * PAS context is device-resource managed, so the caller does not need
> > + * to worry about freeing the context memory.
> > + *
> > + * @dev: PAS firmware device
> > + * @pas_id: peripheral authentication service id
> > + * @mem_phys: Subsystem reserve memory start address
> > + * @mem_size: Subsystem reserve memory size
> > + *
> > + * Return: The new PAS context, or ERR_PTR() on failure.
> > + */
> > +struct qcom_pas_context *devm_qcom_pas_context_alloc(struct device *dev,
> > + u32 pas_id,
> > + phys_addr_t mem_phys,
> > + size_t mem_size)
> > +{
> > + struct qcom_pas_context *ctx;
> > +
> > + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> > + if (!ctx)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + ctx->dev = dev;
> > + ctx->pas_id = pas_id;
> > + ctx->mem_phys = mem_phys;
> > + ctx->mem_size = mem_size;
> > +
> > + return ctx;
> > +}
> > +EXPORT_SYMBOL_GPL(devm_qcom_pas_context_alloc);
> > +
> > +/**
> > + * qcom_pas_init_image() - Initialize peripheral authentication service state
> > + * machine for a given peripheral, using the metadata
> > + * @pas_id: peripheral authentication service id
> > + * @metadata: pointer to memory containing ELF header, program header table
> > + * and optional blob of data used for authenticating the metadata
> > + * and the rest of the firmware
> > + * @size: size of the metadata
> > + * @ctx: optional pas context
> > + *
> > + * Return: 0 on success.
> > + *
> > + * Upon successful return, the PAS metadata context (@ctx) will be used to
> > + * track the metadata allocation, this needs to be released by invoking
> > + * qcom_pas_metadata_release() by the caller.
> > + */
> > +int qcom_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > + struct qcom_pas_context *ctx)
> > +{
>
> I think we should check for !ctx everywhere the way we are doing in qcom_pas_metadata_release().
> !ctx->ptr may be checked conditionally based on whether the underlying implementation
> uses it.
The ctx for this API is optional, that means the backend should check
apporpriately for it. I will add that check for TEE backend though.
>
> > + if (ops_ptr)
> > + return ops_ptr->init_image(ops_ptr->dev, pas_id,
> > + metadata, size, ctx);
> > +
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_init_image);
> > +
> > +/**
> > + * qcom_pas_metadata_release() - release metadata context
> > + * @ctx: pas context
> > + */
> > +void qcom_pas_metadata_release(struct qcom_pas_context *ctx)
> > +{
> > + if (!ctx || !ctx->ptr)
> > + return;
> > +
> > + if (ops_ptr)
> > + ops_ptr->metadata_release(ops_ptr->dev, ctx);
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_metadata_release);
> > +
> > +/**
> > + * qcom_pas_mem_setup() - Prepare the memory related to a given peripheral
> > + * for firmware loading
> > + * @pas_id: peripheral authentication service id
> > + * @addr: start address of memory area to prepare
> > + * @size: size of the memory area to prepare
> > + *
> > + * Return: 0 on success.
> > + */
> > +int qcom_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->mem_setup(ops_ptr->dev, pas_id, addr, size);
> > +
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_mem_setup);
> > +
> > +/**
> > + * qcom_pas_get_rsc_table() - Retrieve the resource table in passed output buffer
> > + * for a given peripheral.
> > + *
> > + * Qualcomm remote processor may rely on both static and dynamic resources for
> > + * its functionality. Static resources typically refer to memory-mapped
> > + * addresses required by the subsystem and are often embedded within the
> > + * firmware binary and dynamic resources, such as shared memory in DDR etc.,
> > + * are determined at runtime during the boot process.
> > + *
> > + * On Qualcomm Technologies devices, it's possible that static resources are
> > + * not embedded in the firmware binary and instead are provided by TrustZone.
> > + * However, dynamic resources are always expected to come from TrustZone. This
> > + * indicates that for Qualcomm devices, all resources (static and dynamic) will
> > + * be provided by TrustZone PAS service.
> > + *
> > + * If the remote processor firmware binary does contain static resources, they
> > + * should be passed in input_rt. These will be forwarded to TrustZone for
> > + * authentication. TrustZone will then append the dynamic resources and return
> > + * the complete resource table in output_rt_tzm.
> > + *
> > + * If the remote processor firmware binary does not include a resource table,
> > + * the caller of this function should set input_rt as NULL and input_rt_size
> > + * as zero respectively.
> > + *
> > + * More about documentation on resource table data structures can be found in
> > + * include/linux/remoteproc.h
> > + *
> > + * @ctx: PAS context
> > + * @pas_id: peripheral authentication service id
> > + * @input_rt: resource table buffer which is present in firmware binary
> > + * @input_rt_size: size of the resource table present in firmware binary
> > + * @output_rt_size: TrustZone expects caller should pass worst case size for
> > + * the output_rt_tzm.
> > + *
> > + * Return:
> > + * On success, returns a pointer to the allocated buffer containing the final
> > + * resource table and output_rt_size will have actual resource table size from
> > + * TrustZone. The caller is responsible for freeing the buffer. On failure,
> > + * returns ERR_PTR(-errno).
> > + */
> > +struct resource_table *qcom_pas_get_rsc_table(struct qcom_pas_context *ctx,
> > + void *input_rt,
> > + size_t input_rt_size,
> > + size_t *output_rt_size)
> > +{
>
> Check for !ctx here as well.
Ack.
>
> > + if (ops_ptr)
> > + return ops_ptr->get_rsc_table(ops_ptr->dev, ctx, input_rt,
> > + input_rt_size, output_rt_size);
> > +
> > + return ERR_PTR(-ENODEV);
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_get_rsc_table);
> > +
> > +/**
> > + * qcom_pas_auth_and_reset() - Authenticate the given peripheral firmware
> > + * and reset the remote processor
> > + * @pas_id: peripheral authentication service id
> > + *
> > + * Return: 0 on success.
> > + */
> > +int qcom_pas_auth_and_reset(u32 pas_id)
> > +{
> > + if (ops_ptr)
> > + return ops_ptr->auth_and_reset(ops_ptr->dev, pas_id);
> > +
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_pas_auth_and_reset);
> > +
> > +/**
> > + * qcom_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_pas_prepare_and_auth_reset(struct qcom_pas_context *ctx)
> > +{
>
> Same here.
Ack.
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
[not found] ` <28d63822-f191-400a-8005-5185dd480dbb@kernel.org>
@ 2026-03-23 13:22 ` Sumit Garg
2026-03-23 14:19 ` Krzysztof Kozlowski
0 siblings, 1 reply; 16+ messages in thread
From: Sumit Garg @ 2026-03-23 13:22 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
linux-kernel, Sumit Garg
On Mon, Mar 16, 2026 at 08:51:16AM +0100, Krzysztof Kozlowski wrote:
> On 12/03/2026 07:27, Sumit Garg wrote:
> > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> >
> > Qcom platforms has the legacy of using non-standard SCM calls
> > splintered over the various kernel drivers. These SCM calls aren't
> > compliant with the standard SMC calling conventions which is a
> > prerequisite to enable migration to the FF-A specifications from Arm.
> >
> > OP-TEE as an alternative trusted OS to Qualcomm TEE (QTEE) can't
> > support these non-standard SCM calls. And even for newer architectures
> > with S-EL2 and Hafnium support, QTEE won't be able to support SCM
> > calls either with FF-A requirements coming in. And with both OP-TEE
> > and QTEE drivers well integrated in the TEE subsystem, it makes further
> > sense to reuse the TEE bus client drivers infrastructure.
> >
> > The added benefit of TEE bus infrastructure is that there is support
> > for discoverable/enumerable services. With that client drivers don't
> > have to manually invoke a special SCM call to know the service status.
> >
> > So enable the generic Peripheral Authentication Service (PAS) provided
> > by the firmware. It acts as the common layer with different TZ
> > backends plugged in whether it's an SCM implementation or a proper
> > TEE bus based PAS service implementation.
> >
> > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/Kconfig | 8 +
> > drivers/firmware/qcom/Makefile | 1 +
> > drivers/firmware/qcom/qcom_pas.c | 298 +++++++++++++++++++++++++
> > drivers/firmware/qcom/qcom_pas.h | 53 +++++
> > include/linux/firmware/qcom/qcom_pas.h | 41 ++++
> > 5 files changed, 401 insertions(+)
> > create mode 100644 drivers/firmware/qcom/qcom_pas.c
> > create mode 100644 drivers/firmware/qcom/qcom_pas.h
> > create mode 100644 include/linux/firmware/qcom/qcom_pas.h
> >
> > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > index b477d54b495a..8653639d06db 100644
> > --- a/drivers/firmware/qcom/Kconfig
> > +++ b/drivers/firmware/qcom/Kconfig
> > @@ -6,6 +6,14 @@
> >
> > menu "Qualcomm firmware drivers"
> >
> > +config QCOM_PAS
> > + tristate
> > + help
> > + Enable the generic Peripheral Authentication Service (PAS) provided
> > + by the firmware. It acts as the common layer with different TZ
> > + backends plugged in whether it's an SCM implementation or a proper
> > + TEE bus based PAS service implementation.
> > +
> > config QCOM_SCM
> > select QCOM_TZMEM
> > tristate
> > diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
> > index 0be40a1abc13..dc5ab45f906a 100644
> > --- a/drivers/firmware/qcom/Makefile
> > +++ b/drivers/firmware/qcom/Makefile
> > @@ -8,3 +8,4 @@ qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
> > 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
> > diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
> > new file mode 100644
> > index 000000000000..beb1bae55546
> > --- /dev/null
> > +++ b/drivers/firmware/qcom/qcom_pas.c
> > @@ -0,0 +1,298 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > + */
> > +
> > +#include <linux/device/devres.h>
> > +#include <linux/firmware/qcom/qcom_pas.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +
> > +#include "qcom_pas.h"
> > +
> > +struct qcom_pas_ops *ops_ptr;
>
> Same comment as before. Don't create singletons. And for sure not global
> ones.
This pattern has been carried from the PAS API contract among kernel
clients and the SCM PAS service earlier. The clients don't hold a
reference to the PAS data like underlying platform or TEE device etc.
Hence the need to have a global data pointer to hold reference to the
ops data structure registered by drivers having different lifetime of
devices. Also, the PAS APIs can be called from very different client
driver contexts.
Surely, avoiding global data is always better given a better alternative
is there. Do you have any better alternative proposal here?
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 03/15] firmware: qcom_scm: Migrate to generic PAS service
[not found] ` <20260313075607.2mw3dzaf274xxe2j@hu-mojha-hyd.qualcomm.com>
@ 2026-03-23 13:33 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-23 13:33 UTC (permalink / raw)
To: Mukesh Ojha
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
On Fri, Mar 13, 2026 at 01:26:07PM +0530, Mukesh Ojha wrote:
> On Thu, Mar 12, 2026 at 11:57:44AM +0530, Sumit Garg wrote:
> > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> >
> > With the availability of generic PAS service, let's add SCM calls as
> > a backend to keep supporting legacy QTEE interfaces. The exported
> > qcom_scm* wrappers will get dropped once all the client drivers get
> > migrated as part of future patches.
> >
> > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/Kconfig | 1 +
> > drivers/firmware/qcom/qcom_scm.c | 336 ++++++++++++++-----------------
> > 2 files changed, 156 insertions(+), 181 deletions(-)
> >
> > diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
> > index 8653639d06db..9a12ae2b639d 100644
> > --- a/drivers/firmware/qcom/Kconfig
> > +++ b/drivers/firmware/qcom/Kconfig
> > @@ -15,6 +15,7 @@ config QCOM_PAS
> > TEE bus based PAS service implementation.
> >
> > config QCOM_SCM
> > + select QCOM_PAS
> > select QCOM_TZMEM
> > tristate
> >
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 8fbc96693a55..2d7937ae7c8f 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -13,6 +13,7 @@
> > #include <linux/dma-mapping.h>
> > #include <linux/err.h>
> > #include <linux/export.h>
> > +#include <linux/firmware/qcom/qcom_pas.h>
> > #include <linux/firmware/qcom/qcom_scm.h>
> > #include <linux/firmware/qcom/qcom_tzmem.h>
> > #include <linux/init.h>
> > @@ -33,6 +34,7 @@
> >
> > #include <dt-bindings/interrupt-controller/arm-gic.h>
> >
> > +#include "qcom_pas.h"
> > #include "qcom_scm.h"
> > #include "qcom_tzmem.h"
> >
> > @@ -480,25 +482,6 @@ void qcom_scm_cpu_power_down(u32 flags)
> > }
> > EXPORT_SYMBOL_GPL(qcom_scm_cpu_power_down);
> >
> > -int qcom_scm_set_remote_state(u32 state, u32 id)
> > -{
> > - struct qcom_scm_desc desc = {
> > - .svc = QCOM_SCM_SVC_BOOT,
> > - .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE,
> > - .arginfo = QCOM_SCM_ARGS(2),
> > - .args[0] = state,
> > - .args[1] = id,
> > - .owner = ARM_SMCCC_OWNER_SIP,
> > - };
> > - struct qcom_scm_res res;
> > - int ret;
> > -
> > - ret = qcom_scm_call(__scm->dev, &desc, &res);
> > -
> > - return ret ? : res.result[0];
> > -}
> > -EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
> > -
> > static int qcom_scm_disable_sdi(void)
> > {
> > int ret;
> > @@ -571,26 +554,12 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
> > dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
> > }
> >
> > -/**
> > - * devm_qcom_scm_pas_context_alloc() - Allocate peripheral authentication service
> > - * context for a given peripheral
> > - *
> > - * PAS context is device-resource managed, so the caller does not need
> > - * to worry about freeing the context memory.
> > - *
> > - * @dev: PAS firmware device
> > - * @pas_id: peripheral authentication service id
> > - * @mem_phys: Subsystem reserve memory start address
> > - * @mem_size: Subsystem reserve memory size
> > - *
> > - * Returns: The new PAS context, or ERR_PTR() on failure.
> > - */
> > struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
> > u32 pas_id,
> > phys_addr_t mem_phys,
> > size_t mem_size)
> > {
> > - struct qcom_scm_pas_context *ctx;
> > + struct qcom_pas_context *ctx;
>
> Why this change..
This is needed for migration to the generic PAS APIs as the internal
wrappers switched over. However, this is just a temporary global wrapper
until all the clients switch over..
>
> >
> > ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> > if (!ctx)
> > @@ -601,11 +570,12 @@ struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
> > ctx->mem_phys = mem_phys;
> > ctx->mem_size = mem_size;
> >
> > - return ctx;
> > + return (struct qcom_scm_pas_context *)ctx;
>
> and this change as well ?
..ditto as above to maintain API compatibility. This whole wrapper gets
dropped in the last patch.
>
> > }
> > EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc);
> >
> > -static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys,
> > +static int __qcom_scm_pas_init_image(struct device *dev, u32 pas_id,
> > + dma_addr_t mdata_phys,
> > struct qcom_scm_res *res)
> > {
> > struct qcom_scm_desc desc = {
> > @@ -627,7 +597,7 @@ static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys,
> >
> > desc.args[1] = mdata_phys;
> >
> > - ret = qcom_scm_call(__scm->dev, &desc, res);
> > + ret = qcom_scm_call(dev, &desc, res);
> > qcom_scm_bw_disable();
> >
> > disable_clk:
> > @@ -636,7 +606,8 @@ static int __qcom_scm_pas_init_image(u32 pas_id, dma_addr_t mdata_phys,
> > return ret;
> > }
> >
> > -static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_context *ctx,
> > +static int qcom_scm_pas_prep_and_init_image(struct device *dev,
> > + struct qcom_pas_context *ctx,
> > const void *metadata, size_t size)
> > {
> > struct qcom_scm_res res;
> > @@ -651,7 +622,7 @@ static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_context *ctx,
> > memcpy(mdata_buf, metadata, size);
> > mdata_phys = qcom_tzmem_to_phys(mdata_buf);
> >
> > - ret = __qcom_scm_pas_init_image(ctx->pas_id, mdata_phys, &res);
> > + ret = __qcom_scm_pas_init_image(dev, ctx->pas_id, mdata_phys, &res);
> > if (ret < 0)
> > qcom_tzmem_free(mdata_buf);
> > else
> > @@ -660,25 +631,9 @@ static int qcom_scm_pas_prep_and_init_image(struct qcom_scm_pas_context *ctx,
> > return ret ? : res.result[0];
> > }
> >
> > -/**
> > - * qcom_scm_pas_init_image() - Initialize peripheral authentication service
> > - * state machine for a given peripheral, using the
> > - * metadata
> > - * @pas_id: peripheral authentication service id
> > - * @metadata: pointer to memory containing ELF header, program header table
> > - * and optional blob of data used for authenticating the metadata
> > - * and the rest of the firmware
> > - * @size: size of the metadata
> > - * @ctx: optional pas context
> > - *
> > - * Return: 0 on success.
> > - *
> > - * Upon successful return, the PAS metadata context (@ctx) will be used to
> > - * track the metadata allocation, this needs to be released by invoking
> > - * qcom_scm_pas_metadata_release() by the caller.
> > - */
> > -int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > - struct qcom_scm_pas_context *ctx)
> > +static int __qcom_scm_pas_init_image2(struct device *dev, u32 pas_id,
> > + const void *metadata, size_t size,
> > + struct qcom_pas_context *ctx)
>
> Looks like alignment got wrong..
It isn't, try applying this patch-set and see if you still see any
alignment issues.
>
> > {
> > struct qcom_scm_res res;
> > dma_addr_t mdata_phys;
> > @@ -686,7 +641,8 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > int ret;
> >
> > if (ctx && ctx->use_tzmem)
> > - return qcom_scm_pas_prep_and_init_image(ctx, metadata, size);
> > + return qcom_scm_pas_prep_and_init_image(dev, ctx, metadata,
> > + size);
>
> unwrap this..
Ack.
>
> >
> > /*
> > * During the scm call memory protection will be enabled for the meta
> > @@ -700,16 +656,15 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > * If we pass a buffer that is already part of an SHM Bridge to this
> > * call, it will fail.
> > */
> > - mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
> > - GFP_KERNEL);
> > + mdata_buf = dma_alloc_coherent(dev, size, &mdata_phys, GFP_KERNEL);
> > if (!mdata_buf)
> > return -ENOMEM;
> >
> > memcpy(mdata_buf, metadata, size);
> >
> > - ret = __qcom_scm_pas_init_image(pas_id, mdata_phys, &res);
> > + ret = __qcom_scm_pas_init_image(dev, pas_id, mdata_phys, &res);
> > if (ret < 0 || !ctx) {
> > - dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
> > + dma_free_coherent(dev, size, mdata_buf, mdata_phys);
> > } else if (ctx) {
> > ctx->ptr = mdata_buf;
> > ctx->phys = mdata_phys;
> > @@ -718,36 +673,35 @@ int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> >
> > return ret ? : res.result[0];
> > }
> > -EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
> >
> > -/**
> > - * qcom_scm_pas_metadata_release() - release metadata context
> > - * @ctx: pas context
> > - */
> > -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
> > +int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
> > + struct qcom_scm_pas_context *ctx)
> > {
> > - if (!ctx->ptr)
> > - return;
> > + return __qcom_scm_pas_init_image2(__scm->dev, pas_id, metadata, size,
> > + (struct qcom_pas_context *)ctx);
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
> >
> > +static void __qcom_scm_pas_metadata_release(struct device *dev,
> > + struct qcom_pas_context *ctx)
> > +{
> > if (ctx->use_tzmem)
> > qcom_tzmem_free(ctx->ptr);
> > else
> > - dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
> > + dma_free_coherent(dev, ctx->size, ctx->ptr, ctx->phys);
> >
> > ctx->ptr = NULL;
> > }
> > +
> > +void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
> > +{
> > + __qcom_scm_pas_metadata_release(__scm->dev,
> > + (struct qcom_pas_context *)ctx);
> > +}
> > EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
> >
> > -/**
> > - * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
> > - * for firmware loading
> > - * @pas_id: peripheral authentication service id
> > - * @addr: start address of memory area to prepare
> > - * @size: size of the memory area to prepare
> > - *
> > - * Returns 0 on success.
> > - */
> > -int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
> > +static int __qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id,
> > + phys_addr_t addr, phys_addr_t size)
> > {
> > int ret;
> > struct qcom_scm_desc desc = {
> > @@ -769,7 +723,7 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
> > if (ret)
> > goto disable_clk;
> >
> > - ret = qcom_scm_call(__scm->dev, &desc, &res);
> > + ret = qcom_scm_call(dev, &desc, &res);
> > qcom_scm_bw_disable();
> >
> > disable_clk:
> > @@ -777,9 +731,15 @@ int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
> >
> > return ret ? : res.result[0];
> > }
> > +
> > +int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
> > +{
> > + return __qcom_scm_pas_mem_setup(__scm->dev, pas_id, addr, size);
> > +}
> > EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup);
> >
> > -static void *__qcom_scm_pas_get_rsc_table(u32 pas_id, void *input_rt_tzm,
> > +static void *__qcom_scm_pas_get_rsc_table(struct device *dev, u32 pas_id,
> > + void *input_rt_tzm,
> > size_t input_rt_size,
> > size_t *output_rt_size)
> > {
> > @@ -814,7 +774,7 @@ static void *__qcom_scm_pas_get_rsc_table(u32 pas_id, void *input_rt_tzm,
> > * with output_rt_tzm buffer with res.result[2] size however, It should not
> > * be of unresonable size.
> > */
> > - ret = qcom_scm_call(__scm->dev, &desc, &res);
> > + ret = qcom_scm_call(dev, &desc, &res);
> > if (!ret && res.result[2] > SZ_1G) {
> > ret = -E2BIG;
> > goto free_output_rt;
> > @@ -831,51 +791,11 @@ static void *__qcom_scm_pas_get_rsc_table(u32 pas_id, void *input_rt_tzm,
> > return ret ? ERR_PTR(ret) : output_rt_tzm;
> > }
> >
> > -/**
> > - * qcom_scm_pas_get_rsc_table() - Retrieve the resource table in passed output buffer
> > - * for a given peripheral.
> > - *
> > - * Qualcomm remote processor may rely on both static and dynamic resources for
> > - * its functionality. Static resources typically refer to memory-mapped addresses
> > - * required by the subsystem and are often embedded within the firmware binary
> > - * and dynamic resources, such as shared memory in DDR etc., are determined at
> > - * runtime during the boot process.
> > - *
> > - * On Qualcomm Technologies devices, it's possible that static resources are not
> > - * embedded in the firmware binary and instead are provided by TrustZone However,
> > - * dynamic resources are always expected to come from TrustZone. This indicates
> > - * that for Qualcomm devices, all resources (static and dynamic) will be provided
> > - * by TrustZone via the SMC call.
> > - *
> > - * If the remote processor firmware binary does contain static resources, they
> > - * should be passed in input_rt. These will be forwarded to TrustZone for
> > - * authentication. TrustZone will then append the dynamic resources and return
> > - * the complete resource table in output_rt_tzm.
> > - *
> > - * If the remote processor firmware binary does not include a resource table,
> > - * the caller of this function should set input_rt as NULL and input_rt_size
> > - * as zero respectively.
> > - *
> > - * More about documentation on resource table data structures can be found in
> > - * include/linux/remoteproc.h
> > - *
> > - * @ctx: PAS context
> > - * @pas_id: peripheral authentication service id
> > - * @input_rt: resource table buffer which is present in firmware binary
> > - * @input_rt_size: size of the resource table present in firmware binary
> > - * @output_rt_size: TrustZone expects caller should pass worst case size for
> > - * the output_rt_tzm.
> > - *
> > - * Return:
> > - * On success, returns a pointer to the allocated buffer containing the final
> > - * resource table and output_rt_size will have actual resource table size from
> > - * TrustZone. The caller is responsible for freeing the buffer. On failure,
> > - * returns ERR_PTR(-errno).
> > - */
> > -struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
> > - void *input_rt,
> > - size_t input_rt_size,
> > - size_t *output_rt_size)
> > +static void *__qcom_scm_pas_get_rsc_table2(struct device *dev,
> > + struct qcom_pas_context *ctx,
> > + void *input_rt,
> > + size_t input_rt_size,
> > + size_t *output_rt_size)
> > {
> > struct resource_table empty_rsc = {};
> > size_t size = SZ_16K;
> > @@ -910,11 +830,12 @@ struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *c
> >
> > memcpy(input_rt_tzm, input_rt, input_rt_size);
> >
> > - output_rt_tzm = __qcom_scm_pas_get_rsc_table(ctx->pas_id, input_rt_tzm,
> > + output_rt_tzm = __qcom_scm_pas_get_rsc_table(dev, ctx->pas_id,
> > + input_rt_tzm,
> > input_rt_size, &size);
> > if (PTR_ERR(output_rt_tzm) == -EOVERFLOW)
> > /* Try again with the size requested by the TZ */
> > - output_rt_tzm = __qcom_scm_pas_get_rsc_table(ctx->pas_id,
> > + output_rt_tzm = __qcom_scm_pas_get_rsc_table(dev, ctx->pas_id,
> > input_rt_tzm,
> > input_rt_size,
> > &size);
> > @@ -945,16 +866,20 @@ struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *c
> >
> > return ret ? ERR_PTR(ret) : tbl_ptr;
> > }
> > +
> > +struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
> > + void *input_rt,
> > + size_t input_rt_size,
> > + size_t *output_rt_size)
> > +{
> > + return __qcom_scm_pas_get_rsc_table2(__scm->dev,
>
> Instead of using integar, we could use addition of more '_' to reflect
> inner level functions..
Let me rather drop the integer as part of last patch when I am already
dropping wrappers.
>
> > + (struct qcom_pas_context *)ctx,
> > + input_rt, input_rt_size,
> > + output_rt_size);
> > +}
> > EXPORT_SYMBOL_GPL(qcom_scm_pas_get_rsc_table);
> >
> > -/**
> > - * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
> > - * and reset the remote processor
> > - * @pas_id: peripheral authentication service id
> > - *
> > - * Return 0 on success.
> > - */
> > -int qcom_scm_pas_auth_and_reset(u32 pas_id)
> > +static int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id)
> > {
> > int ret;
> > struct qcom_scm_desc desc = {
> > @@ -974,7 +899,7 @@ int qcom_scm_pas_auth_and_reset(u32 pas_id)
> > if (ret)
> > goto disable_clk;
> >
> > - ret = qcom_scm_call(__scm->dev, &desc, &res);
> > + ret = qcom_scm_call(dev, &desc, &res);
> > qcom_scm_bw_disable();
> >
> > disable_clk:
> > @@ -982,28 +907,15 @@ int qcom_scm_pas_auth_and_reset(u32 pas_id)
> >
> > return ret ? : res.result[0];
> > }
> > +
> > +int qcom_scm_pas_auth_and_reset(u32 pas_id)
> > +{
> > + return __qcom_scm_pas_auth_and_reset(__scm->dev, 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)
> > +static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
> > + struct qcom_pas_context *ctx)
> > {
> > u64 handle;
> > int ret;
> > @@ -1014,7 +926,7 @@ int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx)
> > * 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);
> > + return __qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
> >
> > /*
> > * When Linux runs @ EL2 Linux must create the shmbridge itself and then
> > @@ -1024,20 +936,45 @@ int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx)
> > if (ret)
> > return ret;
> >
> > - ret = qcom_scm_pas_auth_and_reset(ctx->pas_id);
> > + ret = __qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
> > qcom_tzmem_shm_bridge_delete(handle);
> >
> > return ret;
> > }
> > +
> > +int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx)
> > +{
> > + return __qcom_scm_pas_prepare_and_auth_reset(__scm->dev,
> > + (struct qcom_pas_context *)ctx);
> > +}
> > 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
> > - *
> > - * Returns 0 on success.
> > - */
> > -int qcom_scm_pas_shutdown(u32 pas_id)
> > +static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
> > + u32 pas_id)
> > +{
> > + struct qcom_scm_desc desc = {
> > + .svc = QCOM_SCM_SVC_BOOT,
> > + .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE,
> > + .arginfo = QCOM_SCM_ARGS(2),
> > + .args[0] = state,
> > + .args[1] = pas_id,
> > + .owner = ARM_SMCCC_OWNER_SIP,
> > + };
> > + struct qcom_scm_res res;
> > + int ret;
> > +
> > + ret = qcom_scm_call(dev, &desc, &res);
> > +
> > + return ret ? : res.result[0];
> > +}
> > +
> > +int qcom_scm_set_remote_state(u32 state, u32 id)
> > +{
> > + return __qcom_scm_pas_set_remote_state(__scm->dev, state, id);
> > +}
> > +EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
> > +
> > +static int __qcom_scm_pas_shutdown(struct device *dev, u32 pas_id)
> > {
> > int ret;
> > struct qcom_scm_desc desc = {
> > @@ -1057,7 +994,7 @@ int qcom_scm_pas_shutdown(u32 pas_id)
> > if (ret)
> > goto disable_clk;
> >
> > - ret = qcom_scm_call(__scm->dev, &desc, &res);
> > + ret = qcom_scm_call(dev, &desc, &res);
> > qcom_scm_bw_disable();
> >
> > disable_clk:
> > @@ -1065,16 +1002,14 @@ int qcom_scm_pas_shutdown(u32 pas_id)
> >
> > return ret ? : res.result[0];
> > }
> > +
> > +int qcom_scm_pas_shutdown(u32 pas_id)
> > +{
> > + return __qcom_scm_pas_shutdown(__scm->dev, pas_id);
> > +}
> > EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown);
> >
> > -/**
> > - * qcom_scm_pas_supported() - Check if the peripheral authentication service is
> > - * available for the given peripherial
> > - * @pas_id: peripheral authentication service id
> > - *
> > - * Returns true if PAS is supported for this peripheral, otherwise false.
> > - */
> > -bool qcom_scm_pas_supported(u32 pas_id)
> > +static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id)
> > {
> > int ret;
> > struct qcom_scm_desc desc = {
> > @@ -1086,16 +1021,49 @@ bool qcom_scm_pas_supported(u32 pas_id)
> > };
> > struct qcom_scm_res res;
> >
> > - if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL,
> > + if (!__qcom_scm_is_call_available(dev, QCOM_SCM_SVC_PIL,
> > QCOM_SCM_PIL_PAS_IS_SUPPORTED))
> > return false;
> >
> > - ret = qcom_scm_call(__scm->dev, &desc, &res);
> > + ret = qcom_scm_call(dev, &desc, &res);
> >
> > return ret ? false : !!res.result[0];
> > }
> > +
> > +bool qcom_scm_pas_supported(u32 pas_id)
> > +{
> > + return __qcom_scm_pas_supported(__scm->dev, pas_id);
> > +}
> > EXPORT_SYMBOL_GPL(qcom_scm_pas_supported);
> >
> > +static struct qcom_pas_ops qcom_pas_ops_scm = {
> > + .drv_name = "qcom_scm",
> > + .supported = __qcom_scm_pas_supported,
> > + .init_image = __qcom_scm_pas_init_image2,
> > + .mem_setup = __qcom_scm_pas_mem_setup,
> > + .get_rsc_table = __qcom_scm_pas_get_rsc_table2,
> > + .auth_and_reset = __qcom_scm_pas_auth_and_reset,
> > + .prepare_and_auth_reset = __qcom_scm_pas_prepare_and_auth_reset,
> > + .set_remote_state = __qcom_scm_pas_set_remote_state,
> > + .shutdown = __qcom_scm_pas_shutdown,
> > + .metadata_release = __qcom_scm_pas_metadata_release,
> > +};
> > +
> > +/**
> > + * qcom_scm_is_pas_available() - Check if the peripheral authentication service
> > + * is available via SCM or not
> > + *
> > + * Returns true if PAS is available, otherwise false.
> > + */
> > +static bool qcom_scm_is_pas_available(void)
> > +{
> > + if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL,
> > + QCOM_SCM_PIL_PAS_AUTH_AND_RESET))
> > + return false;
> > +
> > + return true;
> > +}
> > +
> > static int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
> > {
> > struct qcom_scm_desc desc = {
> > @@ -2782,6 +2750,11 @@ static int qcom_scm_probe(struct platform_device *pdev)
> >
> > __get_convention();
> >
> > + if (qcom_scm_is_pas_available()) {
> > + qcom_pas_ops_scm.dev = scm->dev;
> > + qcom_pas_ops_register(&qcom_pas_ops_scm);
> > + }
> > +
> > /*
> > * If "download mode" is requested, from this point on warmboot
> > * will cause the boot stages to enter download mode, unless
> > @@ -2818,6 +2791,7 @@ static void qcom_scm_shutdown(struct platform_device *pdev)
> > {
> > /* Clean shutdown, disable download mode to allow normal restart */
> > qcom_scm_set_download_mode(QCOM_DLOAD_NODUMP);
> > + qcom_pas_ops_unregister();
> > }
> >
> > static const struct of_device_id qcom_scm_dt_match[] = {
> > --
> > 2.51.0
> >
>
> nit: please double check the alignment due to name and 'static' addition
> to the function..
Alignment is fine, it doesn't show appropriately on the plain text
emails.
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 04/15] firmware: qcom: Add a PAS TEE service
[not found] ` <20260313110747.v5bx2snpbtyja3ur@hu-mojha-hyd.qualcomm.com>
@ 2026-03-23 13:38 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-23 13:38 UTC (permalink / raw)
To: Mukesh Ojha
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
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
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
2026-03-23 13:22 ` Sumit Garg
@ 2026-03-23 14:19 ` Krzysztof Kozlowski
2026-03-23 14:26 ` Konrad Dybcio
0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-23 14:19 UTC (permalink / raw)
To: Sumit Garg
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
linux-kernel, Sumit Garg
On 23/03/2026 14:22, Sumit Garg wrote:
> On Mon, Mar 16, 2026 at 08:51:16AM +0100, Krzysztof Kozlowski wrote:
>> On 12/03/2026 07:27, Sumit Garg wrote:
>>> From: Sumit Garg <sumit.garg@oss.qualcomm.com>
>>>
>>> Qcom platforms has the legacy of using non-standard SCM calls
>>> splintered over the various kernel drivers. These SCM calls aren't
>>> compliant with the standard SMC calling conventions which is a
>>> prerequisite to enable migration to the FF-A specifications from Arm.
>>>
>>> OP-TEE as an alternative trusted OS to Qualcomm TEE (QTEE) can't
>>> support these non-standard SCM calls. And even for newer architectures
>>> with S-EL2 and Hafnium support, QTEE won't be able to support SCM
>>> calls either with FF-A requirements coming in. And with both OP-TEE
>>> and QTEE drivers well integrated in the TEE subsystem, it makes further
>>> sense to reuse the TEE bus client drivers infrastructure.
>>>
>>> The added benefit of TEE bus infrastructure is that there is support
>>> for discoverable/enumerable services. With that client drivers don't
>>> have to manually invoke a special SCM call to know the service status.
>>>
>>> So enable the generic Peripheral Authentication Service (PAS) provided
>>> by the firmware. It acts as the common layer with different TZ
>>> backends plugged in whether it's an SCM implementation or a proper
>>> TEE bus based PAS service implementation.
>>>
>>> Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
>>> ---
>>> drivers/firmware/qcom/Kconfig | 8 +
>>> drivers/firmware/qcom/Makefile | 1 +
>>> drivers/firmware/qcom/qcom_pas.c | 298 +++++++++++++++++++++++++
>>> drivers/firmware/qcom/qcom_pas.h | 53 +++++
>>> include/linux/firmware/qcom/qcom_pas.h | 41 ++++
>>> 5 files changed, 401 insertions(+)
>>> create mode 100644 drivers/firmware/qcom/qcom_pas.c
>>> create mode 100644 drivers/firmware/qcom/qcom_pas.h
>>> create mode 100644 include/linux/firmware/qcom/qcom_pas.h
>>>
>>> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
>>> index b477d54b495a..8653639d06db 100644
>>> --- a/drivers/firmware/qcom/Kconfig
>>> +++ b/drivers/firmware/qcom/Kconfig
>>> @@ -6,6 +6,14 @@
>>>
>>> menu "Qualcomm firmware drivers"
>>>
>>> +config QCOM_PAS
>>> + tristate
>>> + help
>>> + Enable the generic Peripheral Authentication Service (PAS) provided
>>> + by the firmware. It acts as the common layer with different TZ
>>> + backends plugged in whether it's an SCM implementation or a proper
>>> + TEE bus based PAS service implementation.
>>> +
>>> config QCOM_SCM
>>> select QCOM_TZMEM
>>> tristate
>>> diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
>>> index 0be40a1abc13..dc5ab45f906a 100644
>>> --- a/drivers/firmware/qcom/Makefile
>>> +++ b/drivers/firmware/qcom/Makefile
>>> @@ -8,3 +8,4 @@ qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
>>> 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
>>> diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
>>> new file mode 100644
>>> index 000000000000..beb1bae55546
>>> --- /dev/null
>>> +++ b/drivers/firmware/qcom/qcom_pas.c
>>> @@ -0,0 +1,298 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>>> + */
>>> +
>>> +#include <linux/device/devres.h>
>>> +#include <linux/firmware/qcom/qcom_pas.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/module.h>
>>> +
>>> +#include "qcom_pas.h"
>>> +
>>> +struct qcom_pas_ops *ops_ptr;
>>
>> Same comment as before. Don't create singletons. And for sure not global
>> ones.
>
> This pattern has been carried from the PAS API contract among kernel
> clients and the SCM PAS service earlier. The clients don't hold a
> reference to the PAS data like underlying platform or TEE device etc.
> Hence the need to have a global data pointer to hold reference to the
> ops data structure registered by drivers having different lifetime of
> devices. Also, the PAS APIs can be called from very different client
> driver contexts.
>
> Surely, avoiding global data is always better given a better alternative
> is there. Do you have any better alternative proposal here?
Why it cannot be part of the context?
Look at your API, e.g.:
qcom_pas_init_image(). It takes struct qcom_pas_context which should
contain the ops.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
2026-03-23 14:19 ` Krzysztof Kozlowski
@ 2026-03-23 14:26 ` Konrad Dybcio
2026-03-27 13:56 ` Krzysztof Kozlowski
0 siblings, 1 reply; 16+ messages in thread
From: Konrad Dybcio @ 2026-03-23 14:26 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sumit Garg
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
linux-kernel, Sumit Garg
On 3/23/26 3:19 PM, Krzysztof Kozlowski wrote:
> On 23/03/2026 14:22, Sumit Garg wrote:
>> On Mon, Mar 16, 2026 at 08:51:16AM +0100, Krzysztof Kozlowski wrote:
>>> On 12/03/2026 07:27, Sumit Garg wrote:
>>>> From: Sumit Garg <sumit.garg@oss.qualcomm.com>
>>>>
>>>> Qcom platforms has the legacy of using non-standard SCM calls
>>>> splintered over the various kernel drivers. These SCM calls aren't
>>>> compliant with the standard SMC calling conventions which is a
>>>> prerequisite to enable migration to the FF-A specifications from Arm.
>>>>
>>>> OP-TEE as an alternative trusted OS to Qualcomm TEE (QTEE) can't
>>>> support these non-standard SCM calls. And even for newer architectures
>>>> with S-EL2 and Hafnium support, QTEE won't be able to support SCM
>>>> calls either with FF-A requirements coming in. And with both OP-TEE
>>>> and QTEE drivers well integrated in the TEE subsystem, it makes further
>>>> sense to reuse the TEE bus client drivers infrastructure.
>>>>
>>>> The added benefit of TEE bus infrastructure is that there is support
>>>> for discoverable/enumerable services. With that client drivers don't
>>>> have to manually invoke a special SCM call to know the service status.
>>>>
>>>> So enable the generic Peripheral Authentication Service (PAS) provided
>>>> by the firmware. It acts as the common layer with different TZ
>>>> backends plugged in whether it's an SCM implementation or a proper
>>>> TEE bus based PAS service implementation.
>>>>
>>>> Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
>>>> ---
>>>> drivers/firmware/qcom/Kconfig | 8 +
>>>> drivers/firmware/qcom/Makefile | 1 +
>>>> drivers/firmware/qcom/qcom_pas.c | 298 +++++++++++++++++++++++++
>>>> drivers/firmware/qcom/qcom_pas.h | 53 +++++
>>>> include/linux/firmware/qcom/qcom_pas.h | 41 ++++
>>>> 5 files changed, 401 insertions(+)
>>>> create mode 100644 drivers/firmware/qcom/qcom_pas.c
>>>> create mode 100644 drivers/firmware/qcom/qcom_pas.h
>>>> create mode 100644 include/linux/firmware/qcom/qcom_pas.h
>>>>
>>>> diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig
>>>> index b477d54b495a..8653639d06db 100644
>>>> --- a/drivers/firmware/qcom/Kconfig
>>>> +++ b/drivers/firmware/qcom/Kconfig
>>>> @@ -6,6 +6,14 @@
>>>>
>>>> menu "Qualcomm firmware drivers"
>>>>
>>>> +config QCOM_PAS
>>>> + tristate
>>>> + help
>>>> + Enable the generic Peripheral Authentication Service (PAS) provided
>>>> + by the firmware. It acts as the common layer with different TZ
>>>> + backends plugged in whether it's an SCM implementation or a proper
>>>> + TEE bus based PAS service implementation.
>>>> +
>>>> config QCOM_SCM
>>>> select QCOM_TZMEM
>>>> tristate
>>>> diff --git a/drivers/firmware/qcom/Makefile b/drivers/firmware/qcom/Makefile
>>>> index 0be40a1abc13..dc5ab45f906a 100644
>>>> --- a/drivers/firmware/qcom/Makefile
>>>> +++ b/drivers/firmware/qcom/Makefile
>>>> @@ -8,3 +8,4 @@ qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
>>>> 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
>>>> diff --git a/drivers/firmware/qcom/qcom_pas.c b/drivers/firmware/qcom/qcom_pas.c
>>>> new file mode 100644
>>>> index 000000000000..beb1bae55546
>>>> --- /dev/null
>>>> +++ b/drivers/firmware/qcom/qcom_pas.c
>>>> @@ -0,0 +1,298 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>> +/*
>>>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>>>> + */
>>>> +
>>>> +#include <linux/device/devres.h>
>>>> +#include <linux/firmware/qcom/qcom_pas.h>
>>>> +#include <linux/kernel.h>
>>>> +#include <linux/module.h>
>>>> +
>>>> +#include "qcom_pas.h"
>>>> +
>>>> +struct qcom_pas_ops *ops_ptr;
>>>
>>> Same comment as before. Don't create singletons. And for sure not global
>>> ones.
>>
>> This pattern has been carried from the PAS API contract among kernel
>> clients and the SCM PAS service earlier. The clients don't hold a
>> reference to the PAS data like underlying platform or TEE device etc.
>> Hence the need to have a global data pointer to hold reference to the
>> ops data structure registered by drivers having different lifetime of
>> devices. Also, the PAS APIs can be called from very different client
>> driver contexts.
>>
>> Surely, avoiding global data is always better given a better alternative
>> is there. Do you have any better alternative proposal here?
>
> Why it cannot be part of the context?
>
> Look at your API, e.g.:
> qcom_pas_init_image(). It takes struct qcom_pas_context which should
> contain the ops.
This would make the client have to select the ops. The whole point is to
avoid that, since the client has no clue (and is supposed not to have any).
What Sumit does is to bind the ops based on the runtime-discovered
mechanism (which needs to only happen once, given we're not replacing the
TZ at runtime)
Konrad
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 03/15] firmware: qcom_scm: Migrate to generic PAS service
[not found] ` <20260312062756.694390-4-sumit.garg@kernel.org>
[not found] ` <20260313075607.2mw3dzaf274xxe2j@hu-mojha-hyd.qualcomm.com>
@ 2026-03-27 12:10 ` Harshal Dev
2026-03-27 12:18 ` Sumit Garg
1 sibling, 1 reply; 16+ messages in thread
From: Harshal Dev @ 2026-03-27 12:10 UTC (permalink / raw)
To: Sumit Garg, linux-arm-msm, devicetree, dri-devel, freedreno,
linux-media, netdev, linux-wireless, ath12k, linux-remoteproc
Cc: andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
linux-kernel, Sumit Garg
On 3/12/2026 11:57 AM, Sumit Garg wrote:
> From: Sumit Garg <sumit.garg@oss.qualcomm.com>
>
> With the availability of generic PAS service, let's add SCM calls as
> a backend to keep supporting legacy QTEE interfaces. The exported
> qcom_scm* wrappers will get dropped once all the client drivers get
> migrated as part of future patches.
>
> Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> ---
> drivers/firmware/qcom/Kconfig | 1 +
> drivers/firmware/qcom/qcom_scm.c | 336 ++++++++++++++-----------------
> 2 files changed, 156 insertions(+), 181 deletions(-)
>
[..]
> diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> index 8fbc96693a55..2d7937ae7c8f 100644
> --- a/drivers/firmware/qcom/qcom_scm.c
> +++ b/drivers/firmware/qcom/qcom_scm.c
> @@ -13,6 +13,7 @@
> #include <linux/dma-mapping.h>
[..]
>
> -/**
> - * devm_qcom_scm_pas_context_alloc() - Allocate peripheral authentication service
> - * context for a given peripheral
> - *
> - * PAS context is device-resource managed, so the caller does not need
> - * to worry about freeing the context memory.
> - *
> - * @dev: PAS firmware device
> - * @pas_id: peripheral authentication service id
> - * @mem_phys: Subsystem reserve memory start address
> - * @mem_size: Subsystem reserve memory size
> - *
> - * Returns: The new PAS context, or ERR_PTR() on failure.
> - */
Shouldn't we drop the documentation for the exported functions in this file as part of
patch 14/15? After this patch is applied, the devm_qcom_scm_pas_context_alloc() function
still remains exported and available.
Regards,
Harshal
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 03/15] firmware: qcom_scm: Migrate to generic PAS service
2026-03-27 12:10 ` Harshal Dev
@ 2026-03-27 12:18 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-27 12:18 UTC (permalink / raw)
To: Harshal Dev
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
linux-kernel, Sumit Garg
On Fri, Mar 27, 2026 at 05:40:16PM +0530, Harshal Dev wrote:
>
>
> On 3/12/2026 11:57 AM, Sumit Garg wrote:
> > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> >
> > With the availability of generic PAS service, let's add SCM calls as
> > a backend to keep supporting legacy QTEE interfaces. The exported
> > qcom_scm* wrappers will get dropped once all the client drivers get
> > migrated as part of future patches.
> >
> > Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > ---
> > drivers/firmware/qcom/Kconfig | 1 +
> > drivers/firmware/qcom/qcom_scm.c | 336 ++++++++++++++-----------------
> > 2 files changed, 156 insertions(+), 181 deletions(-)
> >
>
> [..]
>
> > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
> > index 8fbc96693a55..2d7937ae7c8f 100644
> > --- a/drivers/firmware/qcom/qcom_scm.c
> > +++ b/drivers/firmware/qcom/qcom_scm.c
> > @@ -13,6 +13,7 @@
> > #include <linux/dma-mapping.h>
>
> [..]
>
> >
> > -/**
> > - * devm_qcom_scm_pas_context_alloc() - Allocate peripheral authentication service
> > - * context for a given peripheral
> > - *
> > - * PAS context is device-resource managed, so the caller does not need
> > - * to worry about freeing the context memory.
> > - *
> > - * @dev: PAS firmware device
> > - * @pas_id: peripheral authentication service id
> > - * @mem_phys: Subsystem reserve memory start address
> > - * @mem_size: Subsystem reserve memory size
> > - *
> > - * Returns: The new PAS context, or ERR_PTR() on failure.
> > - */
>
> Shouldn't we drop the documentation for the exported functions in this file as part of
> patch 14/15? After this patch is applied, the devm_qcom_scm_pas_context_alloc() function
> still remains exported and available.
I don't see value in maintaining redundant documentation during the
course of the patch-set. The wrappers are only maintained to keep the
individual commits compilable such that we don't break kernel git
bisection scripts.
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
2026-03-23 12:50 ` [PATCH v2 02/15] firmware: qcom: Add a generic PAS service Sumit Garg
@ 2026-03-27 13:39 ` Krzysztof Kozlowski
2026-03-30 6:29 ` Sumit Garg
0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-27 13:39 UTC (permalink / raw)
To: Sumit Garg, Mukesh Ojha
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
On 23/03/2026 13:50, Sumit Garg wrote:
>>> +
>>> +#include <linux/device/devres.h>
>>> +#include <linux/firmware/qcom/qcom_pas.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/module.h>
>>> +
>>> +#include "qcom_pas.h"
>>> +
>>> +struct qcom_pas_ops *ops_ptr;
>>
>> Should this be static ?
>
> It was static earlier in v1. I dropped it based on earlier v1 discussion
> with Krzysztof. Let me conclude that discussion on the other thread
> again.
The discussion was whether this should be singleton in the first place,
not making it a global singleton.
Of course it cannot be anything else than static - nothing should poke here.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
2026-03-23 14:26 ` Konrad Dybcio
@ 2026-03-27 13:56 ` Krzysztof Kozlowski
2026-03-30 7:08 ` Sumit Garg
0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-27 13:56 UTC (permalink / raw)
To: Konrad Dybcio, Sumit Garg
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
linux-kernel, Sumit Garg
On 23/03/2026 15:26, Konrad Dybcio wrote:
>>>
>>> This pattern has been carried from the PAS API contract among kernel
>>> clients and the SCM PAS service earlier. The clients don't hold a
>>> reference to the PAS data like underlying platform or TEE device etc.
>>> Hence the need to have a global data pointer to hold reference to the
>>> ops data structure registered by drivers having different lifetime of
>>> devices. Also, the PAS APIs can be called from very different client
>>> driver contexts.
>>>
>>> Surely, avoiding global data is always better given a better alternative
>>> is there. Do you have any better alternative proposal here?
>>
>> Why it cannot be part of the context?
>>
>> Look at your API, e.g.:
>> qcom_pas_init_image(). It takes struct qcom_pas_context which should
>> contain the ops.
>
> This would make the client have to select the ops. The whole point is to
> avoid that, since the client has no clue (and is supposed not to have any).
Yeah, I see. The problem is that this patchset just keeps growing the
singletons so except existing 'struct qcom_scm *__scm' in qcom_scm.c,
this one brings at least three new: 'ops_ptr', 'qcom_pas_ops_scm' and
'qcom_pas_ops_tee'.
I don't think you need all four in total, but only one which will hold
whatever pointers are necessary.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
2026-03-27 13:39 ` Krzysztof Kozlowski
@ 2026-03-30 6:29 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-30 6:29 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Mukesh Ojha, linux-arm-msm, devicetree, dri-devel, freedreno,
linux-media, netdev, linux-wireless, ath12k, linux-remoteproc,
andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
On Fri, Mar 27, 2026 at 02:39:24PM +0100, Krzysztof Kozlowski wrote:
> On 23/03/2026 13:50, Sumit Garg wrote:
> >>> +
> >>> +#include <linux/device/devres.h>
> >>> +#include <linux/firmware/qcom/qcom_pas.h>
> >>> +#include <linux/kernel.h>
> >>> +#include <linux/module.h>
> >>> +
> >>> +#include "qcom_pas.h"
> >>> +
> >>> +struct qcom_pas_ops *ops_ptr;
> >>
> >> Should this be static ?
> >
> > It was static earlier in v1. I dropped it based on earlier v1 discussion
> > with Krzysztof. Let me conclude that discussion on the other thread
> > again.
>
> The discussion was whether this should be singleton in the first place,
> not making it a global singleton.
>
> Of course it cannot be anything else than static - nothing should poke here.
Sure, I have put the static back for v3.
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 02/15] firmware: qcom: Add a generic PAS service
2026-03-27 13:56 ` Krzysztof Kozlowski
@ 2026-03-30 7:08 ` Sumit Garg
0 siblings, 0 replies; 16+ messages in thread
From: Sumit Garg @ 2026-03-30 7:08 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Konrad Dybcio, linux-arm-msm, devicetree, dri-devel, freedreno,
linux-media, netdev, linux-wireless, ath12k, linux-remoteproc,
andersson, konradybcio, robh, krzk+dt, conor+dt, robin.clark,
sean, akhilpo, lumag, abhinav.kumar, jesszhan0024, marijn.suijten,
airlied, simona, vikash.garodia, dikshita.agarwal, bod, mchehab,
elder, andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
linux-kernel, Sumit Garg
On Fri, Mar 27, 2026 at 02:56:40PM +0100, Krzysztof Kozlowski wrote:
> On 23/03/2026 15:26, Konrad Dybcio wrote:
> >>>
> >>> This pattern has been carried from the PAS API contract among kernel
> >>> clients and the SCM PAS service earlier. The clients don't hold a
> >>> reference to the PAS data like underlying platform or TEE device etc.
> >>> Hence the need to have a global data pointer to hold reference to the
> >>> ops data structure registered by drivers having different lifetime of
> >>> devices. Also, the PAS APIs can be called from very different client
> >>> driver contexts.
> >>>
> >>> Surely, avoiding global data is always better given a better alternative
> >>> is there. Do you have any better alternative proposal here?
> >>
> >> Why it cannot be part of the context?
> >>
> >> Look at your API, e.g.:
> >> qcom_pas_init_image(). It takes struct qcom_pas_context which should
> >> contain the ops.
Have a look at all other PAS client APIs, the context isn't something
that each client takes a reference and pass it on for every PAS
invocation. And changing the PAS API contract for kernel clients is out
of scope of this patch-set.
> >
> > This would make the client have to select the ops. The whole point is to
> > avoid that, since the client has no clue (and is supposed not to have any).
>
> Yeah, I see. The problem is that this patchset just keeps growing the
> singletons so except existing 'struct qcom_scm *__scm' in qcom_scm.c,
> this one brings at least three new: 'ops_ptr', 'qcom_pas_ops_scm' and
> 'qcom_pas_ops_tee'.
Not sure how you equate ops structure __pointer__ to the ops structure
itself. Can you enlighten me how in the rest of the kernel ops data
structures are shared among independent modules registering on different
bus types?
>
> I don't think you need all four in total, but only one which will hold
> whatever pointers are necessary.
Your arguments seems to be in favour of the existing monolithic SCM
driver design but you need to understand that's not how underlying TZ
services are implemented. The PAS service in TZ has nothing to do with
the ICE service for inline crypto as an example.
Please go through the motivation of this patch-set and the corresponding
OP-TEE implementation as TZ which is all open source.
-Sumit
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-03-30 7:08 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260312062756.694390-1-sumit.garg@kernel.org>
[not found] ` <20260312062756.694390-2-sumit.garg@kernel.org>
[not found] ` <20260313060451.hswg6snnnexchmzs@hu-mojha-hyd.qualcomm.com>
2026-03-23 12:35 ` [PATCH v2 01/15] arm64: dts: qcom: kodiak: Add EL2 overlay Sumit Garg
[not found] ` <20260312062756.694390-3-sumit.garg@kernel.org>
[not found] ` <20260313072450.sx7vqtvh62nflhff@hu-mojha-hyd.qualcomm.com>
2026-03-23 12:50 ` [PATCH v2 02/15] firmware: qcom: Add a generic PAS service Sumit Garg
2026-03-27 13:39 ` Krzysztof Kozlowski
2026-03-30 6:29 ` Sumit Garg
[not found] ` <20260313073121.qb7yq7tcga3sshcr@hu-mojha-hyd.qualcomm.com>
2026-03-23 12:55 ` Sumit Garg
[not found] ` <20260313075948.nbopdkctdcvzlj3f@hu-mojha-hyd.qualcomm.com>
2026-03-23 13:01 ` Sumit Garg
[not found] ` <124f5a78-a3be-4906-bea0-a82bb74b2f96@oss.qualcomm.com>
2026-03-23 13:12 ` Sumit Garg
[not found] ` <28d63822-f191-400a-8005-5185dd480dbb@kernel.org>
2026-03-23 13:22 ` Sumit Garg
2026-03-23 14:19 ` Krzysztof Kozlowski
2026-03-23 14:26 ` Konrad Dybcio
2026-03-27 13:56 ` Krzysztof Kozlowski
2026-03-30 7:08 ` Sumit Garg
[not found] ` <20260312062756.694390-5-sumit.garg@kernel.org>
[not found] ` <20260313110747.v5bx2snpbtyja3ur@hu-mojha-hyd.qualcomm.com>
2026-03-23 13:38 ` [PATCH v2 04/15] firmware: qcom: Add a PAS TEE service Sumit Garg
[not found] ` <20260312062756.694390-4-sumit.garg@kernel.org>
[not found] ` <20260313075607.2mw3dzaf274xxe2j@hu-mojha-hyd.qualcomm.com>
2026-03-23 13:33 ` [PATCH v2 03/15] firmware: qcom_scm: Migrate to generic PAS service Sumit Garg
2026-03-27 12:10 ` Harshal Dev
2026-03-27 12:18 ` Sumit Garg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox