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/device.h> 8 #include <linux/module.h> 9 #include <linux/cleanup.h> 10 #include <linux/pci-tsm.h> 11 12 static void tsm_release(struct device *); 13 static const struct class tsm_class = { 14 .name = "tsm", 15 .dev_release = tsm_release 16 }; 17 static DEFINE_IDA(tsm_ida); 18 19 static int match_id(struct device *dev, const void *data) 20 { 21 struct tsm_dev *tsm_dev = container_of(dev, struct tsm_dev, dev); 22 int id = *(const int *)data; 23 24 return tsm_dev->id == id; 25 } 26 27 struct tsm_dev *find_tsm_dev(int id) 28 { 29 struct device *dev = class_find_device(&tsm_class, NULL, &id, match_id); 30 31 if (!dev) 32 return NULL; 33 return container_of(dev, struct tsm_dev, dev); 34 } 35 36 static struct tsm_dev *alloc_tsm_dev(struct device *parent) 37 { 38 struct device *dev; 39 int id; 40 41 struct tsm_dev *tsm_dev __free(kfree) = 42 kzalloc_obj(*tsm_dev); 43 if (!tsm_dev) 44 return ERR_PTR(-ENOMEM); 45 46 id = ida_alloc(&tsm_ida, GFP_KERNEL); 47 if (id < 0) 48 return ERR_PTR(id); 49 50 tsm_dev->id = id; 51 dev = &tsm_dev->dev; 52 dev->parent = parent; 53 dev->class = &tsm_class; 54 device_initialize(dev); 55 56 return no_free_ptr(tsm_dev); 57 } 58 59 static struct tsm_dev *tsm_register_pci_or_reset(struct tsm_dev *tsm_dev, 60 struct pci_tsm_ops *pci_ops) 61 { 62 int rc; 63 64 if (!pci_ops) 65 return tsm_dev; 66 67 tsm_dev->pci_ops = pci_ops; 68 rc = pci_tsm_register(tsm_dev); 69 if (rc) { 70 dev_err(tsm_dev->dev.parent, 71 "PCI/TSM registration failure: %d\n", rc); 72 device_unregister(&tsm_dev->dev); 73 return ERR_PTR(rc); 74 } 75 76 /* Notify TSM userspace that PCI/TSM operations are now possible */ 77 kobject_uevent(&tsm_dev->dev.kobj, KOBJ_CHANGE); 78 return tsm_dev; 79 } 80 81 struct tsm_dev *tsm_register(struct device *parent, struct pci_tsm_ops *pci_ops) 82 { 83 struct tsm_dev *tsm_dev __free(put_tsm_dev) = alloc_tsm_dev(parent); 84 struct device *dev; 85 int rc; 86 87 if (IS_ERR(tsm_dev)) 88 return tsm_dev; 89 90 dev = &tsm_dev->dev; 91 rc = dev_set_name(dev, "tsm%d", tsm_dev->id); 92 if (rc) 93 return ERR_PTR(rc); 94 95 rc = device_add(dev); 96 if (rc) 97 return ERR_PTR(rc); 98 99 return tsm_register_pci_or_reset(no_free_ptr(tsm_dev), pci_ops); 100 } 101 EXPORT_SYMBOL_GPL(tsm_register); 102 103 void tsm_unregister(struct tsm_dev *tsm_dev) 104 { 105 if (tsm_dev->pci_ops) 106 pci_tsm_unregister(tsm_dev); 107 device_unregister(&tsm_dev->dev); 108 } 109 EXPORT_SYMBOL_GPL(tsm_unregister); 110 111 static void tsm_release(struct device *dev) 112 { 113 struct tsm_dev *tsm_dev = container_of(dev, typeof(*tsm_dev), dev); 114 115 ida_free(&tsm_ida, tsm_dev->id); 116 kfree(tsm_dev); 117 } 118 119 static int __init tsm_init(void) 120 { 121 return class_register(&tsm_class); 122 } 123 module_init(tsm_init) 124 125 static void __exit tsm_exit(void) 126 { 127 class_unregister(&tsm_class); 128 } 129 module_exit(tsm_exit) 130 131 MODULE_LICENSE("GPL"); 132 MODULE_DESCRIPTION("TEE Security Manager Class Device"); 133