diff options
| -rw-r--r-- | drivers/tee/tee_core.c | 54 | ||||
| -rw-r--r-- | include/linux/mod_devicetable.h | 9 | ||||
| -rw-r--r-- | include/linux/tee_drv.h | 32 | ||||
| -rw-r--r-- | scripts/mod/devicetable-offsets.c | 3 | ||||
| -rw-r--r-- | scripts/mod/file2alias.c | 19 |
5 files changed, 112 insertions, 5 deletions
diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index adf2588282fc..25f3b9cc8908 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #define pr_fmt(fmt) "%s: " fmt, __func__ | 15 | #define pr_fmt(fmt) "%s: " fmt, __func__ |
| 16 | 16 | ||
| 17 | #include <linux/cdev.h> | 17 | #include <linux/cdev.h> |
| 18 | #include <linux/device.h> | ||
| 19 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
| 20 | #include <linux/idr.h> | 19 | #include <linux/idr.h> |
| 21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| @@ -1040,6 +1039,39 @@ int tee_client_invoke_func(struct tee_context *ctx, | |||
| 1040 | } | 1039 | } |
| 1041 | EXPORT_SYMBOL_GPL(tee_client_invoke_func); | 1040 | EXPORT_SYMBOL_GPL(tee_client_invoke_func); |
| 1042 | 1041 | ||
| 1042 | static int tee_client_device_match(struct device *dev, | ||
| 1043 | struct device_driver *drv) | ||
| 1044 | { | ||
| 1045 | const struct tee_client_device_id *id_table; | ||
| 1046 | struct tee_client_device *tee_device; | ||
| 1047 | |||
| 1048 | id_table = to_tee_client_driver(drv)->id_table; | ||
| 1049 | tee_device = to_tee_client_device(dev); | ||
| 1050 | |||
| 1051 | while (!uuid_is_null(&id_table->uuid)) { | ||
| 1052 | if (uuid_equal(&tee_device->id.uuid, &id_table->uuid)) | ||
| 1053 | return 1; | ||
| 1054 | id_table++; | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | return 0; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | static int tee_client_device_uevent(struct device *dev, | ||
| 1061 | struct kobj_uevent_env *env) | ||
| 1062 | { | ||
| 1063 | uuid_t *dev_id = &to_tee_client_device(dev)->id.uuid; | ||
| 1064 | |||
| 1065 | return add_uevent_var(env, "MODALIAS=tee:%pUb", dev_id); | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | struct bus_type tee_bus_type = { | ||
| 1069 | .name = "tee", | ||
| 1070 | .match = tee_client_device_match, | ||
| 1071 | .uevent = tee_client_device_uevent, | ||
| 1072 | }; | ||
| 1073 | EXPORT_SYMBOL_GPL(tee_bus_type); | ||
| 1074 | |||
| 1043 | static int __init tee_init(void) | 1075 | static int __init tee_init(void) |
| 1044 | { | 1076 | { |
| 1045 | int rc; | 1077 | int rc; |
| @@ -1053,18 +1085,32 @@ static int __init tee_init(void) | |||
| 1053 | rc = alloc_chrdev_region(&tee_devt, 0, TEE_NUM_DEVICES, "tee"); | 1085 | rc = alloc_chrdev_region(&tee_devt, 0, TEE_NUM_DEVICES, "tee"); |
| 1054 | if (rc) { | 1086 | if (rc) { |
| 1055 | pr_err("failed to allocate char dev region\n"); | 1087 | pr_err("failed to allocate char dev region\n"); |
| 1056 | class_destroy(tee_class); | 1088 | goto out_unreg_class; |
| 1057 | tee_class = NULL; | 1089 | } |
| 1090 | |||
| 1091 | rc = bus_register(&tee_bus_type); | ||
| 1092 | if (rc) { | ||
| 1093 | pr_err("failed to register tee bus\n"); | ||
| 1094 | goto out_unreg_chrdev; | ||
| 1058 | } | 1095 | } |
| 1059 | 1096 | ||
| 1097 | return 0; | ||
| 1098 | |||
| 1099 | out_unreg_chrdev: | ||
| 1100 | unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES); | ||
| 1101 | out_unreg_class: | ||
| 1102 | class_destroy(tee_class); | ||
| 1103 | tee_class = NULL; | ||
| 1104 | |||
| 1060 | return rc; | 1105 | return rc; |
| 1061 | } | 1106 | } |
| 1062 | 1107 | ||
| 1063 | static void __exit tee_exit(void) | 1108 | static void __exit tee_exit(void) |
| 1064 | { | 1109 | { |
| 1110 | bus_unregister(&tee_bus_type); | ||
| 1111 | unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES); | ||
| 1065 | class_destroy(tee_class); | 1112 | class_destroy(tee_class); |
| 1066 | tee_class = NULL; | 1113 | tee_class = NULL; |
| 1067 | unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES); | ||
| 1068 | } | 1114 | } |
| 1069 | 1115 | ||
| 1070 | subsys_initcall(tee_init); | 1116 | subsys_initcall(tee_init); |
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index f9bd2f34b99f..14eaeeb46f41 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
| @@ -779,4 +779,13 @@ struct typec_device_id { | |||
| 779 | kernel_ulong_t driver_data; | 779 | kernel_ulong_t driver_data; |
| 780 | }; | 780 | }; |
| 781 | 781 | ||
| 782 | /** | ||
| 783 | * struct tee_client_device_id - tee based device identifier | ||
| 784 | * @uuid: For TEE based client devices we use the device uuid as | ||
| 785 | * the identifier. | ||
| 786 | */ | ||
| 787 | struct tee_client_device_id { | ||
| 788 | uuid_t uuid; | ||
| 789 | }; | ||
| 790 | |||
| 782 | #endif /* LINUX_MOD_DEVICETABLE_H */ | 791 | #endif /* LINUX_MOD_DEVICETABLE_H */ |
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 5076502c07d7..56d7f1b4516d 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h | |||
| @@ -15,11 +15,14 @@ | |||
| 15 | #ifndef __TEE_DRV_H | 15 | #ifndef __TEE_DRV_H |
| 16 | #define __TEE_DRV_H | 16 | #define __TEE_DRV_H |
| 17 | 17 | ||
| 18 | #include <linux/types.h> | 18 | #include <linux/device.h> |
| 19 | #include <linux/idr.h> | 19 | #include <linux/idr.h> |
| 20 | #include <linux/kref.h> | 20 | #include <linux/kref.h> |
| 21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
| 22 | #include <linux/mod_devicetable.h> | ||
| 22 | #include <linux/tee.h> | 23 | #include <linux/tee.h> |
| 24 | #include <linux/types.h> | ||
| 25 | #include <linux/uuid.h> | ||
| 23 | 26 | ||
| 24 | /* | 27 | /* |
| 25 | * The file describes the API provided by the generic TEE driver to the | 28 | * The file describes the API provided by the generic TEE driver to the |
| @@ -544,4 +547,31 @@ static inline bool tee_param_is_memref(struct tee_param *param) | |||
| 544 | } | 547 | } |
| 545 | } | 548 | } |
| 546 | 549 | ||
| 550 | extern struct bus_type tee_bus_type; | ||
| 551 | |||
| 552 | /** | ||
| 553 | * struct tee_client_device - tee based device | ||
| 554 | * @id: device identifier | ||
| 555 | * @dev: device structure | ||
| 556 | */ | ||
| 557 | struct tee_client_device { | ||
| 558 | struct tee_client_device_id id; | ||
| 559 | struct device dev; | ||
| 560 | }; | ||
| 561 | |||
| 562 | #define to_tee_client_device(d) container_of(d, struct tee_client_device, dev) | ||
| 563 | |||
| 564 | /** | ||
| 565 | * struct tee_client_driver - tee client driver | ||
| 566 | * @id_table: device id table supported by this driver | ||
| 567 | * @driver: driver structure | ||
| 568 | */ | ||
| 569 | struct tee_client_driver { | ||
| 570 | const struct tee_client_device_id *id_table; | ||
| 571 | struct device_driver driver; | ||
| 572 | }; | ||
| 573 | |||
| 574 | #define to_tee_client_driver(d) \ | ||
| 575 | container_of(d, struct tee_client_driver, driver) | ||
| 576 | |||
| 547 | #endif /*__TEE_DRV_H*/ | 577 | #endif /*__TEE_DRV_H*/ |
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 293004499b4d..160718383a71 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c | |||
| @@ -225,5 +225,8 @@ int main(void) | |||
| 225 | DEVID_FIELD(typec_device_id, svid); | 225 | DEVID_FIELD(typec_device_id, svid); |
| 226 | DEVID_FIELD(typec_device_id, mode); | 226 | DEVID_FIELD(typec_device_id, mode); |
| 227 | 227 | ||
| 228 | DEVID(tee_client_device_id); | ||
| 229 | DEVID_FIELD(tee_client_device_id, uuid); | ||
| 230 | |||
| 228 | return 0; | 231 | return 0; |
| 229 | } | 232 | } |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index a37af7d71973..d0e41723627f 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -37,6 +37,9 @@ typedef unsigned char __u8; | |||
| 37 | typedef struct { | 37 | typedef struct { |
| 38 | __u8 b[16]; | 38 | __u8 b[16]; |
| 39 | } uuid_le; | 39 | } uuid_le; |
| 40 | typedef struct { | ||
| 41 | __u8 b[16]; | ||
| 42 | } uuid_t; | ||
| 40 | 43 | ||
| 41 | /* Big exception to the "don't include kernel headers into userspace, which | 44 | /* Big exception to the "don't include kernel headers into userspace, which |
| 42 | * even potentially has different endianness and word sizes, since | 45 | * even potentially has different endianness and word sizes, since |
| @@ -1287,6 +1290,21 @@ static int do_typec_entry(const char *filename, void *symval, char *alias) | |||
| 1287 | return 1; | 1290 | return 1; |
| 1288 | } | 1291 | } |
| 1289 | 1292 | ||
| 1293 | /* Looks like: tee:uuid */ | ||
| 1294 | static int do_tee_entry(const char *filename, void *symval, char *alias) | ||
| 1295 | { | ||
| 1296 | DEF_FIELD(symval, tee_client_device_id, uuid); | ||
| 1297 | |||
| 1298 | sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", | ||
| 1299 | uuid.b[0], uuid.b[1], uuid.b[2], uuid.b[3], uuid.b[4], | ||
| 1300 | uuid.b[5], uuid.b[6], uuid.b[7], uuid.b[8], uuid.b[9], | ||
| 1301 | uuid.b[10], uuid.b[11], uuid.b[12], uuid.b[13], uuid.b[14], | ||
| 1302 | uuid.b[15]); | ||
| 1303 | |||
| 1304 | add_wildcard(alias); | ||
| 1305 | return 1; | ||
| 1306 | } | ||
| 1307 | |||
| 1290 | /* Does namelen bytes of name exactly match the symbol? */ | 1308 | /* Does namelen bytes of name exactly match the symbol? */ |
| 1291 | static bool sym_is(const char *name, unsigned namelen, const char *symbol) | 1309 | static bool sym_is(const char *name, unsigned namelen, const char *symbol) |
| 1292 | { | 1310 | { |
| @@ -1357,6 +1375,7 @@ static const struct devtable devtable[] = { | |||
| 1357 | {"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry}, | 1375 | {"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry}, |
| 1358 | {"tbsvc", SIZE_tb_service_id, do_tbsvc_entry}, | 1376 | {"tbsvc", SIZE_tb_service_id, do_tbsvc_entry}, |
| 1359 | {"typec", SIZE_typec_device_id, do_typec_entry}, | 1377 | {"typec", SIZE_typec_device_id, do_typec_entry}, |
| 1378 | {"tee", SIZE_tee_client_device_id, do_tee_entry}, | ||
| 1360 | }; | 1379 | }; |
| 1361 | 1380 | ||
| 1362 | /* Create MODULE_ALIAS() statements. | 1381 | /* Create MODULE_ALIAS() statements. |
