From patchwork Mon Feb 10 23:22:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13969010 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 578D125A35F; Mon, 10 Feb 2025 23:22:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739229762; cv=none; b=Ppv8CjP4im18nR6x+yKubTgL7eHkzwYb7yfEL+G/wPD6KsLCSRTmhQzLaExMU4D8KGz/j1erUE9U1dN4XIooI6Y8Oo8UQv7tP+ZQPFQk2xrdRQgBWQYND8uCHYt2zrf+kxUFWsq3YotKqOybthoL79Uvwp0L6zNjTRt9B1yWkmk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739229762; c=relaxed/simple; bh=Jri1Bit9GFJYEKQbcGESIvgFLxBoU1W44H0a6g5mDZw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IBj2TJrQtKFYdTq2bMH+hlvUa8z1H0GvKHDXy+o76f3G3gtdxblUB81ke3tJDTJyiLlCWwYP/hnrXGZh1Nb7vIJIZyHDNVdk4nw4dOVHOF6+G2COCQt+nuV4IPFDiJ583ZmT4k3tm96UZc/ogXpHXi4XYMgSw5Qhz/aT1eqzGy0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1D016165C; Mon, 10 Feb 2025 15:23:01 -0800 (PST) Received: from beelzebub.ast.arm.com (unknown [10.118.29.240]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 3261D3F6A8; Mon, 10 Feb 2025 15:22:39 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] tpm_crb: implement driver compliant to CRB over FF-A Date: Mon, 10 Feb 2025 17:22:24 -0600 Message-Id: <20250210232227.97761-2-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250210232227.97761-1-stuart.yoder@arm.com> References: <20250210232227.97761-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The Arm specification TPM Service CRB over FF-A specification defines the FF-A messages to interact with a CRB-based TPM implemented as an FF-A secure partition. Spec URL: https://developer.arm.com/documentation/den0138/latest/ This driver is probed when a TPM Secure Partition is discovered by the FF-A subsystem. It exposes APIs used by the TPM CRB driver to send notifications to the TPM. Signed-off-by: Stuart Yoder --- drivers/char/tpm/Kconfig | 9 ++ drivers/char/tpm/Makefile | 1 + drivers/char/tpm/ffa_crb.c | 310 +++++++++++++++++++++++++++++++++++++ drivers/char/tpm/ffa_crb.h | 30 ++++ 4 files changed, 350 insertions(+) create mode 100644 drivers/char/tpm/ffa_crb.c create mode 100644 drivers/char/tpm/ffa_crb.h diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 0fc9a510e059..f02af3925758 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -210,6 +210,15 @@ config TCG_CRB from within Linux. To compile this driver as a module, choose M here; the module will be called tpm_crb. +config TCG_ARM_FFA_CRB + tristate "TPM CRB over Arm FF-A Transport" + depends on ARM_FFA_TRANSPORT + default y if (TCG_CRB && ARM_FFA_TRANSPORT) + help + If the Arm FF-A transport is used to access the TPM say Yes. + To compile this driver as a module, choose M here; the module + will be called ffa_crb. + config TCG_VTPM_PROXY tristate "VTPM Proxy Interface" depends on TCG_TPM diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 9bb142c75243..7c65368e18db 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -42,5 +42,6 @@ obj-$(CONFIG_TCG_IBMVTPM) += tpm_ibmvtpm.o obj-$(CONFIG_TCG_TIS_ST33ZP24) += st33zp24/ obj-$(CONFIG_TCG_XEN) += xen-tpmfront.o obj-$(CONFIG_TCG_CRB) += tpm_crb.o +obj-$(CONFIG_TCG_ARM_FFA_CRB) += ffa_crb.o obj-$(CONFIG_TCG_VTPM_PROXY) += tpm_vtpm_proxy.o obj-$(CONFIG_TCG_FTPM_TEE) += tpm_ftpm_tee.o diff --git a/drivers/char/tpm/ffa_crb.c b/drivers/char/tpm/ffa_crb.c new file mode 100644 index 000000000000..8f11e49956a8 --- /dev/null +++ b/drivers/char/tpm/ffa_crb.c @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Arm Ltd. + * + * Maintained by: + * + * This device driver implements the TPM CRB start method + * as defined in the TPM Service Command Response Buffer + * Interface Over FF-A (DEN0138). + */ + +#define pr_fmt(fmt) "FFA_CRB: " fmt + +#include +#include "ffa_crb.h" + +/* TPM service function status codes */ +#define FFA_CRB_OK 0x05000001 +#define FFA_CRB_OK_RESULTS_RETURNED 0x05000002 +#define FFA_CRB_NOFUNC 0x8e000001 +#define FFA_CRB_NOTSUP 0x8e000002 +#define FFA_CRB_INVARG 0x8e000005 +#define FFA_CRB_INV_CRB_CTRL_DATA 0x8e000006 +#define FFA_CRB_ALREADY 0x8e000009 +#define FFA_CRB_DENIED 0x8e00000a +#define FFA_CRB_NOMEM 0x8e00000b + +#define FFA_CRB_VERSION_MAJOR 1 +#define FFA_CRB_VERSION_MINOR 0 + +/* version encoding */ +#define FFA_CRB_MAJOR_VERSION_MASK GENMASK(30, 16) +#define FFA_CRB_MINOR_VERSION_MASK GENMASK(15, 0) +#define FFA_CRB_MAJOR_VERSION(x) ((u16)(FIELD_GET(FFA_CRB_MAJOR_VERSION_MASK, (x)))) +#define FFA_CRB_MINOR_VERSION(x) ((u16)(FIELD_GET(FFA_CRB_MINOR_VERSION_MASK, (x)))) + +/* + * Normal world sends requests with FFA_MSG_SEND_DIRECT_REQ and + * responses are returned with FFA_MSG_SEND_DIRECT_RESP for normal + * messages. + * + * All requests with FFA_MSG_SEND_DIRECT_REQ and FFA_MSG_SEND_DIRECT_RESP + * are using the AArch32 SMC calling convention with register usage as + * defined in FF-A specification: + * w0: Function ID (0x8400006F or 0x84000070) + * w1: Source/Destination IDs + * w2: Reserved (MBZ) + * w3-w7: Implementation defined, free to be used below + */ + +/* + * Returns the version of the interface that is available + * Call register usage: + * w3: Not used (MBZ) + * w4: TPM service function ID, FFA_CRB_GET_INTERFACE_VERSION + * w5-w7: Reserved (MBZ) + * + * Return register usage: + * w3: Not used (MBZ) + * w4: TPM service function status + * w5: TPM service interface version + * Bits[31:16]: major version + * Bits[15:0]: minor version + * w6-w7: Reserved (MBZ) + * + * Possible function status codes in register w4: + * CRB_FFA_OK_RESULTS_RETURNED: The version of the interface has been + * returned. + */ +#define FFA_CRB_GET_INTERFACE_VERSION 0x0f000001 + +/* + * Return information on a given feature of the TPM service + * Call register usage: + * w3: Not used (MBZ) + * w4: TPM service function ID, FFA_CRB_START + * w5: Start function qualifier + * Bits[31:8] (MBZ) + * Bits[7:0] + * 0: Notifies TPM that a command is ready to be processed + * 1: Notifies TPM that a locality request is ready to be processed + * w6: TPM locality, one of 0..4 + * -If the start function qualifier is 0, identifies the locality + * from where the command originated. + * -If the start function qualifier is 1, identifies the locality + * of the locality request + * w6-w7: Reserved (MBZ) + * + * Return register usage: + * w3: Not used (MBZ) + * w4: TPM service function status + * w5-w7: Reserved (MBZ) + * + * Possible function status codes in register w4: + * FFA_CRB_OK: the TPM service has been notified successfully + * FFA_CRB_INVARG: one or more arguments are not valid + * FFA_CRB_INV_CRB_CTRL_DATA: CRB control data or locality control + * data at the given TPM locality is not valid + * FFA_CRB_DENIED: the TPM has previously disabled locality requests and + * command processing at the given locality + */ +#define FFA_CRB_START 0x0f000201 + +struct ffa_crb { + struct ffa_device *ffa_dev; + u16 major_version; + u16 minor_version; + struct mutex msg_data_lock; + struct ffa_send_direct_data direct_msg_data; +}; + +static struct ffa_crb *ffa_crb; + +static int ffa_crb_to_linux_errno(int errno) +{ + int rc; + + switch (errno) { + case FFA_CRB_OK: + rc = 0; + break; + case FFA_CRB_OK_RESULTS_RETURNED: + rc = 0; + break; + case FFA_CRB_NOFUNC: + rc = -ENOENT; + break; + case FFA_CRB_NOTSUP: + rc = -EPERM; + break; + case FFA_CRB_INVARG: + rc = -EINVAL; + break; + case FFA_CRB_INV_CRB_CTRL_DATA: + rc = -ENOEXEC; + break; + case FFA_CRB_ALREADY: + rc = -EEXIST; + break; + case FFA_CRB_DENIED: + rc = -EACCES; + break; + case FFA_CRB_NOMEM: + rc = -ENOMEM; + break; + default: + rc = -EINVAL; + } + + return rc; +} + +int ffa_crb_init(void) +{ + if (ffa_crb == NULL) + return -ENOENT; + + if (IS_ERR_VALUE(ffa_crb)) + return -ENODEV; + + return 0; +} +EXPORT_SYMBOL_GPL(ffa_crb_init); + +static int __ffa_crb_send_recieve(unsigned long func_id, + unsigned long a0, unsigned long a1, unsigned long a2) +{ + int ret; + const struct ffa_msg_ops *msg_ops; + + if (ffa_crb == NULL) + return -ENOENT; + + msg_ops = ffa_crb->ffa_dev->ops->msg_ops; + + memset(&ffa_crb->direct_msg_data, 0x00, + sizeof(struct ffa_send_direct_data)); + + ffa_crb->direct_msg_data.data1 = func_id; + ffa_crb->direct_msg_data.data2 = a0; + ffa_crb->direct_msg_data.data3 = a1; + ffa_crb->direct_msg_data.data4 = a2; + + ret = msg_ops->sync_send_receive(ffa_crb->ffa_dev, + &ffa_crb->direct_msg_data); + if (!ret) + ret = ffa_crb_to_linux_errno(ffa_crb->direct_msg_data.data1); + + return ret; +} + +int ffa_crb_get_interface_version(uint16_t *major, uint16_t *minor) +{ + int rc; + + if (ffa_crb == NULL) + return -ENOENT; + + if (IS_ERR_VALUE(ffa_crb)) + return -ENODEV; + + if (major == NULL || minor == NULL) + return -EINVAL; + + guard(mutex)(&ffa_crb->msg_data_lock); + + rc = __ffa_crb_send_recieve(FFA_CRB_GET_INTERFACE_VERSION, 0x00, 0x00, 0x00); + if (!rc) { + *major = FFA_CRB_MAJOR_VERSION(ffa_crb->direct_msg_data.data2); + *minor = FFA_CRB_MINOR_VERSION(ffa_crb->direct_msg_data.data2); + } + + return rc; +} +EXPORT_SYMBOL_GPL(ffa_crb_get_interface_version); + +int ffa_crb_start(int request_type, int locality) +{ + if (ffa_crb == NULL) + return -ENOENT; + + if (IS_ERR_VALUE(ffa_crb)) + return -ENODEV; + + guard(mutex)(&ffa_crb->msg_data_lock); + + return __ffa_crb_send_recieve(FFA_CRB_START, request_type, locality, 0x00); +} +EXPORT_SYMBOL_GPL(ffa_crb_start); + +static int ffa_crb_probe(struct ffa_device *ffa_dev) +{ + int rc; + struct ffa_crb *p; + + /* only one instance of a TPM partition is supported */ + if (ffa_crb && !IS_ERR_VALUE(ffa_crb)) + return -EEXIST; + + ffa_crb = ERR_PTR(-ENODEV); // set ffa_crb so we can detect probe failure + + if (!ffa_partition_supports_direct_recv(ffa_dev)) { + pr_err("TPM partition doesn't support direct message receive.\n"); + return -EINVAL; + } + + p = kzalloc(sizeof(*ffa_crb), GFP_KERNEL); + if (!p) + return -ENOMEM; + ffa_crb = p; + + mutex_init(&ffa_crb->msg_data_lock); + ffa_crb->ffa_dev = ffa_dev; + ffa_dev_set_drvdata(ffa_dev, ffa_crb); + + /* if TPM is aarch32 use 32-bit SMCs */ + if (!ffa_partition_check_property(ffa_dev, FFA_PARTITION_AARCH64_EXEC)) + ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev); + + /* verify compatibility of TPM service version number */ + rc = ffa_crb_get_interface_version(&ffa_crb->major_version, + &ffa_crb->minor_version); + if (rc) { + pr_err("failed to get crb interface version. rc:%d", rc); + goto out; + } + + pr_info("ABI version %u.%u", ffa_crb->major_version, + ffa_crb->minor_version); + + if ((ffa_crb->major_version != FFA_CRB_VERSION_MAJOR) || + (ffa_crb->minor_version < FFA_CRB_VERSION_MINOR)) { + pr_err("Incompatible ABI version"); + goto out; + } + + return 0; + +out: + kfree(ffa_crb); + ffa_crb = ERR_PTR(-ENODEV); + return -EINVAL; +} + +static void ffa_crb_remove(struct ffa_device *ffa_dev) +{ + kfree(ffa_crb); + ffa_crb = NULL; +} + +static const struct ffa_device_id ffa_crb_device_id[] = { + /* 17b862a4-1806-4faf-86b3-089a58353861 */ + { UUID_INIT(0x17b862a4, 0x1806, 0x4faf, + 0x86, 0xb3, 0x08, 0x9a, 0x58, 0x35, 0x38, 0x61) }, + {} +}; + +static struct ffa_driver ffa_crb_driver = { + .name = "ffa-crb", + .probe = ffa_crb_probe, + .remove = ffa_crb_remove, + .id_table = ffa_crb_device_id, +}; + +module_ffa_driver(ffa_crb_driver); + +MODULE_AUTHOR("Arm"); +MODULE_DESCRIPTION("FFA CRB driver"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/char/tpm/ffa_crb.h b/drivers/char/tpm/ffa_crb.h new file mode 100644 index 000000000000..42327d285165 --- /dev/null +++ b/drivers/char/tpm/ffa_crb.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Arm Ltd. + * + * Authors: + * Stuart Yoder + * + * Maintained by: + * + * This device driver implements the TPM CRB start method + * as defined in the TPM Service Command Response Buffer + * Interface Over FF-A (DEN0138). + */ +#ifndef _FFA_CRB_H +#define _FFA_CRB_H + +#if IS_ENABLED(CONFIG_TCG_ARM_FFA_CRB) +int ffa_crb_init(void); +int ffa_crb_get_interface_version(uint16_t *major, uint16_t *minor); +int ffa_crb_start(int request_type, int locality); +#else +static inline int ffa_crb_init(void) { return 0; } +static inline int ffa_crb_get_interface_version(uint16_t *major, uint16_t *minor) { return 0; } +static inline int ffa_crb_start(int request_type, int locality) { return 0; } +#endif + +#define FFA_CRB_START_TYPE_COMMAND 0 +#define FFA_CRB_START_TYPE_LOCALITY_REQUEST 1 + +#endif From patchwork Mon Feb 10 23:22:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13969009 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5793325EFBE; Mon, 10 Feb 2025 23:22:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739229762; cv=none; b=iCjqFTS6S0yk4Hps0pa80dFTvp8h5Xzz3vFcvNvO5XRuEhHubl4p65Kh+dqjxk2SGwadEtHu2j/TwPZ316DtCTqxpbZ0mQVnyC6X//w9uWZiTGw707riGBVWHup1Rht6rHTLC4eRi6wSkZQioc5vgoS1cTbymfOJ1xxRA6/plbo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739229762; c=relaxed/simple; bh=ZGhydeZxTvcnRna3S1bP4MtIhyq1lqgmB9PIFRWKoUg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jCsRyWa8iHz/vLoWh2Vfw4QecBpbLB5Bh4JsB9s6dYV8WFEWu4+rxDB02b66myh9ne7K/meYC490XI6ddao8cRnW/CT5nVzBlRMJQ72nRJya0sRJ04KRimE6eI6U48hi870qSQzovc64UuxE78GNONLbzDV/dnpCKSwSTGxRny4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7224E237B; Mon, 10 Feb 2025 15:23:01 -0800 (PST) Received: from beelzebub.ast.arm.com (unknown [10.118.29.240]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 880863F6A8; Mon, 10 Feb 2025 15:22:39 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] tpm_crb: refactor check for idle support into TPM into inline function Date: Mon, 10 Feb 2025 17:22:25 -0600 Message-Id: <20250210232227.97761-3-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250210232227.97761-1-stuart.yoder@arm.com> References: <20250210232227.97761-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Refactor the two checks for whether the TPM supports idle into a single inline function. Signed-off-by: Stuart Yoder --- drivers/char/tpm/tpm_crb.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index ea085b14ab7c..87d69e990249 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -115,6 +115,16 @@ struct tpm2_crb_pluton { u64 reply_addr; }; +static inline bool does_tpm_support_idle(u32 start_method) +{ + if ((start_method == ACPI_TPM2_START_METHOD) || + (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || + (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) + return false; + else + return true; +} + static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, unsigned long timeout) { @@ -173,9 +183,7 @@ static int __crb_go_idle(struct device *dev, struct crb_priv *priv) { int rc; - if ((priv->sm == ACPI_TPM2_START_METHOD) || - (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || - (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) + if (!does_tpm_support_idle(priv->sm)) return 0; iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req); @@ -222,9 +230,7 @@ static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv) { int rc; - if ((priv->sm == ACPI_TPM2_START_METHOD) || - (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || - (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) + if (!does_tpm_support_idle(priv->sm)) return 0; iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req); From patchwork Mon Feb 10 23:22:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13969011 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C3207264607; Mon, 10 Feb 2025 23:22:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739229762; cv=none; b=LrfpVK8DaIcgqIJ7VHbWcQrR2r4cjjQ10G1xeiRbqSqadubJRlVz6MikE/xSNhCURO3U8rMJtUBQLVyoSpKTIUN2Ksg+UtMUCjDIiyc74NRHle5NolhDL5JBZ4MwrSF6O6/SVDXlFNJq8coWw56NHyncTbgzdMZkB/nkO4ILlc8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739229762; c=relaxed/simple; bh=7fRdcNE7xXsaASuPRp2rHOGLwkB9bid5/zMvjIkOD9Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rDhKB+NusR2cIyKfNeXmQlvdLAhhnqxvZ9y6OZN6JuMMBo8d6SS3qcwn99mcRNNq2zyzGmFUqpX/NT4xQ2nx4OZmgnq0heKHsG4WoUmHxuWH8G6s379Wy5uL5rlYPwHAaT6+zcI4fClTsNnkoY4knM2oL2HfJGqYAT2vINmmOBw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D12142381; Mon, 10 Feb 2025 15:23:01 -0800 (PST) Received: from beelzebub.ast.arm.com (unknown [10.118.29.240]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id DD90D3F6A8; Mon, 10 Feb 2025 15:22:39 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/4] ACPICA: add start method for Arm FF-A Date: Mon, 10 Feb 2025 17:22:26 -0600 Message-Id: <20250210232227.97761-4-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250210232227.97761-1-stuart.yoder@arm.com> References: <20250210232227.97761-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add TPM start method for Arm FF-A defined in the TCG ACPI specification v1.4. Signed-off-by: Stuart Yoder --- include/acpi/actbl3.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h index 5cd755143b7d..a97b1dbab975 100644 --- a/include/acpi/actbl3.h +++ b/include/acpi/actbl3.h @@ -466,6 +466,7 @@ struct acpi_tpm2_phy { #define ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC 11 /* V1.2 Rev 8 */ #define ACPI_TPM2_RESERVED 12 #define ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON 13 +#define ACPI_TPM2_CRB_WITH_ARM_FFA 15 /* Optional trailer appears after any start_method subtables */ From patchwork Mon Feb 10 23:22:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stuart Yoder X-Patchwork-Id: 13969013 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 51771260A26; Mon, 10 Feb 2025 23:22:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739229763; cv=none; b=jQB9V1s7rP98ZDHaChGUdF61P3E3Eh7n3+kHpbpdWYaixPcnEoDgGO2sPsrpj1AuAfyAAJHttbP+5NGG5O0ZBdgFA+twpyYdPLtjb58O5gauXe272EGNuMH/WbPO/hWZO5HnnOjVxhPW7NVyp3Am2U+X3cBLMfSMMyo40Bjyhxs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739229763; c=relaxed/simple; bh=lTqR8TSrLKaqkwG6l8djJ5HYN5FLVTnkebp0+wftjSk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jwiDNpfUzprXM/htQBIorCz8BU8/xAsuus0hPkTGztUkT+rm1BgNeSo1fkf30fTk9s1Oa+y3UTrOal+EKfnrxtDQ9VfH4G/xJFgZC6uj8139wEwTvNYgKNxDEG2rs+IQB0FwoAi7GVoCA/tmHaNukWukyqk8pbKqdPwlLLS9OCA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 32B9D2437; Mon, 10 Feb 2025 15:23:02 -0800 (PST) Received: from beelzebub.ast.arm.com (unknown [10.118.29.240]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 486BC3F6A8; Mon, 10 Feb 2025 15:22:40 -0800 (PST) From: Stuart Yoder To: linux-integrity@vger.kernel.org, jarkko@kernel.org, peterhuewe@gmx.de, jgg@ziepe.ca, sudeep.holla@arm.com, rafael@kernel.org, lenb@kernel.org Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] tpm_crb: add support for the Arm FF-A start method Date: Mon, 10 Feb 2025 17:22:27 -0600 Message-Id: <20250210232227.97761-5-stuart.yoder@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250210232227.97761-1-stuart.yoder@arm.com> References: <20250210232227.97761-1-stuart.yoder@arm.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The TCG ACPI spec v1.4 defines a start method for the TPMs implemented with the Arm CRB over FF-A ABI. Add support for the FF-A start method, and use interfaces provided by the ffa_crb driver to interact with the FF-A based TPM. Signed-off-by: Stuart Yoder --- drivers/char/tpm/tpm_crb.c | 65 +++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 87d69e990249..8b36072916a1 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -19,6 +19,7 @@ #ifdef CONFIG_ARM64 #include #endif +#include "ffa_crb.h" #include "tpm.h" #define ACPI_SIG_TPM2 "TPM2" @@ -100,6 +101,8 @@ struct crb_priv { u32 smc_func_id; u32 __iomem *pluton_start_addr; u32 __iomem *pluton_reply_addr; + u8 ffa_flags; + u8 ffa_attributes; }; struct tpm2_crb_smc { @@ -110,6 +113,14 @@ struct tpm2_crb_smc { u32 smc_func_id; }; +/* CRB over FFA start method parameters in TCG2 ACPI table */ +struct tpm2_crb_ffa { + u8 flags; + u8 attributes; + u16 partition_id; + u8 reserved[8]; +}; + struct tpm2_crb_pluton { u64 start_addr; u64 reply_addr; @@ -119,7 +130,8 @@ static inline bool does_tpm_support_idle(u32 start_method) { if ((start_method == ACPI_TPM2_START_METHOD) || (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || - (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) + (start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) || + (start_method == ACPI_TPM2_CRB_WITH_ARM_FFA)) return false; else return true; @@ -261,6 +273,7 @@ static int crb_cmd_ready(struct tpm_chip *chip) static int __crb_request_locality(struct device *dev, struct crb_priv *priv, int loc) { + int rc; u32 value = CRB_LOC_STATE_LOC_ASSIGNED | CRB_LOC_STATE_TPM_REG_VALID_STS; @@ -268,6 +281,13 @@ static int __crb_request_locality(struct device *dev, return 0; iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl); + + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + rc = ffa_crb_start(FFA_CRB_START_TYPE_LOCALITY_REQUEST, loc); + if (rc) + return rc; + } + if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, value, value, TPM2_TIMEOUT_C)) { dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); @@ -287,6 +307,7 @@ static int crb_request_locality(struct tpm_chip *chip, int loc) static int __crb_relinquish_locality(struct device *dev, struct crb_priv *priv, int loc) { + int rc; u32 mask = CRB_LOC_STATE_LOC_ASSIGNED | CRB_LOC_STATE_TPM_REG_VALID_STS; u32 value = CRB_LOC_STATE_TPM_REG_VALID_STS; @@ -295,6 +316,13 @@ static int __crb_relinquish_locality(struct device *dev, return 0; iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl); + + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + rc = ffa_crb_start(FFA_CRB_START_TYPE_LOCALITY_REQUEST, loc); + if (rc) + return rc; + } + if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value, TPM2_TIMEOUT_C)) { dev_warn(dev, "TPM_LOC_STATE_x.Relinquish timed out\n"); @@ -443,6 +471,11 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len) rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id); } + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start); + rc = ffa_crb_start(FFA_CRB_START_TYPE_COMMAND, chip->locality); + } + if (rc) return rc; @@ -451,6 +484,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len) static void crb_cancel(struct tpm_chip *chip) { + int rc; struct crb_priv *priv = dev_get_drvdata(&chip->dev); iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel); @@ -459,6 +493,12 @@ static void crb_cancel(struct tpm_chip *chip) (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)) && crb_do_acpi_start(chip)) dev_err(&chip->dev, "ACPI Start failed\n"); + + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + rc = ffa_crb_start(FFA_CRB_START_TYPE_COMMAND, chip->locality); + if (rc) + dev_err(&chip->dev, "FF-A Start failed\n"); + } } static bool crb_req_canceled(struct tpm_chip *chip, u8 status) @@ -616,6 +656,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, * stuff that puts the control area outside the ACPI IO region. */ if ((priv->sm == ACPI_TPM2_COMMAND_BUFFER) || + (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) || (priv->sm == ACPI_TPM2_MEMORY_MAPPED)) { if (iores && buf->control_address == iores->start + @@ -737,6 +778,7 @@ static int crb_acpi_add(struct acpi_device *device) struct tpm_chip *chip; struct device *dev = &device->dev; struct tpm2_crb_smc *crb_smc; + struct tpm2_crb_ffa *crb_ffa; struct tpm2_crb_pluton *crb_pluton; acpi_status status; u32 sm; @@ -775,6 +817,27 @@ static int crb_acpi_add(struct acpi_device *device) priv->smc_func_id = crb_smc->smc_func_id; } + if (sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { + if (buf->header.length < (sizeof(*buf) + sizeof(*crb_ffa))) { + dev_err(dev, + FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n", + buf->header.length, + ACPI_TPM2_CRB_WITH_ARM_FFA); + rc = -EINVAL; + goto out; + } + crb_ffa = ACPI_ADD_PTR(struct tpm2_crb_ffa, buf, sizeof(*buf)); + priv->ffa_flags = crb_ffa->flags; + priv->ffa_attributes = crb_ffa->attributes; + rc = ffa_crb_init(); + if (rc) { + if (rc == -ENOENT) { // FF-A driver is not available yet + rc = -EPROBE_DEFER; + } + goto out; + } + } + if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) { if (buf->header.length < (sizeof(*buf) + sizeof(*crb_pluton))) { dev_err(dev,