at v6.13 250 lines 5.9 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2015-2021, Linaro Limited 4 * Copyright (c) 2016, EPAM Systems 5 */ 6 7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 9#include <linux/crash_dump.h> 10#include <linux/errno.h> 11#include <linux/io.h> 12#include <linux/module.h> 13#include <linux/rpmb.h> 14#include <linux/slab.h> 15#include <linux/string.h> 16#include <linux/tee_core.h> 17#include <linux/types.h> 18#include "optee_private.h" 19 20struct blocking_notifier_head optee_rpmb_intf_added = 21 BLOCKING_NOTIFIER_INIT(optee_rpmb_intf_added); 22 23static int rpmb_add_dev(struct device *dev) 24{ 25 blocking_notifier_call_chain(&optee_rpmb_intf_added, 0, 26 to_rpmb_dev(dev)); 27 28 return 0; 29} 30 31static struct class_interface rpmb_class_intf = { 32 .add_dev = rpmb_add_dev, 33}; 34 35void optee_bus_scan_rpmb(struct work_struct *work) 36{ 37 struct optee *optee = container_of(work, struct optee, 38 rpmb_scan_bus_work); 39 int ret; 40 41 if (!optee->rpmb_scan_bus_done) { 42 ret = optee_enumerate_devices(PTA_CMD_GET_DEVICES_RPMB); 43 optee->rpmb_scan_bus_done = !ret; 44 if (ret && ret != -ENODEV) 45 pr_info("Scanning for RPMB device: ret %d\n", ret); 46 } 47} 48 49int optee_rpmb_intf_rdev(struct notifier_block *intf, unsigned long action, 50 void *data) 51{ 52 struct optee *optee = container_of(intf, struct optee, rpmb_intf); 53 54 schedule_work(&optee->rpmb_scan_bus_work); 55 56 return 0; 57} 58 59static void optee_bus_scan(struct work_struct *work) 60{ 61 WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP)); 62} 63 64static ssize_t rpmb_routing_model_show(struct device *dev, 65 struct device_attribute *attr, char *buf) 66{ 67 struct optee *optee = dev_get_drvdata(dev); 68 const char *s; 69 70 if (optee->in_kernel_rpmb_routing) 71 s = "kernel"; 72 else 73 s = "user"; 74 75 return scnprintf(buf, PAGE_SIZE, "%s\n", s); 76} 77static DEVICE_ATTR_RO(rpmb_routing_model); 78 79static struct attribute *optee_dev_attrs[] = { 80 &dev_attr_rpmb_routing_model.attr, 81 NULL 82}; 83 84ATTRIBUTE_GROUPS(optee_dev); 85 86void optee_set_dev_group(struct optee *optee) 87{ 88 tee_device_set_dev_groups(optee->teedev, optee_dev_groups); 89 tee_device_set_dev_groups(optee->supp_teedev, optee_dev_groups); 90} 91 92int optee_open(struct tee_context *ctx, bool cap_memref_null) 93{ 94 struct optee_context_data *ctxdata; 95 struct tee_device *teedev = ctx->teedev; 96 struct optee *optee = tee_get_drvdata(teedev); 97 98 ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL); 99 if (!ctxdata) 100 return -ENOMEM; 101 102 if (teedev == optee->supp_teedev) { 103 bool busy = true; 104 105 mutex_lock(&optee->supp.mutex); 106 if (!optee->supp.ctx) { 107 busy = false; 108 optee->supp.ctx = ctx; 109 } 110 mutex_unlock(&optee->supp.mutex); 111 if (busy) { 112 kfree(ctxdata); 113 return -EBUSY; 114 } 115 116 if (!optee->scan_bus_done) { 117 INIT_WORK(&optee->scan_bus_work, optee_bus_scan); 118 schedule_work(&optee->scan_bus_work); 119 optee->scan_bus_done = true; 120 } 121 } 122 mutex_init(&ctxdata->mutex); 123 INIT_LIST_HEAD(&ctxdata->sess_list); 124 125 ctx->cap_memref_null = cap_memref_null; 126 ctx->data = ctxdata; 127 return 0; 128} 129 130static void optee_release_helper(struct tee_context *ctx, 131 int (*close_session)(struct tee_context *ctx, 132 u32 session, 133 bool system_thread)) 134{ 135 struct optee_context_data *ctxdata = ctx->data; 136 struct optee_session *sess; 137 struct optee_session *sess_tmp; 138 139 if (!ctxdata) 140 return; 141 142 list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, 143 list_node) { 144 list_del(&sess->list_node); 145 close_session(ctx, sess->session_id, sess->use_sys_thread); 146 kfree(sess); 147 } 148 kfree(ctxdata); 149 ctx->data = NULL; 150} 151 152void optee_release(struct tee_context *ctx) 153{ 154 optee_release_helper(ctx, optee_close_session_helper); 155} 156 157void optee_release_supp(struct tee_context *ctx) 158{ 159 struct optee *optee = tee_get_drvdata(ctx->teedev); 160 161 optee_release_helper(ctx, optee_close_session_helper); 162 163 optee_supp_release(&optee->supp); 164} 165 166void optee_remove_common(struct optee *optee) 167{ 168 blocking_notifier_chain_unregister(&optee_rpmb_intf_added, 169 &optee->rpmb_intf); 170 cancel_work_sync(&optee->rpmb_scan_bus_work); 171 /* Unregister OP-TEE specific client devices on TEE bus */ 172 optee_unregister_devices(); 173 174 optee_notif_uninit(optee); 175 optee_shm_arg_cache_uninit(optee); 176 teedev_close_context(optee->ctx); 177 /* 178 * The two devices have to be unregistered before we can free the 179 * other resources. 180 */ 181 tee_device_unregister(optee->supp_teedev); 182 tee_device_unregister(optee->teedev); 183 184 tee_shm_pool_free(optee->pool); 185 optee_supp_uninit(&optee->supp); 186 mutex_destroy(&optee->call_queue.mutex); 187 rpmb_dev_put(optee->rpmb_dev); 188 mutex_destroy(&optee->rpmb_dev_mutex); 189} 190 191static int smc_abi_rc; 192static int ffa_abi_rc; 193static bool intf_is_regged; 194 195static int __init optee_core_init(void) 196{ 197 int rc; 198 199 /* 200 * The kernel may have crashed at the same time that all available 201 * secure world threads were suspended and we cannot reschedule the 202 * suspended threads without access to the crashed kernel's wait_queue. 203 * Therefore, we cannot reliably initialize the OP-TEE driver in the 204 * kdump kernel. 205 */ 206 if (is_kdump_kernel()) 207 return -ENODEV; 208 209 if (IS_REACHABLE(CONFIG_RPMB)) { 210 rc = rpmb_interface_register(&rpmb_class_intf); 211 if (rc) 212 return rc; 213 intf_is_regged = true; 214 } 215 216 smc_abi_rc = optee_smc_abi_register(); 217 ffa_abi_rc = optee_ffa_abi_register(); 218 219 /* If both failed there's no point with this module */ 220 if (smc_abi_rc && ffa_abi_rc) { 221 if (IS_REACHABLE(CONFIG_RPMB)) { 222 rpmb_interface_unregister(&rpmb_class_intf); 223 intf_is_regged = false; 224 } 225 return smc_abi_rc; 226 } 227 228 return 0; 229} 230module_init(optee_core_init); 231 232static void __exit optee_core_exit(void) 233{ 234 if (IS_REACHABLE(CONFIG_RPMB) && intf_is_regged) { 235 rpmb_interface_unregister(&rpmb_class_intf); 236 intf_is_regged = false; 237 } 238 239 if (!smc_abi_rc) 240 optee_smc_abi_unregister(); 241 if (!ffa_abi_rc) 242 optee_ffa_abi_unregister(); 243} 244module_exit(optee_core_exit); 245 246MODULE_AUTHOR("Linaro"); 247MODULE_DESCRIPTION("OP-TEE driver"); 248MODULE_VERSION("1.0"); 249MODULE_LICENSE("GPL v2"); 250MODULE_ALIAS("platform:optee");