From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 42740349B0D for ; Wed, 29 Apr 2026 13:20:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777468842; cv=none; b=ftMJHlrPs/Q+pdZ2nv8rhi7BVDhhUFzunmhWPBVB2RSLdD6lb0HIvVvSO2YZ/QZl0hOvL/zYhvLGTzIgKZKIuTbOFuxUdt32X4eG/HiKFGqDttGH9u7kwQEU/hf0O0xwp58G1OjVMo0b87P7e6UX5RcvPGs3yPYeWm9mxmQbSSI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777468842; c=relaxed/simple; bh=K9SziZwg2cg6hFbGZntKPnTumWR+tSXth0HI677R5sU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=FjQGsVuso1+bjqTEQWkeAsXQFV7Gd7FwcYkV6GPaJ6AklcBk5YlTzd9RtgvTkTFnTn//yl2hcWd6T/XeCjXlciwVfRiNgI82cmiJnRuI1qXUKUjvaM5iclIv0KeA4hS8cKMLFTBrSqY2fMnevAQQLykaL0MK+lQrI28iJnugiOw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=MpzMTZQN; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=kmoEK87O; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="MpzMTZQN"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="kmoEK87O" Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63T8qchV870134 for ; Wed, 29 Apr 2026 13:20:39 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=helEobTcZ3+WqP3KRmH5fips MFY/APaVYYJ+NFxCwsc=; b=MpzMTZQNb86sTF07AiqH/nkpLUkY4jGNjNCCekiR 2F3lTRcf4LUhSYqCaGXyJSDops2MpH3hE94J5UTL3eTvZH702UNURHxKCkYz+qo9 f5XB+VtPssFImppRrpuY39ObjH+ykdPv0SeRkpu5grOK99gwYnfunAVeHQgSsISl 0/i4TSW1EIpmPTHHuw/JTUig82EtiP4i4B4tTKXZQjgTjx2+hL3pxcR2mezcMvCk IGT1ikpLw4y8g2XKFwbLYlqoOyBt+A63FOGXPf4rWwaQ+qnto0vi9Q1HUTRGtqNS egmgHjdignnFQoA2WiuDIaLO7BcWCP3IKfqwfqwt6S8jDg== Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4du0u1v211-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 29 Apr 2026 13:20:39 +0000 (GMT) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-2b2d0c1ead1so225977985ad.0 for ; Wed, 29 Apr 2026 06:20:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1777468839; x=1778073639; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=helEobTcZ3+WqP3KRmH5fipsMFY/APaVYYJ+NFxCwsc=; b=kmoEK87OB1aPejzY3rYWbDlgzUIABonFdnI8o3wN8+kIgQaoRwiKtLHClnvggxplc4 TKeTnCO16HRMp61YjS5qUItxGXwbQo/74NpcbFSdmd+2rbMMpFlDuyqR6I/8Rg0ZCcnJ 7iHLXxOXUdEjUbXthsxgezipIPGWQYG5cxnusOnTfbUd2GZJJBiYSwYy5bH03b0qkw41 a2Ye4CXsQREoA0wCdfq2vG87EXBzw2vWEG/QNCiGdrvgDQy4HY1InX/lXsSp3bLcXM1Z mey7GUqc9QlKbXoMc02R8+1MnfSSTeQh/1uxiVBJ3V/Vg5GU+OehTjJuyROEXip7+4Qc ZOYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777468839; x=1778073639; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=helEobTcZ3+WqP3KRmH5fipsMFY/APaVYYJ+NFxCwsc=; b=Q1HM8ZsTxM7dxnmA6IDxbPXx/0DRXmGTz/foq9k6xfltopuQFLeEaLUG6cxkEuoCVd Ew02RAYjbFTlUwR/fXl5iQmRyy0GkNcn4fAJGVs1cqtIZO9HjIrCrZWHUCyqtqShn92f kxFJF2fHut9XJBMy08pFxxwiV3eJdPx9v5WFstd2MgH8s+5WmCHzEty51z6mYjISQqAq ifoAuoqRFVff8bHYVdnuu2jZKjdKDezgC11xHKkRO6hcVJSsOuyWkww+p3+dHPD3/Po2 6iobhPamOJ1VZkfiOHS+8Ee4SXOjmYm2wv2IG6T3VND3XEeeRtqo6fYUV1Dgy7vXlYgA /2QA== X-Forwarded-Encrypted: i=1; AFNElJ9iAkSv8f2ld73tPqlE5cYyEOAx7Miqx7wCisWy79couNDP9ItBO+cupKbukbSmtDLwyjjjsyc=@vger.kernel.org X-Gm-Message-State: AOJu0Yxc/0F0Bea0RtZhDxMWyIVJt2AmC/5Z4Jqd49iHlM0Q7TnY8UTm DX2A/rYo95lY8ox9Nr8WfWM/wcj63NsVchglwRuJ7DtNRwTelzYtSRYtGenxc3a9yuSCu+rkJv1 ex6WXTDr30oOSrSNsb876cm/4d2Gjtf2/grlvKX8juusdDEa78U/rORoN/H0= X-Gm-Gg: AeBDiesuhiVODS/1CYV5yIxJaaLyUnTDCaCNVf3FKao5o8y8Wrc3md/EVB84769HRWi TqGce7CJMm1WkkuiqMm4HTRzOyHWmJz/khS6O940YRKrwefjf7PxBKzWGiLUkBvB2OpIqum8boB d/KCW5lBU6O9U03yusPKAzIFwWu1t7kf0wb0uh21BX41PDy4YltKP8Xrn637JI+dH9KggNM3qU9 Wi52tmYkJFealvSpVWwKjb5QDHIpSSUKUcrTMo05PpSp9mDthEYeQnSwes9wGdLZhdO488f+91R HyOOxdUHcs0wEIO9cLJ39GVqSeS93GTPfz8sx3yzvHftlG0bPJ/R/tEhjYQZqSTUNgLYFj3YrzD Pe+t/JBzNn8C+/Xhu0KohXoww0S9Ex2b4I80FTCVUEQsITashn+RiBbp4pG8= X-Received: by 2002:a17:902:da81:b0:2b0:62dd:3a80 with SMTP id d9443c01a7336-2b97c4396e6mr82443855ad.17.1777468838422; Wed, 29 Apr 2026 06:20:38 -0700 (PDT) X-Received: by 2002:a17:902:da81:b0:2b0:62dd:3a80 with SMTP id d9443c01a7336-2b97c4396e6mr82443265ad.17.1777468837700; Wed, 29 Apr 2026 06:20:37 -0700 (PDT) Received: from hu-mojha-hyd.qualcomm.com ([202.46.23.25]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b98879f033sm22452335ad.28.2026.04.29.06.20.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2026 06:20:36 -0700 (PDT) Date: Wed, 29 Apr 2026 18:50:21 +0530 From: Mukesh Ojha To: Sumit Garg Cc: andersson@kernel.org, konradybcio@kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-media@vger.kernel.org, netdev@vger.kernel.org, linux-wireless@vger.kernel.org, ath12k@lists.infradead.org, linux-remoteproc@vger.kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, robin.clark@oss.qualcomm.com, sean@poorly.run, akhilpo@oss.qualcomm.com, lumag@kernel.org, abhinav.kumar@linux.dev, jesszhan0024@gmail.com, marijn.suijten@somainline.org, airlied@gmail.com, simona@ffwll.ch, vikash.garodia@oss.qualcomm.com, dikshita.agarwal@oss.qualcomm.com, bod@kernel.org, mchehab@kernel.org, elder@kernel.org, andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, jjohnson@kernel.org, mathieu.poirier@linaro.org, trilokkumar.soni@oss.qualcomm.com, pavan.kondeti@oss.qualcomm.com, jorge.ramirez@oss.qualcomm.com, tonyh@qti.qualcomm.com, vignesh.viswanathan@oss.qualcomm.com, srinivas.kandagatla@oss.qualcomm.com, amirreza.zarrabi@oss.qualcomm.com, jens.wiklander@linaro.org, op-tee@lists.trustedfirmware.org, apurupa@qti.qualcomm.com, skare@qti.qualcomm.com, linux-kernel@vger.kernel.org, Sumit Garg Subject: Re: [PATCH v4 04/15] firmware: qcom: Add a PAS TEE service Message-ID: <20260429132021.xk2xtll545o256oz@hu-mojha-hyd.qualcomm.com> References: <20260427095603.1157963-1-sumit.garg@kernel.org> <20260427095603.1157963-5-sumit.garg@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260427095603.1157963-5-sumit.garg@kernel.org> X-Proofpoint-GUID: cSpT4UskJ55bCvB9zPMfwDUDa4OEI5nR X-Proofpoint-ORIG-GUID: cSpT4UskJ55bCvB9zPMfwDUDa4OEI5nR X-Authority-Analysis: v=2.4 cv=aPPAb79m c=1 sm=1 tr=0 ts=69f205a7 cx=c_pps a=MTSHoo12Qbhz2p7MsH1ifg==:117 a=ZePRamnt/+rB5gQjfz0u9A==:17 a=kj9zAlcOel0A:10 a=A5OVakUREuEA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=uCB-_qCOk_dth8sO8NgA:9 a=CjuIK1q_8ugA:10 a=GvdueXVYPmCkWapjIL-Q:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI5MDEzNSBTYWx0ZWRfX6uLY7/Lu5I0P 5bF7gbLcAFSmYGHRMHUPa8Y0HtKEhntTd3foelZA/bK8780n2mJYGzaALZtDJVmlgzvT/cMhu4i kDK92UX5ULMRikImvmKH2L97Bhq818sVihHK1pfHJu6F6KPuHw+uEGxFrrT/iBy/kpkPNcVHUDT unkTehlN0Djq4aUTbCS4SZ8gf86cDysLl/i/6fv+HUWZkgYD6ye8XXDHxOe6XzzBr+H3YSnJeEJ cgNn9gql19jBar8AhSq7ml9FhTOd0NwjePPzgaEnshj0kz99RmY27nkDyTjoIvZ9TKhqKA4F6t0 KKcCbOVgni6IccDK35EN+BcqzZCkpfiyenXvaN8fZD75jkrXMMTTsOA4umepIqHWEXHnFUxuI8r /R2fAWK3hmp9qQdjQop7M+Y+CXW9W+3HS41Dhj9cqZRvRlBi0N+Hf2g2iRvLI6NFtVcEv+ZpeHp PBzXxxV1tpIdjptLCzQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-28_05,2026-04-28_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 clxscore=1015 priorityscore=1501 adultscore=0 impostorscore=0 lowpriorityscore=0 phishscore=0 bulkscore=0 malwarescore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604290135 On Mon, Apr 27, 2026 at 03:25:52PM +0530, Sumit Garg wrote: > From: Sumit Garg > > 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 > --- > drivers/firmware/qcom/Kconfig | 10 + > drivers/firmware/qcom/Makefile | 1 + > drivers/firmware/qcom/qcom_pas_tee.c | 479 +++++++++++++++++++++++++++ > 3 files changed, 490 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..300b3a1bd178 100644 > --- a/drivers/firmware/qcom/Kconfig > +++ b/drivers/firmware/qcom/Kconfig > @@ -14,6 +14,16 @@ 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 > + default m if ARCH_QCOM > + 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..af73d0a68525 > --- /dev/null > +++ b/drivers/firmware/qcom/qcom_pas_tee.c > @@ -0,0 +1,479 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "qcom_pas.h" > + > +/* > + * Peripheral Authentication Service (PAS) supported. > + * > + * [in] params[0].value.a: Unique 32bit remote processor identifier > + */ > +#define TA_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 TA_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 TA_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 TA_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 TA_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 TA_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 TA_QCOM_PAS_SET_REMOTE_STATE 7 > + > +/* > + * PAS co-processor shutdown. > + * > + * [in] params[0].value.a: Unique 32bit remote processor identifier > + */ > +#define TA_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 = TA_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, ret: %d, err: 0x%x\n", > + pas_id, ret, 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 = TA_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, ret: %d, err: 0x%x\n", > + pas_id, ret, inv_arg.ret); > + tee_shm_free(mdata_shm); > + return ret ?: -EINVAL; > + } > + > + if (ctx) > + ctx->ptr = (void *)mdata_shm; > + else > + tee_shm_free(mdata_shm); > + > + return ret; > +} > + > +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 = TA_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, ret: %d, err: 0x%x\n", > + pas_id, ret, inv_arg.ret); > + return ret ?: -EINVAL; > + } > + > + return ret; > +} > + > +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 = TA_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); > + if (ret < 0 || inv_arg.ret != 0) { > + dev_err(dev, "PAS get RT failed, pas_id: %d, ret: %d, err: 0x%x\n", > + ctx->pas_id, ret, inv_arg.ret); > + return ret ? ERR_PTR(ret) : 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(rt_shm_va)) { > + dev_err(dev, "rt_shm get VA failed\n"); > + return ERR_CAST(rt_shm_va); > + } > + memcpy(rt_shm_va, input_rt, input_rt_size); It is very obvious that every existing user will pass NULL as input_rt and 0 as input_rt_size. Are you not getting NULL pointer on this input_rt ? Ok, you may be not getting because, input_rt_size == 0. I hope, your backend implementation checks for this num == 0 and then ignore input rt. > + > + param[1].u.memref.shm = rt_shm; > + 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, ret: %d, err: 0x%x\n", > + ctx->pas_id, ret, inv_arg.ret); > + return ret ? ERR_PTR(ret) : ERR_PTR(-EINVAL); > + } > + > + if (param[1].u.memref.size) { > + *output_rt_size = param[1].u.memref.size; > + rt_buf = kmemdup(rt_shm_va, *output_rt_size, GFP_KERNEL); > + if (!rt_buf) > + return ERR_PTR(-ENOMEM); > + } > + } > + > + return rt_buf; > +} > + > +static int __qcom_pas_tee_auth_and_reset(struct device *dev, u32 pas_id, > + phys_addr_t mem_phys, size_t mem_size) > +{ > + struct qcom_pas_tee_private *data = dev_get_drvdata(dev); > + struct tee_ioctl_invoke_arg inv_arg = { > + .func = TA_QCOM_PAS_AUTH_AND_RESET, > + .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 = mem_size, > + }, > + [1] = { > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT, > + .u.value.a = lower_32_bits(mem_phys), > + .u.value.b = upper_32_bits(mem_phys), > + }, > + /* Reserved for fw memory space to be shared or lent */ > + [2] = { > + .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT, > + } > + }; > + int ret; > + > + ret = tee_client_invoke_func(data->ctx, &inv_arg, param); > + if (ret < 0 || inv_arg.ret != 0) { > + dev_err(dev, "PAS auth reset failed, pas_id: %d, ret: %d, err: 0x%x\n", > + pas_id, ret, inv_arg.ret); > + return ret ?: -EINVAL; > + } > + > + return ret; > +} > + > +static int qcom_pas_tee_auth_and_reset(struct device *dev, u32 pas_id) > +{ > + return __qcom_pas_tee_auth_and_reset(dev, pas_id, 0, 0); > +} > + > +static int qcom_pas_tee_prepare_and_auth_reset(struct device *dev, > + struct qcom_pas_context *ctx) > +{ > + return __qcom_pas_tee_auth_and_reset(dev, ctx->pas_id, ctx->mem_phys, > + ctx->mem_size); > +} > + > +static int qcom_pas_tee_set_remote_state(struct device *dev, u32 state, > + u32 pas_id) > +{ > + struct qcom_pas_tee_private *data = dev_get_drvdata(dev); > + struct tee_ioctl_invoke_arg inv_arg = { > + .func = TA_QCOM_PAS_SET_REMOTE_STATE, > + .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 = state, > + } > + }; > + int ret; > + > + ret = tee_client_invoke_func(data->ctx, &inv_arg, param); > + if (ret < 0 || inv_arg.ret != 0) { > + dev_err(dev, "PAS shutdown failed, pas_id: %d, ret: %d, err: 0x%x\n", > + pas_id, ret, inv_arg.ret); should be "PAS set remote state failed .." > + return ret ?: -EINVAL; > + } > + > + return ret; > +} > + > +static int qcom_pas_tee_shutdown(struct device *dev, u32 pas_id) > +{ > + struct qcom_pas_tee_private *data = dev_get_drvdata(dev); > + struct tee_ioctl_invoke_arg inv_arg = { > + .func = TA_QCOM_PAS_SHUTDOWN, > + .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 shutdown failed, pas_id: %d, ret: %d, err: 0x%x\n", > + pas_id, ret, inv_arg.ret); > + return ret ?: -EINVAL; > + } > + > + return ret; > +} > + > +static void qcom_pas_tee_metadata_release(struct device *dev, > + struct qcom_pas_context *ctx) > +{ > + struct tee_shm *mdata_shm = ctx->ptr; > + > + tee_shm_free(mdata_shm); > +} > + > +static struct qcom_pas_ops qcom_pas_ops_tee = { > + .drv_name = "qcom-pas-tee", > + .supported = qcom_pas_tee_supported, > + .init_image = qcom_pas_tee_init_image, > + .mem_setup = qcom_pas_tee_mem_setup, > + .get_rsc_table = qcom_pas_tee_get_rsc_table, > + .auth_and_reset = qcom_pas_tee_auth_and_reset, > + .prepare_and_auth_reset = qcom_pas_tee_prepare_and_auth_reset, > + .set_remote_state = qcom_pas_tee_set_remote_state, > + .shutdown = qcom_pas_tee_shutdown, > + .metadata_release = qcom_pas_tee_metadata_release, > +}; > + > +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) > +{ > + return ver->impl_id == TEE_IMPL_ID_OPTEE; > +} > + > +static int qcom_pas_tee_probe(struct tee_client_device *pas_dev) > +{ > + struct device *dev = &pas_dev->dev; > + struct qcom_pas_tee_private *data; > + struct tee_ioctl_open_session_arg sess_arg = { > + .clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL > + }; > + int ret, err = -ENODEV; Most people prefer one line per variable.. > + > + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); > + if (!data) > + return -ENOMEM; > + > + data->ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); > + if (IS_ERR(data->ctx)) > + return -ENODEV; > + > + export_uuid(sess_arg.uuid, &pas_dev->id.uuid); > + ret = tee_client_open_session(data->ctx, &sess_arg, NULL); > + if (ret < 0 || sess_arg.ret != 0) { > + dev_err(dev, "tee_client_open_session failed, ret: %d, err: 0x%x\n", > + ret, sess_arg.ret); > + err = ret ?: -EINVAL; Only user of goto, we can close the context and return from here and 'err' not used. tee_client_close_context(data->ctx); return ret ?: -EINVAL; > + goto out_ctx; > + } > + > + data->session_id = sess_arg.session; > + dev_set_drvdata(dev, data); > + qcom_pas_ops_tee.dev = dev; > + qcom_pas_ops_register(&qcom_pas_ops_tee); > + > + return ret; > +out_ctx: > + tee_client_close_context(data->ctx); Return after two line does not look nice. > + > + return err; > +} > + > +static void qcom_pas_tee_remove(struct tee_client_device *pas_dev) > +{ > + struct device *dev = &pas_dev->dev; > + struct qcom_pas_tee_private *data = dev_get_drvdata(dev); > + > + qcom_pas_ops_unregister(); > + tee_client_close_session(data->ctx, data->session_id); > + tee_client_close_context(data->ctx); > +} > + > +static const struct tee_client_device_id qcom_pas_tee_id_table[] = { > + {UUID_INIT(0xcff7d191, 0x7ca0, 0x4784, > + 0xaf, 0x13, 0x48, 0x22, 0x3b, 0x9a, 0x4f, 0xbe)}, > + {} > +}; > +MODULE_DEVICE_TABLE(tee, qcom_pas_tee_id_table); > + > +static struct tee_client_driver optee_pas_tee_driver = { > + .probe = qcom_pas_tee_probe, > + .remove = qcom_pas_tee_remove, > + .id_table = qcom_pas_tee_id_table, > + .driver = { > + .name = "qcom-pas-tee", > + }, > +}; > + > +module_tee_client_driver(optee_pas_tee_driver); > + > +MODULE_LICENSE("GPL"); > +MODULE_DESCRIPTION("Qualcomm PAS TEE driver"); > -- > 2.51.0 > With above change, Reviewed-by: Mukesh Ojha -- -Mukesh Ojha