[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250728135216.48084-25-aneesh.kumar@kernel.org>
Date: Mon, 28 Jul 2025 19:22:01 +0530
From: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@...nel.org>
To: linux-coco@...ts.linux.dev,
kvmarm@...ts.linux.dev
Cc: linux-pci@...r.kernel.org,
linux-kernel@...r.kernel.org,
aik@....com,
lukas@...ner.de,
Samuel Ortiz <sameo@...osinc.com>,
Xu Yilun <yilun.xu@...ux.intel.com>,
Jason Gunthorpe <jgg@...pe.ca>,
Suzuki K Poulose <Suzuki.Poulose@....com>,
Steven Price <steven.price@....com>,
Catalin Marinas <catalin.marinas@....com>,
Marc Zyngier <maz@...nel.org>,
Will Deacon <will@...nel.org>,
Oliver Upton <oliver.upton@...ux.dev>,
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@...nel.org>
Subject: [RFC PATCH v1 24/38] arm64: CCA: Register guest tsm callback
Register the TSM callback if the DA feature is supported by RSI.
Additionally, adjust the build order so that the TSM class is created
before the arm-cca-guest driver initialization.
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@...nel.org>
---
arch/arm64/include/asm/rsi.h | 3 +
arch/arm64/include/asm/rsi_cmds.h | 18 ++++++
arch/arm64/include/asm/rsi_smc.h | 1 +
arch/arm64/kernel/rsi.c | 24 ++++++--
drivers/virt/coco/Makefile | 2 +-
drivers/virt/coco/arm-cca-guest/Kconfig | 8 ++-
drivers/virt/coco/arm-cca-guest/arm-cca.c | 71 ++++++++++++++++++++++-
drivers/virt/coco/arm-cca-guest/rsi-da.h | 27 +++++++++
8 files changed, 144 insertions(+), 10 deletions(-)
create mode 100644 drivers/virt/coco/arm-cca-guest/rsi-da.h
diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h
index 26ef6143562b..35dfbba4767b 100644
--- a/arch/arm64/include/asm/rsi.h
+++ b/arch/arm64/include/asm/rsi.h
@@ -67,4 +67,7 @@ static inline int rsi_set_memory_range_shared(phys_addr_t start,
return rsi_set_memory_range(start, end, RSI_RIPAS_EMPTY,
RSI_CHANGE_DESTROYED);
}
+
+bool rsi_has_da_feature(void);
+
#endif /* __ASM_RSI_H_ */
diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi_cmds.h
index 2c8763876dfb..d4834baeef1b 100644
--- a/arch/arm64/include/asm/rsi_cmds.h
+++ b/arch/arm64/include/asm/rsi_cmds.h
@@ -159,4 +159,22 @@ static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule,
return res.a0;
}
+/**
+ * rsi_features() - Read feature register
+ * @index: Feature register index
+ * @out: Feature register value is written to this pointer
+ *
+ * Return: RSI return code
+ */
+static inline int rsi_features(unsigned long index, unsigned long *out)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(SMC_RSI_FEATURES, index, &res);
+
+ if (out)
+ *out = res.a1;
+ return res.a0;
+}
+
#endif /* __ASM_RSI_CMDS_H */
diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_smc.h
index 6cb070eca9e9..8e486cdef9eb 100644
--- a/arch/arm64/include/asm/rsi_smc.h
+++ b/arch/arm64/include/asm/rsi_smc.h
@@ -53,6 +53,7 @@
*/
#define SMC_RSI_ABI_VERSION SMC_RSI_FID(0x190)
+#define RSI_FEATURE_REGISTER_0_DA BIT(0)
/*
* Read feature register.
*
diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
index bf9ea99e2aa1..ef06c083990a 100644
--- a/arch/arm64/kernel/rsi.c
+++ b/arch/arm64/kernel/rsi.c
@@ -15,6 +15,7 @@
#include <asm/rsi.h>
static struct realm_config config;
+static unsigned long rsi_feat_reg0;
unsigned long prot_ns_shared;
EXPORT_SYMBOL(prot_ns_shared);
@@ -22,6 +23,12 @@ EXPORT_SYMBOL(prot_ns_shared);
DEFINE_STATIC_KEY_FALSE_RO(rsi_present);
EXPORT_SYMBOL(rsi_present);
+bool rsi_has_da_feature(void)
+{
+ return !!u64_get_bits(rsi_feat_reg0, RSI_FEATURE_REGISTER_0_DA);
+}
+EXPORT_SYMBOL_GPL(rsi_has_da_feature);
+
bool cc_platform_has(enum cc_attr attr)
{
switch (attr) {
@@ -128,6 +135,10 @@ void __init arm64_rsi_init(void)
return;
if (WARN_ON(rsi_get_realm_config(&config)))
return;
+
+ if (WARN_ON(rsi_features(0, &rsi_feat_reg0)))
+ return;
+
prot_ns_shared = BIT(config.ipa_bits - 1);
if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))
@@ -141,17 +152,18 @@ void __init arm64_rsi_init(void)
static_branch_enable(&rsi_present);
}
-static struct platform_device rsi_dev = {
+static struct platform_device cca_guest_dev = {
.name = RSI_DEV_NAME,
.id = PLATFORM_DEVID_NONE
};
-static int __init arm64_create_dummy_rsi_dev(void)
+static int __init arm64_create_cca_guest_dev(void)
{
- if (is_realm_world() &&
- platform_device_register(&rsi_dev))
- pr_err("failed to register rsi platform device\n");
+ if (is_realm_world()) {
+ if (!platform_device_register(&cca_guest_dev))
+ pr_info("CCA guest platform device registered.\n");
+ }
return 0;
}
-arch_initcall(arm64_create_dummy_rsi_dev)
+device_initcall(arm64_create_cca_guest_dev)
diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile
index d0a859dd9eaf..4264ee367b3b 100644
--- a/drivers/virt/coco/Makefile
+++ b/drivers/virt/coco/Makefile
@@ -7,8 +7,8 @@ obj-$(CONFIG_EFI_SECRET) += efi_secret/
obj-$(CONFIG_ARM_PKVM_GUEST) += pkvm-guest/
obj-$(CONFIG_SEV_GUEST) += sev-guest/
obj-$(CONFIG_INTEL_TDX_GUEST) += tdx-guest/
-obj-$(CONFIG_ARM_CCA_GUEST) += arm-cca-guest/
obj-$(CONFIG_TSM) += tsm-core.o
obj-y += guest/
+obj-$(CONFIG_ARM_CCA_GUEST) += arm-cca-guest/
obj-$(CONFIG_ARM_CCA_HOST) += arm-cca-host/
diff --git a/drivers/virt/coco/arm-cca-guest/Kconfig b/drivers/virt/coco/arm-cca-guest/Kconfig
index 3f0f013f03f1..410d9c3fb2b3 100644
--- a/drivers/virt/coco/arm-cca-guest/Kconfig
+++ b/drivers/virt/coco/arm-cca-guest/Kconfig
@@ -1,10 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+
config ARM_CCA_GUEST
tristate "Arm CCA Guest driver"
depends on ARM64
+ depends on PCI_TSM
select TSM_REPORTS
+ select TSM
help
- The driver provides userspace interface to request and
+ The driver provides userspace interface to request an
attestation report from the Realm Management Monitor(RMM).
+ If the DA feature is supported, it also register with TSM framework.
If you choose 'M' here, this module will be called
arm-cca-guest.
diff --git a/drivers/virt/coco/arm-cca-guest/arm-cca.c b/drivers/virt/coco/arm-cca-guest/arm-cca.c
index 547fc2c79f7d..3adbbd67e06e 100644
--- a/drivers/virt/coco/arm-cca-guest/arm-cca.c
+++ b/drivers/virt/coco/arm-cca-guest/arm-cca.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2023 ARM Ltd.
+ * Copyright (C) 2025 ARM Ltd.
*/
#include <linux/arm-smccc.h>
@@ -15,6 +15,8 @@
#include <asm/rsi.h>
+#include "rsi-da.h"
+
/**
* struct arm_cca_token_info - a descriptor for the token buffer.
* @challenge: Pointer to the challenge data
@@ -192,6 +194,60 @@ static void unregister_cca_tsm_report(void *data)
tsm_report_unregister(&arm_cca_tsm_report_ops);
}
+static struct pci_tsm *cca_tsm_pci_probe(struct pci_dev *pdev)
+{
+ struct cca_guest_dsc *cca_dsc __free(kfree);
+
+ if (!is_pci_tsm_pf0(pdev))
+ return NULL;
+
+ cca_dsc = kzalloc(sizeof(*cca_dsc), GFP_KERNEL);
+ if (!cca_dsc)
+ return NULL;
+
+ if (pci_tsm_pf0_initialize(pdev, &cca_dsc->pci))
+ return NULL;
+
+ pci_info(pdev, "Guest tsm enabled\n");
+ return &no_free_ptr(cca_dsc)->pci.tsm;
+}
+
+static void cca_tsm_pci_remove(struct pci_tsm *tsm)
+{
+ struct cca_guest_dsc *cca_dsc = to_cca_guest_dsc(tsm->pdev);
+
+ pci_dbg(tsm->pdev, "tsm disabled\n");
+ kfree(cca_dsc);
+}
+
+static const struct pci_tsm_ops cca_pci_ops = {
+ .probe = cca_tsm_pci_probe,
+ .remove = cca_tsm_pci_remove,
+};
+
+static void cca_tsm_unregister(void *tsm)
+{
+ tsm_unregister(tsm);
+}
+
+static int cca_tsm_register(struct platform_device *pdev)
+{
+ struct tsm_core_dev *tsm_core;
+ int rc;
+
+ tsm_core = tsm_register(&pdev->dev, NULL, &cca_pci_ops);
+ if (IS_ERR(tsm_core))
+ return PTR_ERR(tsm_core);
+
+ rc = devm_add_action_or_reset(&pdev->dev, cca_tsm_unregister, tsm_core);
+ if (rc) {
+ cca_tsm_unregister(tsm_core);
+ return rc;
+ }
+
+ return 0;
+}
+
static int cca_guest_probe(struct platform_device *pdev)
{
int ret;
@@ -200,11 +256,22 @@ static int cca_guest_probe(struct platform_device *pdev)
return -ENODEV;
ret = tsm_report_register(&arm_cca_tsm_report_ops, NULL);
- if (ret < 0)
+ if (ret < 0) {
pr_err("Error %d registering with TSM\n", ret);
+ goto err_out;
+ }
ret = devm_add_action_or_reset(&pdev->dev, unregister_cca_tsm_report, NULL);
+ if (ret < 0) {
+ pr_err("Error %d registering devm action\n", ret);
+ unregister_cca_tsm_report(NULL);
+ goto err_out;
+ }
+
+ if (rsi_has_da_feature())
+ ret = cca_tsm_register(pdev);
+err_out:
return ret;
}
diff --git a/drivers/virt/coco/arm-cca-guest/rsi-da.h b/drivers/virt/coco/arm-cca-guest/rsi-da.h
new file mode 100644
index 000000000000..8a4d5f1b0263
--- /dev/null
+++ b/drivers/virt/coco/arm-cca-guest/rsi-da.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2025 ARM Ltd.
+ */
+
+#ifndef RSI_DA_H_
+#define RSI_DA_H_
+
+#include <linux/pci.h>
+#include <linux/pci-tsm.h>
+#include <asm/rsi_smc.h>
+
+
+struct cca_guest_dsc {
+ struct pci_tsm_pf0 pci;
+};
+
+static inline struct cca_guest_dsc *to_cca_guest_dsc(struct pci_dev *pdev)
+{
+ struct pci_tsm *tsm = pdev->tsm;
+
+ if (!tsm)
+ return NULL;
+ return container_of(tsm, struct cca_guest_dsc, pci.tsm);
+}
+
+#endif
--
2.43.0
Powered by blists - more mailing lists