Given that the platform TSM owns IDE Stream ID allocation, report the active streams via the TSM class device. Establish a symlink from the class device to the PCI endpoint device consuming the stream, named by the Stream ID. Acked-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Reviewed-by: Jonathan Cameron <jonathan.cameron@xxxxxxxxxx> Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> --- Documentation/ABI/testing/sysfs-class-tsm | 10 ++++++++ drivers/pci/ide.c | 6 ++++- drivers/pci/pci.h | 2 +- drivers/virt/coco/tsm-core.c | 29 +++++++++++++++++++++++ include/linux/pci-ide.h | 2 ++ include/linux/tsm.h | 3 +++ 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-tsm b/Documentation/ABI/testing/sysfs-class-tsm index 2949468deaf7..6fc1a5ac6da1 100644 --- a/Documentation/ABI/testing/sysfs-class-tsm +++ b/Documentation/ABI/testing/sysfs-class-tsm @@ -7,3 +7,13 @@ Description: signals when the PCI layer is able to support establishment of link encryption and other device-security features coordinated through a platform tsm. + +What: /sys/class/tsm/tsmN/streamH.R.E +Contact: linux-pci@xxxxxxxxxxxxxxx +Description: + (RO) When a host bridge has established a secure connection via + the platform TSM, symlink appears. The primary function of this + is have a system global review of TSM resource consumption + across host bridges. The link points to the endpoint PCI device + and matches the same link published by the host bridge. See + Documentation/ABI/testing/sysfs-devices-pci-host-bridge. diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c index 7383ee542972..3f772979eacb 100644 --- a/drivers/pci/ide.c +++ b/drivers/pci/ide.c @@ -11,6 +11,7 @@ #include <linux/pci_regs.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/tsm.h> #include "pci.h" @@ -272,6 +273,9 @@ void pci_ide_stream_release(struct pci_ide *ide) if (ide->partner[PCI_IDE_EP].enable) pci_ide_stream_disable(pdev, ide); + if (ide->tsm_dev) + tsm_ide_stream_unregister(ide); + if (ide->partner[PCI_IDE_RP].setup) pci_ide_stream_teardown(rp, ide); @@ -551,7 +555,7 @@ static umode_t pci_ide_attr_visible(struct kobject *kobj, struct attribute *a, i return a->mode; } -struct attribute_group pci_ide_attr_group = { +const struct attribute_group pci_ide_attr_group = { .attrs = pci_ide_attrs, .is_visible = pci_ide_attr_visible, }; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 22e0256a10ba..716eb7fecb16 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -521,7 +521,7 @@ static inline void pci_doe_sysfs_teardown(struct pci_dev *pdev) { } #ifdef CONFIG_PCI_IDE void pci_ide_init(struct pci_dev *dev); -extern struct attribute_group pci_ide_attr_group; +extern const struct attribute_group pci_ide_attr_group; #define PCI_IDE_ATTR_GROUP (&pci_ide_attr_group) #else static inline void pci_ide_init(struct pci_dev *dev) { } diff --git a/drivers/virt/coco/tsm-core.c b/drivers/virt/coco/tsm-core.c index 6fdcf23d57ec..f5bab1a9c617 100644 --- a/drivers/virt/coco/tsm-core.c +++ b/drivers/virt/coco/tsm-core.c @@ -2,14 +2,17 @@ /* Copyright(c) 2024 Intel Corporation. All rights reserved. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#define dev_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/tsm.h> #include <linux/idr.h> +#include <linux/pci.h> #include <linux/rwsem.h> #include <linux/device.h> #include <linux/module.h> #include <linux/cleanup.h> #include <linux/pci-tsm.h> +#include <linux/pci-ide.h> static struct class *tsm_class; static DECLARE_RWSEM(tsm_rwsem); @@ -124,6 +127,32 @@ void tsm_unregister(struct tsm_dev *tsm_dev) } EXPORT_SYMBOL_GPL(tsm_unregister); +/* must be invoked between tsm_register / tsm_unregister */ +int tsm_ide_stream_register(struct pci_ide *ide) +{ + struct pci_dev *pdev = ide->pdev; + struct pci_tsm *tsm = pdev->tsm; + struct tsm_dev *tsm_dev = tsm->ops->owner; + int rc; + + rc = sysfs_create_link(&tsm_dev->dev.kobj, &pdev->dev.kobj, ide->name); + if (rc) + return rc; + + ide->tsm_dev = tsm_dev; + return 0; +} +EXPORT_SYMBOL_GPL(tsm_ide_stream_register); + +void tsm_ide_stream_unregister(struct pci_ide *ide) +{ + struct tsm_dev *tsm_dev = ide->tsm_dev; + + sysfs_remove_link(&tsm_dev->dev.kobj, ide->name); + ide->tsm_dev = NULL; +} +EXPORT_SYMBOL_GPL(tsm_ide_stream_unregister); + static void tsm_release(struct device *dev) { struct tsm_dev *tsm_dev = container_of(dev, typeof(*tsm_dev), dev); diff --git a/include/linux/pci-ide.h b/include/linux/pci-ide.h index cf1f7a10e8e0..c3838d11af88 100644 --- a/include/linux/pci-ide.h +++ b/include/linux/pci-ide.h @@ -43,6 +43,7 @@ struct pci_ide_partner { * @host_bridge_stream: track platform Stream ID * @stream_id: unique Stream ID (within Partner Port pairing) * @name: name of the established Selective IDE Stream in sysfs + * @tsm_dev: For TSM established IDE, the TSM device context * * Negative @stream_id values indicate "uninitialized" on the * expectation that with TSM established IDE the TSM owns the stream_id @@ -54,6 +55,7 @@ struct pci_ide { u8 host_bridge_stream; int stream_id; const char *name; + struct tsm_dev *tsm_dev; }; struct pci_ide_partner *pci_ide_to_settings(struct pci_dev *pdev, struct pci_ide *ide); diff --git a/include/linux/tsm.h b/include/linux/tsm.h index c99d85fe56f4..749824498f32 100644 --- a/include/linux/tsm.h +++ b/include/linux/tsm.h @@ -117,4 +117,7 @@ void tsm_unregister(struct tsm_dev *tsm_dev); const char *tsm_name(const struct tsm_dev *tsm_dev); struct tsm_dev *find_tsm_dev(int id); const struct pci_tsm_ops *tsm_pci_ops(const struct tsm_dev *tsm_dev); +struct pci_ide; +int tsm_ide_stream_register(struct pci_ide *ide); +void tsm_ide_stream_unregister(struct pci_ide *ide); #endif /* __TSM_H */ -- 2.50.1