Commit 603c646f authored by Dan Williams's avatar Dan Williams
Browse files

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: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Co-developed-by: default avatarAneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Signed-off-by: default avatarAneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarAlexey Kardashevskiy <aik@amd.com>
Link: https://patch.msgid.link/20251031212902.2256310-2-dan.j.williams@intel.com


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 6146a0f1
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
What:		/sys/class/tsm/tsmN
Contact:	linux-coco@lists.linux.dev
Description:
		"tsmN" is a device that represents the generic attributes of a
		platform TEE Security Manager.  It is typically a child of a
		platform enumerated TSM device. /sys/class/tsm/tsmN/uevent
		signals when the PCI layer is able to support establishment of
		link encryption and other device-security features coordinated
		through a platform tsm.
+1 −1
Original line number Diff line number Diff line
@@ -26112,7 +26112,7 @@ M: David Lechner <dlechner@baylibre.com>
S:	Maintained
F:	Documentation/devicetree/bindings/trigger-source/*
TRUSTED SECURITY MODULE (TSM) INFRASTRUCTURE
TRUSTED EXECUTION ENVIRONMENT SECURITY MANAGER (TSM)
M:	Dan Williams <dan.j.williams@intel.com>
L:	linux-coco@lists.linux.dev
S:	Maintained
+3 −0
Original line number Diff line number Diff line
@@ -14,3 +14,6 @@ source "drivers/virt/coco/tdx-guest/Kconfig"
source "drivers/virt/coco/arm-cca-guest/Kconfig"

source "drivers/virt/coco/guest/Kconfig"

config TSM
	bool
+1 −0
Original line number Diff line number Diff line
@@ -7,4 +7,5 @@ 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-$(CONFIG_TSM_GUEST)		+= guest/
+93 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2024-2025 Intel Corporation. All rights reserved. */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/tsm.h>
#include <linux/rwsem.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/cleanup.h>

static struct class *tsm_class;
static DECLARE_RWSEM(tsm_rwsem);
static DEFINE_IDA(tsm_ida);

static struct tsm_dev *alloc_tsm_dev(struct device *parent)
{
	struct device *dev;
	int id;

	struct tsm_dev *tsm_dev __free(kfree) =
		kzalloc(sizeof(*tsm_dev), GFP_KERNEL);
	if (!tsm_dev)
		return ERR_PTR(-ENOMEM);

	id = ida_alloc(&tsm_ida, GFP_KERNEL);
	if (id < 0)
		return ERR_PTR(id);

	tsm_dev->id = id;
	dev = &tsm_dev->dev;
	dev->parent = parent;
	dev->class = tsm_class;
	device_initialize(dev);

	return no_free_ptr(tsm_dev);
}

struct tsm_dev *tsm_register(struct device *parent)
{
	struct tsm_dev *tsm_dev __free(put_tsm_dev) = alloc_tsm_dev(parent);
	struct device *dev;
	int rc;

	if (IS_ERR(tsm_dev))
		return tsm_dev;

	dev = &tsm_dev->dev;
	rc = dev_set_name(dev, "tsm%d", tsm_dev->id);
	if (rc)
		return ERR_PTR(rc);

	rc = device_add(dev);
	if (rc)
		return ERR_PTR(rc);

	return no_free_ptr(tsm_dev);
}
EXPORT_SYMBOL_GPL(tsm_register);

void tsm_unregister(struct tsm_dev *tsm_dev)
{
	device_unregister(&tsm_dev->dev);
}
EXPORT_SYMBOL_GPL(tsm_unregister);

static void tsm_release(struct device *dev)
{
	struct tsm_dev *tsm_dev = container_of(dev, typeof(*tsm_dev), dev);

	ida_free(&tsm_ida, tsm_dev->id);
	kfree(tsm_dev);
}

static int __init tsm_init(void)
{
	tsm_class = class_create("tsm");
	if (IS_ERR(tsm_class))
		return PTR_ERR(tsm_class);

	tsm_class->dev_release = tsm_release;
	return 0;
}
module_init(tsm_init)

static void __exit tsm_exit(void)
{
	class_destroy(tsm_class);
}
module_exit(tsm_exit)

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("TEE Security Manager Class Device");
Loading