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