Skip to content

Commit 603c646

Browse files
committed
coco/tsm: Introduce a core device for TEE Security Managers
A "TSM" is a platform component that provides an API for securely provisioning resources for a confidential guest (TVM) to consume. The name originates from the PCI specification for platform agent that carries out operations for PCIe TDISP (TEE Device Interface Security Protocol). Instances of this core device are parented by a device representing the platform security function like CONFIG_CRYPTO_DEV_CCP or CONFIG_INTEL_TDX_HOST. This device interface is a frontend to the aspects of a TSM and TEE I/O that are cross-architecture common. This includes mechanisms like enumerating available platform TEE I/O capabilities and provisioning connections between the platform TSM and device DSMs (Device Security Manager (TDISP)). For now this is just the scaffolding for registering a TSM device sysfs interface. Cc: Xu Yilun <yilun.xu@linux.intel.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Co-developed-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Alexey Kardashevskiy <aik@amd.com> Link: https://patch.msgid.link/20251031212902.2256310-2-dan.j.williams@intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 6146a0f commit 603c646

6 files changed

Lines changed: 118 additions & 1 deletion

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
What: /sys/class/tsm/tsmN
2+
Contact: linux-coco@lists.linux.dev
3+
Description:
4+
"tsmN" is a device that represents the generic attributes of a
5+
platform TEE Security Manager. It is typically a child of a
6+
platform enumerated TSM device. /sys/class/tsm/tsmN/uevent
7+
signals when the PCI layer is able to support establishment of
8+
link encryption and other device-security features coordinated
9+
through a platform tsm.

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26112,7 +26112,7 @@ M: David Lechner <dlechner@baylibre.com>
2611226112
S: Maintained
2611326113
F: Documentation/devicetree/bindings/trigger-source/*
2611426114

26115-
TRUSTED SECURITY MODULE (TSM) INFRASTRUCTURE
26115+
TRUSTED EXECUTION ENVIRONMENT SECURITY MANAGER (TSM)
2611626116
M: Dan Williams <dan.j.williams@intel.com>
2611726117
L: linux-coco@lists.linux.dev
2611826118
S: Maintained

drivers/virt/coco/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ source "drivers/virt/coco/tdx-guest/Kconfig"
1414
source "drivers/virt/coco/arm-cca-guest/Kconfig"
1515

1616
source "drivers/virt/coco/guest/Kconfig"
17+
18+
config TSM
19+
bool

drivers/virt/coco/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ obj-$(CONFIG_ARM_PKVM_GUEST) += pkvm-guest/
77
obj-$(CONFIG_SEV_GUEST) += sev-guest/
88
obj-$(CONFIG_INTEL_TDX_GUEST) += tdx-guest/
99
obj-$(CONFIG_ARM_CCA_GUEST) += arm-cca-guest/
10+
obj-$(CONFIG_TSM) += tsm-core.o
1011
obj-$(CONFIG_TSM_GUEST) += guest/

drivers/virt/coco/tsm-core.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/* Copyright(c) 2024-2025 Intel Corporation. All rights reserved. */
3+
4+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5+
6+
#include <linux/tsm.h>
7+
#include <linux/rwsem.h>
8+
#include <linux/device.h>
9+
#include <linux/module.h>
10+
#include <linux/cleanup.h>
11+
12+
static struct class *tsm_class;
13+
static DECLARE_RWSEM(tsm_rwsem);
14+
static DEFINE_IDA(tsm_ida);
15+
16+
static struct tsm_dev *alloc_tsm_dev(struct device *parent)
17+
{
18+
struct device *dev;
19+
int id;
20+
21+
struct tsm_dev *tsm_dev __free(kfree) =
22+
kzalloc(sizeof(*tsm_dev), GFP_KERNEL);
23+
if (!tsm_dev)
24+
return ERR_PTR(-ENOMEM);
25+
26+
id = ida_alloc(&tsm_ida, GFP_KERNEL);
27+
if (id < 0)
28+
return ERR_PTR(id);
29+
30+
tsm_dev->id = id;
31+
dev = &tsm_dev->dev;
32+
dev->parent = parent;
33+
dev->class = tsm_class;
34+
device_initialize(dev);
35+
36+
return no_free_ptr(tsm_dev);
37+
}
38+
39+
struct tsm_dev *tsm_register(struct device *parent)
40+
{
41+
struct tsm_dev *tsm_dev __free(put_tsm_dev) = alloc_tsm_dev(parent);
42+
struct device *dev;
43+
int rc;
44+
45+
if (IS_ERR(tsm_dev))
46+
return tsm_dev;
47+
48+
dev = &tsm_dev->dev;
49+
rc = dev_set_name(dev, "tsm%d", tsm_dev->id);
50+
if (rc)
51+
return ERR_PTR(rc);
52+
53+
rc = device_add(dev);
54+
if (rc)
55+
return ERR_PTR(rc);
56+
57+
return no_free_ptr(tsm_dev);
58+
}
59+
EXPORT_SYMBOL_GPL(tsm_register);
60+
61+
void tsm_unregister(struct tsm_dev *tsm_dev)
62+
{
63+
device_unregister(&tsm_dev->dev);
64+
}
65+
EXPORT_SYMBOL_GPL(tsm_unregister);
66+
67+
static void tsm_release(struct device *dev)
68+
{
69+
struct tsm_dev *tsm_dev = container_of(dev, typeof(*tsm_dev), dev);
70+
71+
ida_free(&tsm_ida, tsm_dev->id);
72+
kfree(tsm_dev);
73+
}
74+
75+
static int __init tsm_init(void)
76+
{
77+
tsm_class = class_create("tsm");
78+
if (IS_ERR(tsm_class))
79+
return PTR_ERR(tsm_class);
80+
81+
tsm_class->dev_release = tsm_release;
82+
return 0;
83+
}
84+
module_init(tsm_init)
85+
86+
static void __exit tsm_exit(void)
87+
{
88+
class_destroy(tsm_class);
89+
}
90+
module_exit(tsm_exit)
91+
92+
MODULE_LICENSE("GPL");
93+
MODULE_DESCRIPTION("TEE Security Manager Class Device");

include/linux/tsm.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/sizes.h>
66
#include <linux/types.h>
77
#include <linux/uuid.h>
8+
#include <linux/device.h>
89

910
#define TSM_REPORT_INBLOB_MAX 64
1011
#define TSM_REPORT_OUTBLOB_MAX SZ_32K
@@ -107,6 +108,16 @@ struct tsm_report_ops {
107108
bool (*report_bin_attr_visible)(int n);
108109
};
109110

111+
struct tsm_dev {
112+
struct device dev;
113+
int id;
114+
};
115+
116+
DEFINE_FREE(put_tsm_dev, struct tsm_dev *,
117+
if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))
118+
110119
int tsm_report_register(const struct tsm_report_ops *ops, void *priv);
111120
int tsm_report_unregister(const struct tsm_report_ops *ops);
121+
struct tsm_dev *tsm_register(struct device *parent);
122+
void tsm_unregister(struct tsm_dev *tsm_dev);
112123
#endif /* __TSM_H */

0 commit comments

Comments
 (0)