From patchwork Thu Nov 10 15:45:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 13038950 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 70274C4332F for ; Thu, 10 Nov 2022 15:48:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Mjqbe0vXQMvUSKlVCpw5EhHodPTrBrTEpw/552dfozI=; b=LAR9QqswI5Owfm SRzHrCY4RwsZ4tD8p9a52pP3CKsxkaHnfo2R61OzX0NlYdr2RIyYgL14qORNOUle/e9vtz/uROfGG baUsp1nZ1/DHHzCF4XNtsoEEdKag4kL3+M28Mz4aeRjp3jkQ6ZM8ARb7unfkZAJ02KsvWl+hs1Glz fMQpRBifFo/58DmFIn0bDoTor6Bsevw/UVC5Z9EHf0fhqstl+I3EYnwoj/amaCmTwMUWYv9qF8vu+ ru2RKAJy6RYtqnNHw8dDepX986tGEIREGdbsKdyePdhlQMkAyfeVjk3629LCm6RwVjDcBOgXxABJV Nhv/ITRT5StJThqYa/2g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1ot9lm-006rn3-S5; Thu, 10 Nov 2022 15:47:11 +0000 Received: from mx07-00178001.pphosted.com ([185.132.182.106]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1ot9lF-006rPK-5b for linux-arm-kernel@lists.infradead.org; Thu, 10 Nov 2022 15:46:40 +0000 Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2AAFbJkN000805; Thu, 10 Nov 2022 16:46:19 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=selector1; bh=mloTfjScbE+KvHcb3ds6SBjdWfKRWzgGZsYJkOZEgeQ=; b=b+chlpkhuPZ91bOcrI6Lcb+thXsZ1rgfj+XgCBdmuFWrU9vnnN6D1ZrO0bcDkOi7s9mC gWc2wuW8q9/svQGKVTRGEwVDx70vGIhfsV6RGHhLPxvqczzvzpzxUbngbpnHHdGrWvCB XWrNil8Vnhf27lkrtcqjqsmF1HcJkVIKrFj7Cz5cNJoDdMmcr358x7VpqgTSNVXM7oxM DCY5+JA8z+VH+uG/Q1UtB/C45aroIo263c0YZgTI+2dBrv5eeqNsNXH02VCQtX3VtHR6 HJ/sDImndSf6UvGj3M/V/aumo1L0Ojf2Dq9Rgm5ncW13pkwOr3atLIZNzUPi6sUKfx6X 1g== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3ks43u01mh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 10 Nov 2022 16:46:19 +0100 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id D5788100034; Thu, 10 Nov 2022 16:46:14 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id CCD9F22AFED; Thu, 10 Nov 2022 16:46:14 +0100 (CET) Received: from localhost (10.252.15.206) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Thu, 10 Nov 2022 16:46:14 +0100 From: Patrick Delaunay To: Alexandre TORGUE , Rob Herring , Krzysztof Kozlowski , Maxime Coquelin CC: Fabrice GASNIER , Patrick Delaunay , , , , Subject: [PATCH v2 1/3] ARM: dts: stm32mp13: fix compatible for BSEC Date: Thu, 10 Nov 2022 16:45:47 +0100 Message-ID: <20221110164329.v2.1.I167a5efc1f8777cce14518c6fa38400ac684de3e@changeid> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221110154550.3220800-1-patrick.delaunay@foss.st.com> References: <20221110154550.3220800-1-patrick.delaunay@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.15.206] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.895,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-11-10_10,2022-11-09_01,2022-06-22_01 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221110_074637_559413_3764C449 X-CRM114-Status: GOOD ( 20.42 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Use the correct compatible for stm32mp13 support. The BSEC driver for STM32MP15x is not compatible with STM32MP13x. For example the proprietary's smc STM32_SMC_BSEC is not supported in STM32MP13x OP-TEE, it is replaced by SM32MP BSEC Pseudo Trusted Application in OP-TEE to access to the secured IP BSEC on STM32MP13X SoC. The correct compatible is already used in U-Boot and in upstream is in progress for OP-TEE device tree. As the SoC STM32MP13X is not yet official and it is not available outside STMicroelectronics, it is the good time to break the DTS compatibility and to correct the error done in the introduction of STM32MP131. Signed-off-by: Patrick Delaunay --- This patch is already sent separately in: https://lore.kernel.org/all/20221017134437.1.I167a5efc1f8777cce14518c6fa38400ac684de3e@changeid/ https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=685815 I create a serie for more efficient review. Patrick. (no changes since v1) Changes in v1: - update commit message to indicate DTS break reason. arch/arm/boot/dts/stm32mp131.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi index 2a9b3a5bba83..f034cbe0d5b2 100644 --- a/arch/arm/boot/dts/stm32mp131.dtsi +++ b/arch/arm/boot/dts/stm32mp131.dtsi @@ -522,7 +522,7 @@ rtc: rtc@5c004000 { }; bsec: efuse@5c005000 { - compatible = "st,stm32mp15-bsec"; + compatible = "st,stm32mp13-bsec"; reg = <0x5c005000 0x400>; #address-cells = <1>; #size-cells = <1>; From patchwork Thu Nov 10 15:45:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 13038951 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5D7E3C4332F for ; Thu, 10 Nov 2022 15:48:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ScKh+voUJMJAbQOt8vfeTzvzwRbZOOyoVWtXbey2znQ=; b=24Fy/L0IW+5Oz1 uVBLq/tGuFVJlevsVA+MJTELFO/H5tOL0UAhpilvY146D2s1dTCBHlKs931+r2XHigeKk41yJgHfk Ubuhdf8ZmbW7CGAEOt+Qi7mANfkDM/n0NS8ZOiEO2g5VqmdsS4q6r7QLb8z1CRmZEHR1udzDxrpyb RDaKwHyhW94GxeA6VyiCnj2mbqP5YrqQWfypQUpPI0CeUCENoc1hixY3+iyMEDBbRIAV91SvjCjhB +decE2Jz1XA5piIJ+8q5rfPoUfM1+xxsx1BHClgSsX3XBj4EDf00EKTToSTx/WAysmkJWOIyFoQUP GTZ/6QM06nUr0Jk2evAg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1ot9mC-006rzM-A8; Thu, 10 Nov 2022 15:47:37 +0000 Received: from mx08-00178001.pphosted.com ([91.207.212.93] helo=mx07-00178001.pphosted.com) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1ot9lF-006rML-4K for linux-arm-kernel@lists.infradead.org; Thu, 10 Nov 2022 15:46:41 +0000 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2AAFbrE2011740; Thu, 10 Nov 2022 16:46:20 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=selector1; bh=yOeh3RiZA3+txo8FSZDXOsHC1HecM76LGBbP5ku2mAU=; b=ouU+YerwtMOrKQWrMiOB/IFjCE+Ozn/7KvIFXhJy2citTIUz/ZgYob/ZL+2pZRZnCsGS Rz73ww0mIpjh0gCvSI1fGT5fI4gynD7n627ncmN10AVzhwhcpzsDB9zN1sfH+av5frMn NtJJ4Pb/80I2qjPGdZgGeKetW9cJla9Z0KCXIq63XPojkQ8vbHZW8oiXOCmTZUpEe+H5 9KF8K2DYnKqaMrnO/k6gciLxPQ1dB4oWl9fwpFDX7Bn26W5W75Lg6FZFB46GNKxT5xB+ 8F6CAwfFDl2yHuIpTdLayg9OT7Id21Dc4j6x/EdOI2vXdaFbNTt0l47MebIJb98yY26X +Q== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3ks443g1sv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 10 Nov 2022 16:46:20 +0100 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 02CB0100038; Thu, 10 Nov 2022 16:46:16 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id ED1C622AFED; Thu, 10 Nov 2022 16:46:15 +0100 (CET) Received: from localhost (10.252.15.206) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Thu, 10 Nov 2022 16:46:15 +0100 From: Patrick Delaunay To: Alexandre TORGUE , Srinivas Kandagatla , Maxime Coquelin CC: Fabrice GASNIER , Patrick Delaunay , Etienne CARRIERE , , , Subject: [PATCH v2 2/3] nvmem: stm32: add OP-TEE support for STM32MP13x Date: Thu, 10 Nov 2022 16:45:48 +0100 Message-ID: <20221110164329.v2.2.Ibc43aa73f865090affeb1751af0cc260c7f1dd07@changeid> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221110154550.3220800-1-patrick.delaunay@foss.st.com> References: <20221110154550.3220800-1-patrick.delaunay@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.15.206] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.895,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-11-10_10,2022-11-09_01,2022-06-22_01 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221110_074637_611431_D08F9BDA X-CRM114-Status: GOOD ( 34.41 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org For boot with OP-TEE on STM32MP13, the communication with the secure world no more use STMicroelectronics SMC but communication with the BSEC TA, for data access (read/write) or lock operation: - all the request are sent to OP-TEE trusted application, - for upper OTP with ECC protection and with word programming only each OTP are permanently locked when programmed to avoid ECC error on the second write operation Signed-off-by: Patrick Delaunay --- Changes in v2: - rebase series on linux-next/master - minor update after V1 revue - add missing sentinel in stm32_romem_of_match() - reorder function and remove prototypes for stm32_bsec_pta... functions - change stm32_bsec_pta_find to static - add return value in dev_err() - cleanups some comments, which can be on one line - remove test on priv->ctx in stm32_bsec_pta_remove - add missing tee_shm_free(shm) in stm32_bsec_pta_write() when tee_shm_get_va failed - return error in stm32_bsec_pta_find when devm_add_action_or_reset failed - handle driver_register error in stm32_romem_init drivers/nvmem/stm32-romem.c | 445 +++++++++++++++++++++++++++++++++++- 1 file changed, 441 insertions(+), 4 deletions(-) diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c index d1d03c2ad081..0a0e29d09b67 100644 --- a/drivers/nvmem/stm32-romem.c +++ b/drivers/nvmem/stm32-romem.c @@ -11,6 +11,7 @@ #include #include #include +#include /* BSEC secure service access from non-secure */ #define STM32_SMC_BSEC 0x82001003 @@ -25,14 +26,401 @@ struct stm32_romem_cfg { int size; u8 lower; + bool ta; }; struct stm32_romem_priv { void __iomem *base; struct nvmem_config cfg; u8 lower; + struct device *ta; }; +#if IS_ENABLED(CONFIG_OPTEE) +/* + * Read OTP memory + * + * [in] value[0].a OTP start offset in byte + * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) + * [out] memref[1].buffer Output buffer to store read values + * [out] memref[1].size Size of OTP to be read + * + * Return codes: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + */ +#define PTA_BSEC_READ_MEM 0x0 /* Read OTP */ + +/* + * Write OTP memory + * + * [in] value[0].a OTP start offset in byte + * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) + * [in] memref[1].buffer Input buffer to read values + * [in] memref[1].size Size of OTP to be written + * + * Return codes: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + */ +#define PTA_BSEC_WRITE_MEM 0x1 /* Write OTP */ + +/* value of PTA_BSEC access type = value[in] b */ +#define SHADOW_ACCESS 0 +#define FUSE_ACCESS 1 +#define LOCK_ACCESS 2 + +/* Bitfield definition for LOCK status */ +#define LOCK_PERM BIT(30) + +/** + * struct stm32_bsec_pta_priv - OP-TEE BSEC TA private data + * @ctx: OP-TEE context handler. + * @session_id: TA session identifier. + */ +struct stm32_bsec_pta_priv { + struct tee_context *ctx; + u32 session_id; +}; + +/* + * Check whether this driver supports the BSEC TA in the TEE instance + * represented by the params (ver/data) to this function. + */ +static int stm32_bsec_pta_match(struct tee_ioctl_version_data *ver, const void *data) +{ + /* Currently this driver only supports GP compliant, OP-TEE based TA */ + if ((ver->impl_id == TEE_IMPL_ID_OPTEE) && + (ver->gen_caps & TEE_GEN_CAP_GP)) + return 1; + else + return 0; +} + +/** + * stm32_bsec_pta_probe() - initialize the PTA BSEC + * @dev: the platform_device description. + * + * Return: + * On success, 0. On failure, -errno. + */ +static int stm32_bsec_pta_probe(struct device *dev) +{ + int rc; + struct tee_ioctl_open_session_arg sess_arg; + struct tee_client_device *tee_device = to_tee_client_device(dev); + struct stm32_bsec_pta_priv *priv; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + /* Open context with TEE driver */ + priv->ctx = tee_client_open_context(NULL, stm32_bsec_pta_match, NULL, NULL); + if (IS_ERR(priv->ctx)) { + rc = PTR_ERR(priv->ctx); + if (rc == -ENOENT) + return -EPROBE_DEFER; + dev_err(dev, "%s: tee_client_open_context failed (%d)\n", __func__, rc); + + return rc; + } + + /* Open a session with BSEC TA */ + memset(&sess_arg, 0, sizeof(sess_arg)); + export_uuid(sess_arg.uuid, &tee_device->id.uuid); + sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; + sess_arg.num_params = 0; + + rc = tee_client_open_session(priv->ctx, &sess_arg, NULL); + if ((rc < 0) || (sess_arg.ret != 0)) { + dev_err(dev, "%s: tee_client_open_session failed err:%x, ret:%x\n", + __func__, sess_arg.ret, rc); + rc = -EINVAL; + goto out_tee_session; + } + priv->session_id = sess_arg.session; + dev_set_drvdata(dev, priv); + + return 0; + +out_tee_session: + tee_client_close_context(priv->ctx); + + return rc; +} + +/** + * stm32_bsec_pta_remove() - remove the BSEC TEE device + * @dev: the platform_device description. + * + * Return: + * 0 always. + */ +static int stm32_bsec_pta_remove(struct device *dev) +{ + struct stm32_bsec_pta_priv *priv = dev_get_drvdata(dev); + + tee_client_close_session(priv->ctx, priv->session_id); + tee_client_close_context(priv->ctx); + + return 0; +} + +/** + * stm32_bsec_pta_read() - nvmem read access using PTA client driver + * @context: nvmem context => romem privdate data + * @offset: nvmem offset + * @buf: buffer to fill with nvem values + * @bytes: number of bytes to read + * + * Return: + * On success, 0. On failure, -errno. + */ +static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf, + size_t bytes) +{ + struct stm32_romem_priv *romem_priv = context; + struct device *dev; + struct stm32_bsec_pta_priv *priv; + struct tee_shm *shm; + struct tee_ioctl_invoke_arg arg; + struct tee_param param[2]; + u8 *shm_buf; + u32 start, num_bytes; + int ret; + + dev = romem_priv->ta; + if (!dev) { + pr_err("TA_BSEC invoke without driver\n"); + return -ENXIO; + } + + priv = dev_get_drvdata(dev); + + memset(&arg, 0, sizeof(arg)); + memset(¶m, 0, sizeof(param)); + + arg.func = PTA_BSEC_READ_MEM; + arg.session = priv->session_id; + arg.num_params = 2; + + /* align access on 32bits */ + start = ALIGN_DOWN(offset, 4); + num_bytes = round_up(offset + bytes - start, 4); + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; + param[0].u.value.a = start; + param[0].u.value.b = SHADOW_ACCESS; + + shm = tee_shm_alloc_kernel_buf(priv->ctx, num_bytes); + if (IS_ERR(shm)) + return PTR_ERR(shm); + + param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param[1].u.memref.shm = shm; + param[1].u.memref.size = num_bytes; + + ret = tee_client_invoke_func(priv->ctx, &arg, param); + if (ret < 0 || arg.ret != 0) { + dev_err(dev, "TA_BSEC invoke failed TEE err:%x, ret:%x\n", + arg.ret, ret); + if (!ret) + ret = -EIO; + } + if (!ret) { + shm_buf = tee_shm_get_va(shm, 0); + if (IS_ERR(shm_buf)) { + ret = PTR_ERR(shm_buf); + dev_err(dev, "tee_shm_get_va failed for transmit (%d)\n", ret); + } else { + /* read data from 32 bits aligned buffer */ + memcpy(buf, &shm_buf[offset % 4], bytes); + } + } + + tee_shm_free(shm); + + return ret; +} + +/** + * stm32_bsec_pta_write() - nvmem write access using PTA client driver + * @context: nvmem context => romem privdate data + * @offset: nvmem offset + * @buf: buffer with nvem values + * @bytes: number of bytes to write + * + * Return: + * On success, 0. On failure, -errno. + */ +static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf, + size_t bytes) +{ + struct stm32_romem_priv *romem_priv = context; + struct device *dev; + struct stm32_bsec_pta_priv *priv; + struct tee_shm *shm; + struct tee_ioctl_invoke_arg arg; + struct tee_param param[2]; + u8 *shm_buf; + int ret; + + dev = romem_priv->ta; + if (!dev) { + pr_err("TA_BSEC invoke without driver\n"); + return -ENXIO; + } + + /* Allow only writing complete 32-bits aligned words */ + if ((bytes % 4) || (offset % 4)) + return -EINVAL; + + priv = dev_get_drvdata(dev); + + memset(&arg, 0, sizeof(arg)); + memset(¶m, 0, sizeof(param)); + + arg.func = PTA_BSEC_WRITE_MEM; + arg.session = priv->session_id; + arg.num_params = 2; + + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; + param[0].u.value.a = offset; + param[0].u.value.b = FUSE_ACCESS; + + shm = tee_shm_alloc_kernel_buf(priv->ctx, bytes); + if (IS_ERR(shm)) + return PTR_ERR(shm); + + param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; + param[1].u.memref.shm = shm; + param[1].u.memref.size = bytes; + + shm_buf = tee_shm_get_va(shm, 0); + if (IS_ERR(shm_buf)) { + ret = PTR_ERR(shm_buf); + dev_err(dev, "tee_shm_get_va failed for transmit (%d)\n", ret); + tee_shm_free(shm); + + return ret; + } + + memcpy(shm_buf, buf, bytes); + + ret = tee_client_invoke_func(priv->ctx, &arg, param); + if (ret < 0 || arg.ret != 0) { + dev_err(dev, "TA_BSEC invoke failed TEE err:%x, ret:%x\n", + arg.ret, ret); + if (!ret) + ret = -EIO; + } + dev_dbg(dev, "Write OTPs %d to %d, ret=%d\n", + offset / 4, (offset + bytes) / 4, ret); + + /* Lock the upper OTPs with ECC protection, word programming only */ + if (!ret && ((offset + bytes) >= (romem_priv->lower * 4))) { + u32 start, nb_lock; + u32 *lock = (u32 *)shm_buf; + int i; + + /* + * don't lock the lower OTPs, no ECC protection and incremental + * bit programming, a second write is allowed + */ + start = max_t(u32, offset, romem_priv->lower * 4); + nb_lock = (offset + bytes - start) / 4; + + param[0].u.value.a = start; + param[0].u.value.b = LOCK_ACCESS; + param[1].u.memref.size = nb_lock * 4; + + for (i = 0; i < nb_lock; i++) + lock[i] = LOCK_PERM; + + ret = tee_client_invoke_func(priv->ctx, &arg, param); + if (ret < 0 || arg.ret != 0) { + dev_err(dev, "TA_BSEC invoke failed TEE err:%x, ret:%x\n", + arg.ret, ret); + if (!ret) + ret = -EIO; + } + dev_dbg(dev, "Lock upper OTPs %d to %d, ret=%d\n", + start / 4, start / 4 + nb_lock, ret); + } + + tee_shm_free(shm); + + return ret; +} + +static const struct tee_client_device_id stm32_bsec_id_table[] = { + { + UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5, + 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03) + }, + { } +}; + +MODULE_DEVICE_TABLE(tee, stm32_bsec_id_table); + +static struct tee_client_driver stm32_bsec_pta_driver = { + .id_table = stm32_bsec_id_table, + .driver = { + .name = "stm32-bsec-pta", + .bus = &tee_bus_type, + .probe = stm32_bsec_pta_probe, + .remove = stm32_bsec_pta_remove, + }, +}; + +static void stm32_bsec_put_device(void *data) +{ + put_device(data); +} + +static struct device *stm32_bsec_pta_find(struct device *dev) +{ + struct device *pta_dev; + int ret; + + pta_dev = driver_find_next_device(&stm32_bsec_pta_driver.driver, NULL); + + if (pta_dev) { + ret = devm_add_action_or_reset(dev, stm32_bsec_put_device, pta_dev); + if (ret) + dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", ret); + + return ERR_PTR(ret); + } + + return pta_dev; +} + +#else +static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf, + size_t bytes) +{ + pr_debug("%s: TA BSEC request without OPTEE support\n", __func__); + + return -ENXIO; +} + +static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf, + size_t bytes) +{ + pr_debug("%s: TA BSEC request without OPTEE support\n", __func__); + + return -ENXIO; +} + +static struct device *stm32_bsec_pta_find(struct device *dev) +{ + pr_debug("%s: TA BSEC request without OPTEE support\n", __func__); + + return NULL; +} +#endif + static int stm32_romem_read(void *context, unsigned int offset, void *buf, size_t bytes) { @@ -173,15 +561,27 @@ static int stm32_romem_probe(struct platform_device *pdev) } else { priv->cfg.size = cfg->size; priv->lower = cfg->lower; - priv->cfg.reg_read = stm32_bsec_read; - priv->cfg.reg_write = stm32_bsec_write; + if (cfg->ta) { + priv->ta = stm32_bsec_pta_find(dev); + /* wait for OP-TEE client driver to be up and ready */ + if (!priv->ta) + return -EPROBE_DEFER; + if (IS_ERR(priv->ta)) + return PTR_ERR(priv->ta); + + priv->cfg.reg_read = stm32_bsec_pta_read; + priv->cfg.reg_write = stm32_bsec_pta_write; + } else { + priv->cfg.reg_read = stm32_bsec_read; + priv->cfg.reg_write = stm32_bsec_write; + } } return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); } /* - * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) + * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) * => 96 x 32-bits data words * - Lower: 1K bits, 2:1 redundancy, incremental bit programming * => 32 (x 32-bits) lower shadow registers = words 0 to 31 @@ -191,6 +591,13 @@ static int stm32_romem_probe(struct platform_device *pdev) static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { .size = 384, .lower = 32, + .ta = false, +}; + +static const struct stm32_romem_cfg stm32mp13_bsec_cfg = { + .size = 384, + .lower = 32, + .ta = true, }; static const struct of_device_id stm32_romem_of_match[] = { @@ -198,7 +605,10 @@ static const struct of_device_id stm32_romem_of_match[] = { .compatible = "st,stm32mp15-bsec", .data = (void *)&stm32mp15_bsec_cfg, }, { + .compatible = "st,stm32mp13-bsec", + .data = (void *)&stm32mp13_bsec_cfg, }, + { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, stm32_romem_of_match); @@ -209,7 +619,34 @@ static struct platform_driver stm32_romem_driver = { .of_match_table = of_match_ptr(stm32_romem_of_match), }, }; -module_platform_driver(stm32_romem_driver); + +static int __init stm32_romem_init(void) +{ + int rc; + + rc = platform_driver_register(&stm32_romem_driver); + if (rc) + return rc; + +#if IS_ENABLED(CONFIG_OPTEE) + rc = driver_register(&stm32_bsec_pta_driver.driver); + if (rc) + platform_driver_unregister(&stm32_romem_driver); +#endif + + return rc; +} + +static void __exit stm32_romem_exit(void) +{ + platform_driver_unregister(&stm32_romem_driver); +#if IS_ENABLED(CONFIG_OPTEE) + driver_unregister(&stm32_bsec_pta_driver.driver); +#endif +} + +module_init(stm32_romem_init); +module_exit(stm32_romem_exit); MODULE_AUTHOR("Fabrice Gasnier "); MODULE_DESCRIPTION("STMicroelectronics STM32 RO-MEM"); From patchwork Thu Nov 10 15:45:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 13038948 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2A406C433FE for ; Thu, 10 Nov 2022 15:47:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=OfYjOYClIf48Im6DCsZ+PgfwunM9+JenZYPlysUoVII=; b=LeghyF/Ad9gX8C GvYL/2Q9C/appEUodmmHVrSxbzn1FVBIKoApiHGVV7FjQNVeoZjBII+QRskDD1gsyC77/KoSb0BLq pz4PLuV2+UGHcOJgBJtvBapConoiKmiUtaa7R0zjNoUxobUClXVy3Oh3R7iv8JTrHb1Iz1sLv7mL9 KTT7KrYk4h8wFGi1Tajozoxa5gVKAZn15US0y6KIZYM4QnMR67d7Q5UKY0A+1GFeA0ogglqenueyq M4i3wMXpgWrIw+YQWN8p6QYInnzAZSGnYHhJMxK19zfDvCGRuVEpFPSJRNZU2aC405xX8FtOGkeiV DFiVP+7qtc23GDNFwV8w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1ot9lP-006rcB-T6; Thu, 10 Nov 2022 15:46:48 +0000 Received: from mx08-00178001.pphosted.com ([91.207.212.93] helo=mx07-00178001.pphosted.com) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1ot9lE-006rMV-8v for linux-arm-kernel@lists.infradead.org; Thu, 10 Nov 2022 15:46:38 +0000 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2AAFbsNB011752; Thu, 10 Nov 2022 16:46:22 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=selector1; bh=Dqy9dYHsxt9AzTmF5WyUZLFE2yygm9hJF+Zgo8L1RJY=; b=3QoRxOAqokFH7cqxQ7p2j3qdCaQoq3PrlYExjHyn0x8lDlyE04KafHpVBq0zGaeKs2yl xUlf2FSGJO5XqP73atdvgQxtDcQkDHPY74BH/ITUEdoKc9FsT9L5Z+EzCoXwsnhEN5Zb ebJnv+XutgPZzzYNzLXOQomXAuUSVcgtgq2mArGoq8RcyM7vc7pkrFdLQdVUqodo/SNO v6k6I8pNAAqV9CqxnmK2INuIMZWKVzLwyzWozdu1MWWKWjiv+bbKIWQMFKocARdLgVid ulNPy+nBabNz4Of8pABkt5HwU/S4oqdqWa9l9CkRxb/lkeulSw+J48eo08Pfa/DuzRgN qA== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3ks443g1t1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 10 Nov 2022 16:46:22 +0100 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 960A710002A; Thu, 10 Nov 2022 16:46:17 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 8F93422AFED; Thu, 10 Nov 2022 16:46:17 +0100 (CET) Received: from localhost (10.252.15.206) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Thu, 10 Nov 2022 16:46:16 +0100 From: Patrick Delaunay To: Alexandre TORGUE , Srinivas Kandagatla , Maxime Coquelin CC: Fabrice GASNIER , Patrick Delaunay , , , Subject: [PATCH v2 3/3] nvmem: stm32: detect bsec pta presence for STM32MP15x Date: Thu, 10 Nov 2022 16:45:49 +0100 Message-ID: <20221110164329.v2.3.I59210046e368cfc22bd3cca2afe1653674f8ece8@changeid> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221110154550.3220800-1-patrick.delaunay@foss.st.com> References: <20221110154550.3220800-1-patrick.delaunay@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.252.15.206] X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.895,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-11-10_10,2022-11-09_01,2022-06-22_01 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221110_074636_651189_D9718EBB X-CRM114-Status: GOOD ( 23.45 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used; the PTA BSEC should be used as it is done on STM32MP13x platform, but the BSEC SMC can be also used: it is a legacy mode in OP-TEE, not recommended but used in previous OP-TEE firmware. The presence of OP-TEE is dynamically detected in STM32MP15x device tree and the supported NVMEM backend is dynamically detected: - PTA with stm32_bsec_pta_find - SMC with stm32_bsec_check With OP-TEE but without PTA and SMC detection, the probe is deferred for STM32MP15x devices. On STM32MP13x platform, only the PTA is supported with cfg->ta = true and this detection is skipped. Signed-off-by: Patrick Delaunay --- Changes in v2: - Added patch in the serie for BSEC PTA support on STM32MP15x with dynamic detection of OP-TEE presence and SMC support (legacy mode) drivers/nvmem/stm32-romem.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c index 0a0e29d09b67..35997d581c9d 100644 --- a/drivers/nvmem/stm32-romem.c +++ b/drivers/nvmem/stm32-romem.c @@ -526,6 +526,31 @@ static int stm32_bsec_write(void *context, unsigned int offset, void *buf, return 0; } +static bool stm32_bsec_smc_check(void) +{ + u32 val; + int ret; + + /* check that the OP-TEE support the BSEC SMC (legacy mode) */ + ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val); + + return !ret; +} + +static bool optee_presence_check(void) +{ + struct device_node *np; + bool tee_detected = false; + + /* check that the OP-TEE node is present and available. */ + np = of_find_node_by_path("/firmware/optee"); + if (np && of_device_is_available(np)) + tee_detected = true; + of_node_put(np); + + return tee_detected; +} + static int stm32_romem_probe(struct platform_device *pdev) { const struct stm32_romem_cfg *cfg; @@ -561,14 +586,18 @@ static int stm32_romem_probe(struct platform_device *pdev) } else { priv->cfg.size = cfg->size; priv->lower = cfg->lower; - if (cfg->ta) { + if (cfg->ta || optee_presence_check()) { priv->ta = stm32_bsec_pta_find(dev); /* wait for OP-TEE client driver to be up and ready */ - if (!priv->ta) - return -EPROBE_DEFER; + if (!priv->ta) { + /* BSEC PTA is required or SMC not ready */ + if (cfg->ta || !stm32_bsec_smc_check()) + return -EPROBE_DEFER; + } if (IS_ERR(priv->ta)) return PTR_ERR(priv->ta); - + } + if (priv->ta) { priv->cfg.reg_read = stm32_bsec_pta_read; priv->cfg.reg_write = stm32_bsec_pta_write; } else {