From: Stuart Yoder <stuart.yoder@arm.com>
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 [thread overview]
Message-ID: <20250210232227.97761-5-stuart.yoder@arm.com> (raw)
In-Reply-To: <20250210232227.97761-1-stuart.yoder@arm.com>
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 <stuart.yoder@arm.com>
---
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 <linux/arm-smccc.h>
#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,
--
2.34.1
next prev parent reply other threads:[~2025-02-10 23:22 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-10 23:22 [PATCH 0/4] Add support for the TPM FF-A start method Stuart Yoder
2025-02-10 23:22 ` [PATCH 1/4] tpm_crb: implement driver compliant to CRB over FF-A Stuart Yoder
2025-02-11 21:08 ` Jarkko Sakkinen
2025-02-11 23:21 ` Stuart Yoder
2025-02-10 23:22 ` [PATCH 2/4] tpm_crb: refactor check for idle support into TPM into inline function Stuart Yoder
2025-02-10 23:22 ` [PATCH 3/4] ACPICA: add start method for Arm FF-A Stuart Yoder
2025-02-11 9:57 ` Sudeep Holla
2025-02-11 21:50 ` Stuart Yoder
2025-02-10 23:22 ` Stuart Yoder [this message]
2025-02-11 6:45 ` [PATCH 0/4] Add support for the TPM FF-A start method Sumit Garg
2025-02-11 16:09 ` Stuart Yoder
2025-02-12 7:39 ` Sumit Garg
2025-02-12 21:55 ` Stuart Yoder
2025-02-13 5:31 ` Sumit Garg
2025-02-13 15:19 ` Stuart Yoder
2025-02-17 5:17 ` Sumit Garg
2025-02-17 16:56 ` Stuart Yoder
2025-02-21 13:46 ` Sumit Garg
2025-02-21 14:02 ` Sudeep Holla
2025-02-21 18:29 ` Stuart Yoder
2025-02-22 15:39 ` Sudeep Holla
2025-02-11 10:12 ` Sudeep Holla
2025-02-11 21:07 ` Jarkko Sakkinen
2025-02-11 23:21 ` Stuart Yoder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250210232227.97761-5-stuart.yoder@arm.com \
--to=stuart.yoder@arm.com \
--cc=jarkko@kernel.org \
--cc=jgg@ziepe.ca \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peterhuewe@gmx.de \
--cc=rafael@kernel.org \
--cc=sudeep.holla@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.