Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

optee: probe RPMB device using RPMB subsystem

Adds support in the OP-TEE drivers (both SMC and FF-A ABIs) to probe and
use an RPMB device via the RPMB subsystem instead of passing the RPMB
frames via tee-supplicant in user space. A fallback mechanism is kept to
route RPMB frames via tee-supplicant if the RPMB subsystem isn't
available.

The OP-TEE RPC ABI is extended to support iterating over all RPMB
devices until one is found with the expected RPMB key already
programmed.

Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Tested-by: Manuel Traut <manut@mecka.net>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Link: https://lore.kernel.org/r/20240814153558.708365-5-jens.wiklander@linaro.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Jens Wiklander and committed by
Ulf Hansson
f0c84315 c30b855e

+387 -2
+15
Documentation/ABI/testing/sysfs-class-tee
··· 1 + What: /sys/class/tee/tee{,priv}X/rpmb_routing_model 2 + Date: May 2024 3 + KernelVersion: 6.10 4 + Contact: op-tee@lists.trustedfirmware.org 5 + Description: 6 + RPMB frames can be routed to the RPMB device via the 7 + user-space daemon tee-supplicant or the RPMB subsystem 8 + in the kernel. The value "user" means that the driver 9 + will route the RPMB frames via user space. Conversely, 10 + "kernel" means that the frames are routed via the RPMB 11 + subsystem without assistance from tee-supplicant. It 12 + should be assumed that RPMB frames are routed via user 13 + space if the variable is absent. The primary purpose 14 + of this variable is to let systemd know whether 15 + tee-supplicant is needed in the early boot with initramfs.
+1
MAINTAINERS
··· 22458 22458 R: Sumit Garg <sumit.garg@linaro.org> 22459 22459 L: op-tee@lists.trustedfirmware.org 22460 22460 S: Maintained 22461 + F: Documentation/ABI/testing/sysfs-class-tee 22461 22462 F: Documentation/driver-api/tee.rst 22462 22463 F: Documentation/tee/ 22463 22464 F: Documentation/userspace-api/tee.rst
+95 -1
drivers/tee/optee/core.c
··· 10 10 #include <linux/errno.h> 11 11 #include <linux/io.h> 12 12 #include <linux/module.h> 13 + #include <linux/rpmb.h> 13 14 #include <linux/slab.h> 14 15 #include <linux/string.h> 15 16 #include <linux/tee_core.h> 16 17 #include <linux/types.h> 17 18 #include "optee_private.h" 18 19 20 + struct blocking_notifier_head optee_rpmb_intf_added = 21 + BLOCKING_NOTIFIER_INIT(optee_rpmb_intf_added); 22 + 23 + static 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 + 31 + static struct class_interface rpmb_class_intf = { 32 + .add_dev = rpmb_add_dev, 33 + }; 34 + 35 + void 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 + 49 + int 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 + 19 59 static void optee_bus_scan(struct work_struct *work) 20 60 { 21 61 WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP)); 62 + } 63 + 64 + static 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 + } 77 + static DEVICE_ATTR_RO(rpmb_routing_model); 78 + 79 + static struct attribute *optee_dev_attrs[] = { 80 + &dev_attr_rpmb_routing_model.attr, 81 + NULL 82 + }; 83 + 84 + ATTRIBUTE_GROUPS(optee_dev); 85 + 86 + void 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); 22 90 } 23 91 24 92 int optee_open(struct tee_context *ctx, bool cap_memref_null) ··· 165 97 166 98 void optee_remove_common(struct optee *optee) 167 99 { 100 + blocking_notifier_chain_unregister(&optee_rpmb_intf_added, 101 + &optee->rpmb_intf); 102 + cancel_work_sync(&optee->rpmb_scan_bus_work); 168 103 /* Unregister OP-TEE specific client devices on TEE bus */ 169 104 optee_unregister_devices(); 170 105 ··· 184 113 tee_shm_pool_free(optee->pool); 185 114 optee_supp_uninit(&optee->supp); 186 115 mutex_destroy(&optee->call_queue.mutex); 116 + rpmb_dev_put(optee->rpmb_dev); 117 + mutex_destroy(&optee->rpmb_dev_mutex); 187 118 } 188 119 189 120 static int smc_abi_rc; 190 121 static int ffa_abi_rc; 122 + static bool intf_is_regged; 191 123 192 124 static int __init optee_core_init(void) 193 125 { 126 + int rc; 127 + 194 128 /* 195 129 * The kernel may have crashed at the same time that all available 196 130 * secure world threads were suspended and we cannot reschedule the ··· 206 130 if (is_kdump_kernel()) 207 131 return -ENODEV; 208 132 133 + if (IS_REACHABLE(CONFIG_RPMB)) { 134 + rc = rpmb_interface_register(&rpmb_class_intf); 135 + if (rc) 136 + return rc; 137 + intf_is_regged = true; 138 + } 139 + 209 140 smc_abi_rc = optee_smc_abi_register(); 210 141 ffa_abi_rc = optee_ffa_abi_register(); 211 142 212 143 /* If both failed there's no point with this module */ 213 - if (smc_abi_rc && ffa_abi_rc) 144 + if (smc_abi_rc && ffa_abi_rc) { 145 + if (IS_REACHABLE(CONFIG_RPMB)) { 146 + rpmb_interface_unregister(&rpmb_class_intf); 147 + intf_is_regged = false; 148 + } 214 149 return smc_abi_rc; 150 + } 151 + 215 152 return 0; 216 153 } 217 154 module_init(optee_core_init); 218 155 219 156 static void __exit optee_core_exit(void) 220 157 { 158 + if (IS_REACHABLE(CONFIG_RPMB) && intf_is_regged) { 159 + rpmb_interface_unregister(&rpmb_class_intf); 160 + intf_is_regged = false; 161 + } 162 + 221 163 if (!smc_abi_rc) 222 164 optee_smc_abi_unregister(); 223 165 if (!ffa_abi_rc)
+7
drivers/tee/optee/device.c
··· 43 43 ret = tee_client_invoke_func(ctx, &inv_arg, param); 44 44 if ((ret < 0) || ((inv_arg.ret != TEEC_SUCCESS) && 45 45 (inv_arg.ret != TEEC_ERROR_SHORT_BUFFER))) { 46 + /* 47 + * TEE_ERROR_STORAGE_NOT_AVAILABLE is returned when getting 48 + * the list of device TAs that depends on RPMB but a usable 49 + * RPMB device isn't found. 50 + */ 51 + if (inv_arg.ret == TEE_ERROR_STORAGE_NOT_AVAILABLE) 52 + return -ENODEV; 46 53 pr_err("PTA_CMD_GET_DEVICES invoke function err: %x\n", 47 54 inv_arg.ret); 48 55 return -EINVAL;
+14
drivers/tee/optee/ffa_abi.c
··· 7 7 8 8 #include <linux/arm_ffa.h> 9 9 #include <linux/errno.h> 10 + #include <linux/rpmb.h> 10 11 #include <linux/scatterlist.h> 11 12 #include <linux/sched.h> 12 13 #include <linux/slab.h> ··· 910 909 optee->ffa.bottom_half_value = U32_MAX; 911 910 optee->rpc_param_count = rpc_param_count; 912 911 912 + if (IS_REACHABLE(CONFIG_RPMB) && 913 + (sec_caps & OPTEE_FFA_SEC_CAP_RPMB_PROBE)) 914 + optee->in_kernel_rpmb_routing = true; 915 + 913 916 teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool, 914 917 optee); 915 918 if (IS_ERR(teedev)) { ··· 930 925 } 931 926 optee->supp_teedev = teedev; 932 927 928 + optee_set_dev_group(optee); 929 + 933 930 rc = tee_device_register(optee->teedev); 934 931 if (rc) 935 932 goto err_unreg_supp_teedev; ··· 947 940 optee_cq_init(&optee->call_queue, 0); 948 941 optee_supp_init(&optee->supp); 949 942 optee_shm_arg_cache_init(optee, arg_cache_flags); 943 + mutex_init(&optee->rpmb_dev_mutex); 950 944 ffa_dev_set_drvdata(ffa_dev, optee); 951 945 ctx = teedev_open(optee->teedev); 952 946 if (IS_ERR(ctx)) { ··· 969 961 if (rc) 970 962 goto err_unregister_devices; 971 963 964 + INIT_WORK(&optee->rpmb_scan_bus_work, optee_bus_scan_rpmb); 965 + optee->rpmb_intf.notifier_call = optee_rpmb_intf_rdev; 966 + blocking_notifier_chain_register(&optee_rpmb_intf_added, 967 + &optee->rpmb_intf); 972 968 pr_info("initialized driver\n"); 973 969 return 0; 974 970 ··· 986 974 teedev_close_context(ctx); 987 975 err_rhashtable_free: 988 976 rhashtable_free_and_destroy(&optee->ffa.global_ids, rh_free_fn, NULL); 977 + rpmb_dev_put(optee->rpmb_dev); 978 + mutex_destroy(&optee->rpmb_dev_mutex); 989 979 optee_supp_uninit(&optee->supp); 990 980 mutex_destroy(&optee->call_queue.mutex); 991 981 mutex_destroy(&optee->ffa.mutex);
+2
drivers/tee/optee/optee_ffa.h
··· 92 92 #define OPTEE_FFA_SEC_CAP_ARG_OFFSET BIT(0) 93 93 /* OP-TEE supports asynchronous notification via FF-A */ 94 94 #define OPTEE_FFA_SEC_CAP_ASYNC_NOTIF BIT(1) 95 + /* OP-TEE supports probing for RPMB device if needed */ 96 + #define OPTEE_FFA_SEC_CAP_RPMB_PROBE BIT(2) 95 97 96 98 #define OPTEE_FFA_EXCHANGE_CAPABILITIES OPTEE_FFA_BLOCKING_CALL(2) 97 99
+25 -1
drivers/tee/optee/optee_private.h
··· 7 7 #define OPTEE_PRIVATE_H 8 8 9 9 #include <linux/arm-smccc.h> 10 + #include <linux/notifier.h> 10 11 #include <linux/rhashtable.h> 12 + #include <linux/rpmb.h> 11 13 #include <linux/semaphore.h> 12 14 #include <linux/tee_core.h> 13 15 #include <linux/types.h> ··· 22 20 /* Some Global Platform error codes used in this driver */ 23 21 #define TEEC_SUCCESS 0x00000000 24 22 #define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006 23 + #define TEEC_ERROR_ITEM_NOT_FOUND 0xFFFF0008 25 24 #define TEEC_ERROR_NOT_SUPPORTED 0xFFFF000A 26 25 #define TEEC_ERROR_COMMUNICATION 0xFFFF000E 27 26 #define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C ··· 31 28 32 29 /* API Return Codes are from the GP TEE Internal Core API Specification */ 33 30 #define TEE_ERROR_TIMEOUT 0xFFFF3001 31 + #define TEE_ERROR_STORAGE_NOT_AVAILABLE 0xF0100003 34 32 35 33 #define TEEC_ORIGIN_COMMS 0x00000002 36 34 ··· 204 200 * @notif: notification synchronization struct 205 201 * @supp: supplicant synchronization struct for RPC to supplicant 206 202 * @pool: shared memory pool 203 + * @mutex: mutex protecting @rpmb_dev 204 + * @rpmb_dev: current RPMB device or NULL 205 + * @rpmb_scan_bus_done flag if device registation of RPMB dependent devices 206 + * was already done 207 + * @rpmb_scan_bus_work workq to for an RPMB device and to scan optee bus 208 + * and register RPMB dependent optee drivers 207 209 * @rpc_param_count: If > 0 number of RPC parameters to make room for 208 210 * @scan_bus_done flag if device registation was already done. 209 211 * @scan_bus_work workq to scan optee bus and register optee drivers ··· 228 218 struct optee_notif notif; 229 219 struct optee_supp supp; 230 220 struct tee_shm_pool *pool; 221 + /* Protects rpmb_dev pointer */ 222 + struct mutex rpmb_dev_mutex; 223 + struct rpmb_dev *rpmb_dev; 224 + struct notifier_block rpmb_intf; 231 225 unsigned int rpc_param_count; 232 - bool scan_bus_done; 226 + bool scan_bus_done; 227 + bool rpmb_scan_bus_done; 228 + bool in_kernel_rpmb_routing; 233 229 struct work_struct scan_bus_work; 230 + struct work_struct rpmb_scan_bus_work; 234 231 }; 235 232 236 233 struct optee_session { ··· 270 253 size_t num_entries; 271 254 }; 272 255 256 + extern struct blocking_notifier_head optee_rpmb_intf_added; 257 + 273 258 int optee_notif_init(struct optee *optee, u_int max_key); 274 259 void optee_notif_uninit(struct optee *optee); 275 260 int optee_notif_wait(struct optee *optee, u_int key, u32 timeout); ··· 302 283 303 284 #define PTA_CMD_GET_DEVICES 0x0 304 285 #define PTA_CMD_GET_DEVICES_SUPP 0x1 286 + #define PTA_CMD_GET_DEVICES_RPMB 0x2 305 287 int optee_enumerate_devices(u32 func); 306 288 void optee_unregister_devices(void); 289 + void optee_bus_scan_rpmb(struct work_struct *work); 290 + int optee_rpmb_intf_rdev(struct notifier_block *intf, unsigned long action, 291 + void *data); 307 292 293 + void optee_set_dev_group(struct optee *optee); 308 294 void optee_remove_common(struct optee *optee); 309 295 int optee_open(struct tee_context *ctx, bool cap_memref_null); 310 296 void optee_release(struct tee_context *ctx);
+35
drivers/tee/optee/optee_rpc_cmd.h
··· 104 104 /* I2C master control flags */ 105 105 #define OPTEE_RPC_I2C_FLAGS_TEN_BIT BIT(0) 106 106 107 + /* 108 + * Reset RPMB probing 109 + * 110 + * Releases an eventually already used RPMB devices and starts over searching 111 + * for RPMB devices. Returns the kind of shared memory to use in subsequent 112 + * OPTEE_RPC_CMD_RPMB_PROBE_NEXT and OPTEE_RPC_CMD_RPMB calls. 113 + * 114 + * [out] value[0].a OPTEE_RPC_SHM_TYPE_*, the parameter for 115 + * OPTEE_RPC_CMD_SHM_ALLOC 116 + */ 117 + #define OPTEE_RPC_CMD_RPMB_PROBE_RESET 22 118 + 119 + /* 120 + * Probe next RPMB device 121 + * 122 + * [out] value[0].a Type of RPMB device, OPTEE_RPC_RPMB_* 123 + * [out] value[0].b EXT CSD-slice 168 "RPMB Size" 124 + * [out] value[0].c EXT CSD-slice 222 "Reliable Write Sector Count" 125 + * [out] memref[1] Buffer with the raw CID 126 + */ 127 + #define OPTEE_RPC_CMD_RPMB_PROBE_NEXT 23 128 + 129 + /* Type of RPMB device */ 130 + #define OPTEE_RPC_RPMB_EMMC 0 131 + #define OPTEE_RPC_RPMB_UFS 1 132 + #define OPTEE_RPC_RPMB_NVME 2 133 + 134 + /* 135 + * Replay Protected Memory Block access 136 + * 137 + * [in] memref[0] Frames to device 138 + * [out] memref[1] Frames from device 139 + */ 140 + #define OPTEE_RPC_CMD_RPMB_FRAMES 24 141 + 107 142 #endif /*__OPTEE_RPC_CMD_H*/
+2
drivers/tee/optee/optee_smc.h
··· 278 278 #define OPTEE_SMC_SEC_CAP_ASYNC_NOTIF BIT(5) 279 279 /* Secure world supports pre-allocating RPC arg struct */ 280 280 #define OPTEE_SMC_SEC_CAP_RPC_ARG BIT(6) 281 + /* Secure world supports probing for RPMB device if needed */ 282 + #define OPTEE_SMC_SEC_CAP_RPMB_PROBE BIT(7) 281 283 282 284 #define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES 9 283 285 #define OPTEE_SMC_EXCHANGE_CAPABILITIES \
+177
drivers/tee/optee/rpc.c
··· 7 7 8 8 #include <linux/delay.h> 9 9 #include <linux/i2c.h> 10 + #include <linux/rpmb.h> 10 11 #include <linux/slab.h> 11 12 #include <linux/tee_core.h> 12 13 #include "optee_private.h" ··· 262 261 optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_FREE, 1, &param); 263 262 } 264 263 264 + static void handle_rpc_func_rpmb_probe_reset(struct tee_context *ctx, 265 + struct optee *optee, 266 + struct optee_msg_arg *arg) 267 + { 268 + struct tee_param params[1]; 269 + 270 + if (arg->num_params != ARRAY_SIZE(params) || 271 + optee->ops->from_msg_param(optee, params, arg->num_params, 272 + arg->params) || 273 + params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT) { 274 + arg->ret = TEEC_ERROR_BAD_PARAMETERS; 275 + return; 276 + } 277 + 278 + params[0].u.value.a = OPTEE_RPC_SHM_TYPE_KERNEL; 279 + params[0].u.value.b = 0; 280 + params[0].u.value.c = 0; 281 + if (optee->ops->to_msg_param(optee, arg->params, 282 + arg->num_params, params)) { 283 + arg->ret = TEEC_ERROR_BAD_PARAMETERS; 284 + return; 285 + } 286 + 287 + mutex_lock(&optee->rpmb_dev_mutex); 288 + rpmb_dev_put(optee->rpmb_dev); 289 + optee->rpmb_dev = NULL; 290 + mutex_unlock(&optee->rpmb_dev_mutex); 291 + 292 + arg->ret = TEEC_SUCCESS; 293 + } 294 + 295 + static int rpmb_type_to_rpc_type(enum rpmb_type rtype) 296 + { 297 + switch (rtype) { 298 + case RPMB_TYPE_EMMC: 299 + return OPTEE_RPC_RPMB_EMMC; 300 + case RPMB_TYPE_UFS: 301 + return OPTEE_RPC_RPMB_UFS; 302 + case RPMB_TYPE_NVME: 303 + return OPTEE_RPC_RPMB_NVME; 304 + default: 305 + return -1; 306 + } 307 + } 308 + 309 + static int rpc_rpmb_match(struct device *dev, const void *data) 310 + { 311 + struct rpmb_dev *rdev = to_rpmb_dev(dev); 312 + 313 + return rpmb_type_to_rpc_type(rdev->descr.type) >= 0; 314 + } 315 + 316 + static void handle_rpc_func_rpmb_probe_next(struct tee_context *ctx, 317 + struct optee *optee, 318 + struct optee_msg_arg *arg) 319 + { 320 + struct rpmb_dev *rdev; 321 + struct tee_param params[2]; 322 + void *buf; 323 + 324 + if (arg->num_params != ARRAY_SIZE(params) || 325 + optee->ops->from_msg_param(optee, params, arg->num_params, 326 + arg->params) || 327 + params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT || 328 + params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) { 329 + arg->ret = TEEC_ERROR_BAD_PARAMETERS; 330 + return; 331 + } 332 + buf = tee_shm_get_va(params[1].u.memref.shm, 333 + params[1].u.memref.shm_offs); 334 + if (!buf) { 335 + arg->ret = TEEC_ERROR_BAD_PARAMETERS; 336 + return; 337 + } 338 + 339 + mutex_lock(&optee->rpmb_dev_mutex); 340 + rdev = rpmb_dev_find_device(NULL, optee->rpmb_dev, rpc_rpmb_match); 341 + rpmb_dev_put(optee->rpmb_dev); 342 + optee->rpmb_dev = rdev; 343 + mutex_unlock(&optee->rpmb_dev_mutex); 344 + 345 + if (!rdev) { 346 + arg->ret = TEEC_ERROR_ITEM_NOT_FOUND; 347 + return; 348 + } 349 + 350 + if (params[1].u.memref.size < rdev->descr.dev_id_len) { 351 + arg->ret = TEEC_ERROR_SHORT_BUFFER; 352 + return; 353 + } 354 + memcpy(buf, rdev->descr.dev_id, rdev->descr.dev_id_len); 355 + params[1].u.memref.size = rdev->descr.dev_id_len; 356 + params[0].u.value.a = rpmb_type_to_rpc_type(rdev->descr.type); 357 + params[0].u.value.b = rdev->descr.capacity; 358 + params[0].u.value.c = rdev->descr.reliable_wr_count; 359 + if (optee->ops->to_msg_param(optee, arg->params, 360 + arg->num_params, params)) { 361 + arg->ret = TEEC_ERROR_BAD_PARAMETERS; 362 + return; 363 + } 364 + 365 + arg->ret = TEEC_SUCCESS; 366 + } 367 + 368 + static void handle_rpc_func_rpmb_frames(struct tee_context *ctx, 369 + struct optee *optee, 370 + struct optee_msg_arg *arg) 371 + { 372 + struct tee_param params[2]; 373 + struct rpmb_dev *rdev; 374 + void *p0, *p1; 375 + 376 + mutex_lock(&optee->rpmb_dev_mutex); 377 + rdev = rpmb_dev_get(optee->rpmb_dev); 378 + mutex_unlock(&optee->rpmb_dev_mutex); 379 + if (!rdev) { 380 + arg->ret = TEEC_ERROR_ITEM_NOT_FOUND; 381 + return; 382 + } 383 + 384 + if (arg->num_params != ARRAY_SIZE(params) || 385 + optee->ops->from_msg_param(optee, params, arg->num_params, 386 + arg->params) || 387 + params[0].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT || 388 + params[1].attr != TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) { 389 + arg->ret = TEEC_ERROR_BAD_PARAMETERS; 390 + goto out; 391 + } 392 + 393 + p0 = tee_shm_get_va(params[0].u.memref.shm, 394 + params[0].u.memref.shm_offs); 395 + p1 = tee_shm_get_va(params[1].u.memref.shm, 396 + params[1].u.memref.shm_offs); 397 + if (rpmb_route_frames(rdev, p0, params[0].u.memref.size, p1, 398 + params[1].u.memref.size)) { 399 + arg->ret = TEEC_ERROR_BAD_PARAMETERS; 400 + goto out; 401 + } 402 + if (optee->ops->to_msg_param(optee, arg->params, 403 + arg->num_params, params)) { 404 + arg->ret = TEEC_ERROR_BAD_PARAMETERS; 405 + goto out; 406 + } 407 + arg->ret = TEEC_SUCCESS; 408 + out: 409 + rpmb_dev_put(rdev); 410 + } 411 + 265 412 void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee, 266 413 struct optee_msg_arg *arg) 267 414 { ··· 425 276 break; 426 277 case OPTEE_RPC_CMD_I2C_TRANSFER: 427 278 handle_rpc_func_cmd_i2c_transfer(ctx, arg); 279 + break; 280 + /* 281 + * optee->in_kernel_rpmb_routing true means that OP-TEE supports 282 + * in-kernel RPMB routing _and_ that the RPMB subsystem is 283 + * reachable. This is reported to user space with 284 + * rpmb_routing_model=kernel in sysfs. 285 + * 286 + * rpmb_routing_model=kernel is also a promise to user space that 287 + * RPMB access will not require supplicant support, hence the 288 + * checks below. 289 + */ 290 + case OPTEE_RPC_CMD_RPMB_PROBE_RESET: 291 + if (optee->in_kernel_rpmb_routing) 292 + handle_rpc_func_rpmb_probe_reset(ctx, optee, arg); 293 + else 294 + handle_rpc_supp_cmd(ctx, optee, arg); 295 + break; 296 + case OPTEE_RPC_CMD_RPMB_PROBE_NEXT: 297 + if (optee->in_kernel_rpmb_routing) 298 + handle_rpc_func_rpmb_probe_next(ctx, optee, arg); 299 + else 300 + handle_rpc_supp_cmd(ctx, optee, arg); 301 + break; 302 + case OPTEE_RPC_CMD_RPMB_FRAMES: 303 + if (optee->in_kernel_rpmb_routing) 304 + handle_rpc_func_rpmb_frames(ctx, optee, arg); 305 + else 306 + handle_rpc_supp_cmd(ctx, optee, arg); 428 307 break; 429 308 default: 430 309 handle_rpc_supp_cmd(ctx, optee, arg);
+14
drivers/tee/optee/smc_abi.c
··· 20 20 #include <linux/of_irq.h> 21 21 #include <linux/of_platform.h> 22 22 #include <linux/platform_device.h> 23 + #include <linux/rpmb.h> 23 24 #include <linux/sched.h> 24 25 #include <linux/slab.h> 25 26 #include <linux/string.h> ··· 1686 1685 optee->smc.sec_caps = sec_caps; 1687 1686 optee->rpc_param_count = rpc_param_count; 1688 1687 1688 + if (IS_REACHABLE(CONFIG_RPMB) && 1689 + (sec_caps & OPTEE_SMC_SEC_CAP_RPMB_PROBE)) 1690 + optee->in_kernel_rpmb_routing = true; 1691 + 1689 1692 teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee); 1690 1693 if (IS_ERR(teedev)) { 1691 1694 rc = PTR_ERR(teedev); ··· 1704 1699 } 1705 1700 optee->supp_teedev = teedev; 1706 1701 1702 + optee_set_dev_group(optee); 1703 + 1707 1704 rc = tee_device_register(optee->teedev); 1708 1705 if (rc) 1709 1706 goto err_unreg_supp_teedev; ··· 1719 1712 optee->smc.memremaped_shm = memremaped_shm; 1720 1713 optee->pool = pool; 1721 1714 optee_shm_arg_cache_init(optee, arg_cache_flags); 1715 + mutex_init(&optee->rpmb_dev_mutex); 1722 1716 1723 1717 platform_set_drvdata(pdev, optee); 1724 1718 ctx = teedev_open(optee->teedev); ··· 1774 1766 if (rc) 1775 1767 goto err_disable_shm_cache; 1776 1768 1769 + INIT_WORK(&optee->rpmb_scan_bus_work, optee_bus_scan_rpmb); 1770 + optee->rpmb_intf.notifier_call = optee_rpmb_intf_rdev; 1771 + blocking_notifier_chain_register(&optee_rpmb_intf_added, 1772 + &optee->rpmb_intf); 1777 1773 pr_info("initialized driver\n"); 1778 1774 return 0; 1779 1775 ··· 1791 1779 err_close_ctx: 1792 1780 teedev_close_context(ctx); 1793 1781 err_supp_uninit: 1782 + rpmb_dev_put(optee->rpmb_dev); 1783 + mutex_destroy(&optee->rpmb_dev_mutex); 1794 1784 optee_shm_arg_cache_uninit(optee); 1795 1785 optee_supp_uninit(&optee->supp); 1796 1786 mutex_destroy(&optee->call_queue.mutex);