[RFC PATCH v2 6/6] tdx_tsm: TEE Security Manager driver for TDX

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Recall that a TEE Security Manager (TSM) is a platform agent that speaks
the TEE Device Interface Security Protocol (TDISP) to PCIe devices and
manages private memory resources for the platform. The tdx_tsm driver
loads against a device of the same name registered at TDX Module
initialization time. The device lives on the "tdx" bus which is a
virtual subsystem that hosts the TDX module sysfs ABI.

It allows for device-security enumeration and initialization flows to be
deferred from TDX Module init time. Crucially, when / if TDX Module
init moves earlier in x86 initialization flow this driver is still
guaranteed to run after IOMMU and PCI init (i.e. subsys_initcall() vs
device_initcall()).

The ability to unload the module, or unbind the driver is also useful
for debug and coarse grained transitioning between PCI TSM operation and
PCI CMA operation (native kernel PCI device authentication).

For now this is the basic boilerplate with sysfs attributes and
operation flows to be added later.

Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
---
 arch/x86/include/asm/shared/tdx.h |    3 ++
 arch/x86/virt/vmx/tdx/tdx.c       |    9 ++++-
 drivers/virt/coco/host/Kconfig    |    6 +++
 drivers/virt/coco/host/Makefile   |    2 +
 drivers/virt/coco/host/tdx_tsm.c  |   68 +++++++++++++++++++++++++++++++++++++
 5 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 drivers/virt/coco/host/tdx_tsm.c

diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
index fdfd41511b02..7cc5cfb65e8d 100644
--- a/arch/x86/include/asm/shared/tdx.h
+++ b/arch/x86/include/asm/shared/tdx.h
@@ -132,5 +132,8 @@ static __always_inline u64 hcall_func(u64 exit_reason)
         return exit_reason;
 }
 
+/* tdx_tsm driver interfaces */
+extern const struct bus_type tdx_subsys;
+
 #endif /* !__ASSEMBLY__ */
 #endif /* _ASM_X86_SHARED_TDX_H */
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index e23bddf31daa..13b285e4e91e 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1099,9 +1099,16 @@ static int init_tdmrs(struct tdmr_info_list *tdmr_list)
 	return 0;
 }
 
-static const struct bus_type tdx_subsys = {
+static int tdx_uevent(const struct device *dev, struct kobj_uevent_env *env)
+{
+	return add_uevent_var(env, "MODALIAS=%s", dev_name(dev));
+}
+
+const struct bus_type tdx_subsys = {
 	.name = "tdx",
+	.uevent = tdx_uevent,
 };
+EXPORT_SYMBOL_NS_GPL(tdx_subsys, TDX);
 
 struct tdx_tsm {
 	struct device dev;
diff --git a/drivers/virt/coco/host/Kconfig b/drivers/virt/coco/host/Kconfig
index 4fbc6ef34f12..2155507b8516 100644
--- a/drivers/virt/coco/host/Kconfig
+++ b/drivers/virt/coco/host/Kconfig
@@ -4,3 +4,9 @@
 #
 config TSM
 	tristate
+
+config TDX_TSM
+	depends on INTEL_TDX_HOST
+	select PCI_TSM
+	select TSM
+	tristate
diff --git a/drivers/virt/coco/host/Makefile b/drivers/virt/coco/host/Makefile
index be0aba6007cd..2612f17ec966 100644
--- a/drivers/virt/coco/host/Makefile
+++ b/drivers/virt/coco/host/Makefile
@@ -4,3 +4,5 @@
 
 obj-$(CONFIG_TSM) += tsm.o
 tsm-y := tsm-core.o
+
+obj-$(CONFIG_TDX_TSM) += tdx_tsm.o
diff --git a/drivers/virt/coco/host/tdx_tsm.c b/drivers/virt/coco/host/tdx_tsm.c
new file mode 100644
index 000000000000..95d1352589c9
--- /dev/null
+++ b/drivers/virt/coco/host/tdx_tsm.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
+#include <linux/tsm.h>
+#include <linux/pci-tsm.h>
+#include <asm/tdx.h>
+
+static int tdx_tsm_add(struct pci_dev *pdev)
+{
+	return 0;
+}
+
+static void tdx_tsm_del(struct pci_dev *pdev)
+{
+}
+
+static int tdx_tsm_exec(struct pci_dev *pdev, enum pci_tsm_cmd cmd)
+{
+	return -EOPNOTSUPP;
+}
+
+static const struct pci_tsm_ops tdx_pci_tsm_ops = {
+	.add = tdx_tsm_add,
+	.del = tdx_tsm_del,
+	.exec = tdx_tsm_exec,
+};
+
+static void unregister_tsm(void *subsys)
+{
+	tsm_unregister(subsys);
+}
+
+static int tdx_tsm_probe(struct device *dev)
+{
+	struct tsm_subsys *subsys;
+
+	subsys = tsm_register(dev, NULL, &tdx_pci_tsm_ops);
+	if (IS_ERR(subsys)) {
+		dev_err(dev, "failed to register TSM: (%pe)\n", subsys);
+		return PTR_ERR(subsys);
+	}
+
+	return devm_add_action_or_reset(dev, unregister_tsm, subsys);
+}
+
+static struct device_driver tdx_tsm_driver = {
+	.probe = tdx_tsm_probe,
+	.bus = &tdx_subsys,
+	.owner = THIS_MODULE,
+	.name = KBUILD_MODNAME,
+	.mod_name = KBUILD_MODNAME,
+};
+
+static int __init tdx_tsm_init(void)
+{
+	return driver_register(&tdx_tsm_driver);
+}
+module_init(tdx_tsm_init);
+
+static void __exit tdx_tsm_exit(void)
+{
+	driver_unregister(&tdx_tsm_driver);
+}
+module_exit(tdx_tsm_exit);
+
+MODULE_IMPORT_NS(TDX);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("tdx_tsm");
+MODULE_DESCRIPTION("TDX TEE Security Manager");





[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux