From patchwork Tue May 31 16:09:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 577447 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:330b:0:0:0:0 with SMTP id f11csp1300044mag; Tue, 31 May 2022 09:09:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxICi6LUgew9RqxOvFh3SmH5TRFE/0lPXLPHJ9W3UxBnjqWctVeagexPhYYEhp9TRWhTVSq X-Received: by 2002:a92:cd8e:0:b0:2d1:807d:35d8 with SMTP id r14-20020a92cd8e000000b002d1807d35d8mr28358600ilb.312.1654013396269; Tue, 31 May 2022 09:09:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654013396; cv=none; d=google.com; s=arc-20160816; b=g9O+iWITXjtPAwik+vgHUv0g2SCWpJS72nPhxo8INvTwQUvl8IAL151dbgWZ27nHiY WRPAta28At4YnUTquXFXEqTZr/kzbmNjDXK5HJI1nM5S1DTAMT/6rd/ekg00m++2JuID KYbLIUiSxwWY8Xl2N/TfAOz7Bc49ifu+v17s+rfw47X1xLJOakkSHCJNTPmrxHKO+0i1 4B1qQv6DlkavUQoQSqGxNeWnmujM2oK4qUSVAV4UiGZjPHr15fc2GiI4E0AKtUxCmO6c WQNZ+IBI32aJ468Ldhq292y+aueAl/mr07cz80HcJRo9XFap09lYLUFyR3z09expSoST PioA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=tUwsYIyMddQh95344M+xWvMZHPy9IfsHq+gKIrH8e30=; b=yd6rFKTwCLSBtz0oXPvSEUKIZsaKFyOzq/Ib33jM0KTBqpOYNyNCFJ94VMf3CGd7YV oqLOFaUWkKF1fWoj249irCapocHlXD+M31Kk6Sopj2dO7V6vTaofvJJen9MKLmvKXJuz ov8dvy2bNlGRg1WDRlqxKiDgv1W74piiijScaW64Hw7PwFh/lP+Qff6MLRFUNW6HS+8z xOmDzAxS2UtGfGmstvM+Yra/pa6tiYdSUG6eXJhSBTnTRn2BHDaWqQ7cWZKB034yYB5r xiQLJ/Y20hLlt/7q48x38T7iCDzqtbSeim9tt5GLA5nSfTUgiQWQKXOSzQxIV2fETLr0 BpAw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="bS2oj9v/"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id y7-20020a05663824c700b0031a2a42162fsi16432728jat.81.2022.05.31.09.09.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 May 2022 09:09:56 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="bS2oj9v/"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 09DCF84284; Tue, 31 May 2022 18:09:53 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="bS2oj9v/"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F065383E1B; Tue, 31 May 2022 18:09:42 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B2E5083D77 for ; Tue, 31 May 2022 18:09:37 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=etienne.carriere@linaro.org Received: by mail-wm1-x330.google.com with SMTP id h62-20020a1c2141000000b0039aa4d054e2so1532113wmh.1 for ; Tue, 31 May 2022 09:09:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tUwsYIyMddQh95344M+xWvMZHPy9IfsHq+gKIrH8e30=; b=bS2oj9v/UAXHz/7LNHqNlVyZpKq84OamnVcDVkqL1IKQliiz13l1kMQzLZp2Jszr84 Q57lHB37zR0LPr1jCB3Q5/0ZIdfpjG0OziICZHec6qUj8km3Y6mfOM3Bo9X2htRRCEwb CF4Bxu3Vd40i67HHfsPizuYtwFoEe/0JQh9mx2uVUfcyaROPZREz14ZNYJVP7Vo/0zas N3AemvS4C/d3f5uTOLwrn6xYYE6O1W4H5b4fQ2FeZZBriZdlRJ1snV8XBy5Fv61/ri36 Aj5HuDti9wSLlfCgcmBr3CyYeIvQx1Mr6TpRY+T2O/QC8F7SZyoq+lmyDP3C5sJZDmZa R5Iw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tUwsYIyMddQh95344M+xWvMZHPy9IfsHq+gKIrH8e30=; b=reeOwNLV3tS8wppAx4q2RBhssfuhOtaREKbHkJHTgikiSKtIIxYjeG8bjE6PShmC5v gcSiOpq1lnBSfF2MsgTY9uHFaXOHYHcjjxi+cAL3OAOMbYZOOFyP4p2V0rFFhJ/Y65P9 OAlfZJgF5GO8QZ+B/RbC1h+I4fYKj8uUfZ47yv/tepq/1v0i2dtISUB5e7zdwvqupNzC zVjUFk1NZIn2SQIWdKBflzplZhEzOO1xxsV1Uo5XvyQey+LzwdO/fieNhy+hKL8WkRJK Dq2Z3ipL13IsbVfoJblRM7aDuJSCSpTIdXssOOeDXw91pb3LtHVcIOO7iaut9Il87GWx xBWQ== X-Gm-Message-State: AOAM532m6BouKP+1Ja4V8z8wMBLMBP5vRO7ot9kgQZKm6llEoGNtGnSH oQU/O+5nsVDXkHFD2OmafnaBoR8QyMPcJg== X-Received: by 2002:a05:600c:3d94:b0:39c:1c04:3191 with SMTP id bi20-20020a05600c3d9400b0039c1c043191mr2937724wmb.171.1654013376898; Tue, 31 May 2022 09:09:36 -0700 (PDT) Received: from lmecxl1178.lme.st.com ([2a04:cec0:117a:a94e:9569:2e63:8a35:2cc5]) by smtp.gmail.com with ESMTPSA id r23-20020a05600c321700b0039aa4d054f8sm2884035wmp.5.2022.05.31.09.09.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 May 2022 09:09:36 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Patrick Delaunay , Patrice Chotard , etienne.carriere@linaro.org Subject: [PATCH v2 01/14] firmware: scmi: optee: use TEE shared memory for SCMI messages Date: Tue, 31 May 2022 18:09:16 +0200 Message-Id: <20220531160929.931150-2-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220531160929.931150-1-etienne.carriere@linaro.org> References: <20220531160929.931150-1-etienne.carriere@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Changes implementation when using TEE dynamically allocated shared memory to synchronize with the Linux implementation where the legacy SMT protocol cannot be used with such memory since it is expected from device mapped memory whereas OP-TEE shared memory is cached and hence should not be accessed using memcpy_toio()/memcpy_fromio(). This change implements the MSG shared memory protocol introduced in Linux [1]. The protocol uses a simplified SMT header of 32bit named MSG_SMT to carry SCMI protocol information and uses side channel means to carry exchanged buffer size information, as TEE invocation API parameters when used in the SCMI OP-TEE transport. Link: [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f301bba0ca7392d16a6ea4f1d264a91f1fadea1a Signed-off-by: Etienne Carriere --- No change since v1. --- drivers/firmware/scmi/optee_agent.c | 68 ++++++++++++++++++++++------- drivers/firmware/scmi/smt.c | 53 +++++++++++++++++++++- drivers/firmware/scmi/smt.h | 45 ++++++++++++++++++- 3 files changed, 149 insertions(+), 17 deletions(-) diff --git a/drivers/firmware/scmi/optee_agent.c b/drivers/firmware/scmi/optee_agent.c index 1f265922343..e76f738bbaf 100644 --- a/drivers/firmware/scmi/optee_agent.c +++ b/drivers/firmware/scmi/optee_agent.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2020-2021 Linaro Limited. + * Copyright (C) 2020-2022 Linaro Limited. */ #define LOG_CATEGORY UCLASS_SCMI_AGENT @@ -98,6 +98,22 @@ enum optee_smci_pta_cmd { * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps) */ PTA_SCMI_CMD_GET_CHANNEL = 3, + + /* + * PTA_SCMI_CMD_PROCESS_MSG_CHANNEL - Process SCMI message in MSG + * buffers pointed by memref parameters + * + * [in] value[0].a: Channel handle + * [in] memref[1]: Message buffer (MSG header and SCMI payload) + * [out] memref[2]: Response buffer (MSG header and SCMI payload) + * + * Shared memories used for SCMI message/response are MSG buffers + * referenced by param[1] and param[2]. MSG transport protocol + * uses a 32bit header to carry SCMI meta-data (protocol ID and + * protocol message ID) followed by the effective SCMI message + * payload. + */ + PTA_SCMI_CMD_PROCESS_MSG_CHANNEL = 4, }; /* @@ -106,9 +122,17 @@ enum optee_smci_pta_cmd { * PTA_SCMI_CAPS_SMT_HEADER * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in * shared memory buffers to carry SCMI protocol synchronisation information. + * + * PTA_SCMI_CAPS_MSG_HEADER + * When set, OP-TEE supports command using MSG header protocol in an OP-TEE + * shared memory to carry SCMI protocol synchronisation information and SCMI + * message payload. */ #define PTA_SCMI_CAPS_NONE 0 #define PTA_SCMI_CAPS_SMT_HEADER BIT(0) +#define PTA_SCMI_CAPS_MSG_HEADER BIT(1) +#define PTA_SCMI_CAPS_MASK (PTA_SCMI_CAPS_SMT_HEADER | \ + PTA_SCMI_CAPS_MSG_HEADER) static int open_channel(struct udevice *dev, struct channel_session *sess) { @@ -139,7 +163,10 @@ static int open_channel(struct udevice *dev, struct channel_session *sess) param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT; param[0].u.value.a = chan->channel_id; - param[0].u.value.b = PTA_SCMI_CAPS_SMT_HEADER; + if (chan->dyn_shm) + param[0].u.value.b = PTA_SCMI_CAPS_MSG_HEADER; + else + param[0].u.value.b = PTA_SCMI_CAPS_SMT_HEADER; ret = tee_invoke_func(sess->tee, &cmd_arg, ARRAY_SIZE(param), param); if (ret || cmd_arg.ret) { @@ -167,34 +194,48 @@ static int invoke_cmd(struct udevice *dev, struct channel_session *sess, { struct scmi_optee_channel *chan = dev_get_plat(dev); struct tee_invoke_arg arg = { }; - struct tee_param param[2] = { }; + struct tee_param param[3] = { }; int ret; - scmi_write_msg_to_smt(dev, &chan->smt, msg); - arg.session = sess->tee_session; param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; param[0].u.value.a = sess->channel_hdl; - if (chan->dyn_shm) { - arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE; - param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT; + if (sess->tee_shm) { + size_t in_size; + + ret = scmi_msg_to_smt_msg(dev, &chan->smt, msg, &in_size); + if (ret < 0) + return ret; + + arg.func = PTA_SCMI_CMD_PROCESS_MSG_CHANNEL; + param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT; param[1].u.memref.shm = sess->tee_shm; - param[1].u.memref.size = SCMI_SHM_SIZE; + param[1].u.memref.size = in_size; + param[2].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param[2].u.memref.shm = sess->tee_shm; + param[2].u.memref.size = sess->tee_shm->size; } else { arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL; + scmi_write_msg_to_smt(dev, &chan->smt, msg); } ret = tee_invoke_func(sess->tee, &arg, ARRAY_SIZE(param), param); if (ret || arg.ret) { if (!ret) ret = -EPROTO; + + return ret; + } + + if (sess->tee_shm) { + ret = scmi_msg_from_smt_msg(dev, &chan->smt, msg, + param[2].u.memref.size); } else { ret = scmi_read_resp_from_smt(dev, &chan->smt, msg); + scmi_clear_smt_channel(&chan->smt); } - scmi_clear_smt_channel(&chan->smt); - return ret; } @@ -217,9 +258,6 @@ static int prepare_shm(struct udevice *dev, struct channel_session *sess) chan->smt.buf = sess->tee_shm->addr; - /* Initialize shm buffer for message exchanges */ - scmi_clear_smt_channel(&chan->smt); - return 0; } @@ -233,7 +271,7 @@ static void release_shm(struct udevice *dev, struct channel_session *sess) static int scmi_optee_process_msg(struct udevice *dev, struct scmi_msg *msg) { - struct channel_session sess; + struct channel_session sess = { }; int ret; ret = open_channel(dev, &sess); diff --git a/drivers/firmware/scmi/smt.c b/drivers/firmware/scmi/smt.c index e60c2aebc89..509ed618a99 100644 --- a/drivers/firmware/scmi/smt.c +++ b/drivers/firmware/scmi/smt.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (C) 2019-2020 Linaro Limited. + * Copyright (C) 2019-2022 Linaro Limited. */ #define LOG_CATEGORY UCLASS_SCMI_AGENT @@ -137,3 +137,54 @@ void scmi_clear_smt_channel(struct scmi_smt *smt) hdr->channel_status &= ~SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR; } + +/** + * Write SCMI message @msg into a SMT_MSG shared buffer @smt. + * Return 0 on success and with a negative errno in case of error. + */ +int scmi_msg_to_smt_msg(struct udevice *dev, struct scmi_smt *smt, + struct scmi_msg *msg, size_t *buf_size) +{ + struct scmi_smt_msg_header *hdr = (void *)smt->buf; + + if ((!msg->in_msg && msg->in_msg_sz) || + (!msg->out_msg && msg->out_msg_sz)) + return -EINVAL; + + if (smt->size < (sizeof(*hdr) + msg->in_msg_sz) || + smt->size < (sizeof(*hdr) + msg->out_msg_sz)) { + dev_dbg(dev, "Buffer too small\n"); + return -ETOOSMALL; + } + + *buf_size = msg->in_msg_sz + sizeof(hdr->msg_header); + + hdr->msg_header = SMT_HEADER_TOKEN(0) | + SMT_HEADER_MESSAGE_TYPE(0) | + SMT_HEADER_PROTOCOL_ID(msg->protocol_id) | + SMT_HEADER_MESSAGE_ID(msg->message_id); + + memcpy(hdr->msg_payload, msg->in_msg, msg->in_msg_sz); + + return 0; +} + +/** + * Read SCMI message from a SMT shared buffer @smt and copy it into @msg. + * Return 0 on success and with a negative errno in case of error. + */ +int scmi_msg_from_smt_msg(struct udevice *dev, struct scmi_smt *smt, + struct scmi_msg *msg, size_t buf_size) +{ + struct scmi_smt_msg_header *hdr = (void *)smt->buf; + + if (buf_size > msg->out_msg_sz + sizeof(hdr->msg_header)) { + dev_err(dev, "Buffer to small\n"); + return -ETOOSMALL; + } + + msg->out_msg_sz = buf_size - sizeof(hdr->msg_header); + memcpy(msg->out_msg, hdr->msg_payload, msg->out_msg_sz); + + return 0; +} diff --git a/drivers/firmware/scmi/smt.h b/drivers/firmware/scmi/smt.h index a8c0987bd30..9d669a6c922 100644 --- a/drivers/firmware/scmi/smt.h +++ b/drivers/firmware/scmi/smt.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved. - * Copyright (C) 2019-2020 Linaro Limited. + * Copyright (C) 2019-2022 Linaro Limited. */ #ifndef SCMI_SMT_H #define SCMI_SMT_H @@ -29,6 +29,17 @@ struct scmi_smt_header { u8 msg_payload[0]; }; +/** + * struct scmi_msg_header - Description of a MSG shared memory message buffer + * + * MSG communication protocol uses a 32bit header memory cell to store SCMI + * protocol data followed by the exchange SCMI message payload. + */ +struct scmi_smt_msg_header { + __le32 msg_header; + u8 msg_payload[0]; +}; + #define SMT_HEADER_TOKEN(token) (((token) << 18) & GENMASK(31, 18)) #define SMT_HEADER_PROTOCOL_ID(proto) (((proto) << 10) & GENMASK(17, 10)) #define SMT_HEADER_MESSAGE_TYPE(type) (((type) << 18) & GENMASK(9, 8)) @@ -75,12 +86,44 @@ static inline void scmi_smt_put_channel(struct scmi_smt *smt) int scmi_dt_get_smt_buffer(struct udevice *dev, struct scmi_smt *smt); +/* + * Write SCMI message to a SMT shared memory + * @dev: SCMI device + * @smt: Reference to shared memory using SMT header + * @msg: Input SCMI message transmitted + */ int scmi_write_msg_to_smt(struct udevice *dev, struct scmi_smt *smt, struct scmi_msg *msg); +/* + * Read SCMI message from a SMT shared memory + * @dev: SCMI device + * @smt: Reference to shared memory using SMT header + * @msg: Output SCMI message received + */ int scmi_read_resp_from_smt(struct udevice *dev, struct scmi_smt *smt, struct scmi_msg *msg); void scmi_clear_smt_channel(struct scmi_smt *smt); +/* + * Write SCMI message to SMT_MSG shared memory + * @dev: SCMI device + * @smt: Reference to shared memory using SMT_MSG header + * @msg: Input SCMI message transmitted + * @buf_size: Size of the full SMT_MSG buffer transmitted + */ +int scmi_msg_to_smt_msg(struct udevice *dev, struct scmi_smt *smt, + struct scmi_msg *msg, size_t *buf_size); + +/* + * Read SCMI message from SMT_MSG shared memory + * @dev: SCMI device + * @smt: Reference to shared memory using SMT_MSG header + * @msg: Output SCMI message received + * @buf_size: Size of the full SMT_MSG buffer received + */ +int scmi_msg_from_smt_msg(struct udevice *dev, struct scmi_smt *smt, + struct scmi_msg *msg, size_t buf_size); + #endif /* SCMI_SMT_H */