device.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2019 Linaro Ltd.
  4. */
  5. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  6. #include <linux/kernel.h>
  7. #include <linux/slab.h>
  8. #include <linux/tee_drv.h>
  9. #include <linux/uuid.h>
  10. #include "optee_private.h"
  11. static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
  12. {
  13. if (ver->impl_id == TEE_IMPL_ID_OPTEE)
  14. return 1;
  15. else
  16. return 0;
  17. }
  18. static int get_devices(struct tee_context *ctx, u32 session,
  19. struct tee_shm *device_shm, u32 *shm_size,
  20. u32 func)
  21. {
  22. int ret = 0;
  23. struct tee_ioctl_invoke_arg inv_arg;
  24. struct tee_param param[4];
  25. memset(&inv_arg, 0, sizeof(inv_arg));
  26. memset(&param, 0, sizeof(param));
  27. inv_arg.func = func;
  28. inv_arg.session = session;
  29. inv_arg.num_params = 4;
  30. /* Fill invoke cmd params */
  31. param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
  32. param[0].u.memref.shm = device_shm;
  33. param[0].u.memref.size = *shm_size;
  34. param[0].u.memref.shm_offs = 0;
  35. ret = tee_client_invoke_func(ctx, &inv_arg, param);
  36. if ((ret < 0) || ((inv_arg.ret != TEEC_SUCCESS) &&
  37. (inv_arg.ret != TEEC_ERROR_SHORT_BUFFER))) {
  38. pr_err("PTA_CMD_GET_DEVICES invoke function err: %x\n",
  39. inv_arg.ret);
  40. return -EINVAL;
  41. }
  42. *shm_size = param[0].u.memref.size;
  43. return 0;
  44. }
  45. static void optee_release_device(struct device *dev)
  46. {
  47. struct tee_client_device *optee_device = to_tee_client_device(dev);
  48. kfree(optee_device);
  49. }
  50. static ssize_t need_supplicant_show(struct device *dev,
  51. struct device_attribute *attr,
  52. char *buf)
  53. {
  54. return 0;
  55. }
  56. static DEVICE_ATTR_RO(need_supplicant);
  57. static int optee_register_device(const uuid_t *device_uuid, u32 func)
  58. {
  59. struct tee_client_device *optee_device = NULL;
  60. int rc;
  61. optee_device = kzalloc(sizeof(*optee_device), GFP_KERNEL);
  62. if (!optee_device)
  63. return -ENOMEM;
  64. optee_device->dev.bus = &tee_bus_type;
  65. optee_device->dev.release = optee_release_device;
  66. if (dev_set_name(&optee_device->dev, "optee-ta-%pUb", device_uuid)) {
  67. kfree(optee_device);
  68. return -ENOMEM;
  69. }
  70. uuid_copy(&optee_device->id.uuid, device_uuid);
  71. rc = device_register(&optee_device->dev);
  72. if (rc) {
  73. pr_err("device registration failed, err: %d\n", rc);
  74. put_device(&optee_device->dev);
  75. }
  76. if (func == PTA_CMD_GET_DEVICES_SUPP)
  77. device_create_file(&optee_device->dev,
  78. &dev_attr_need_supplicant);
  79. return rc;
  80. }
  81. static int __optee_enumerate_devices(u32 func)
  82. {
  83. const uuid_t pta_uuid =
  84. UUID_INIT(0x7011a688, 0xddde, 0x4053,
  85. 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8);
  86. struct tee_ioctl_open_session_arg sess_arg;
  87. struct tee_shm *device_shm = NULL;
  88. const uuid_t *device_uuid = NULL;
  89. struct tee_context *ctx = NULL;
  90. u32 shm_size = 0, idx, num_devices = 0;
  91. int rc;
  92. memset(&sess_arg, 0, sizeof(sess_arg));
  93. /* Open context with OP-TEE driver */
  94. ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL);
  95. if (IS_ERR(ctx))
  96. return -ENODEV;
  97. /* Open session with device enumeration pseudo TA */
  98. export_uuid(sess_arg.uuid, &pta_uuid);
  99. sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
  100. sess_arg.num_params = 0;
  101. rc = tee_client_open_session(ctx, &sess_arg, NULL);
  102. if ((rc < 0) || (sess_arg.ret != TEEC_SUCCESS)) {
  103. /* Device enumeration pseudo TA not found */
  104. rc = 0;
  105. goto out_ctx;
  106. }
  107. rc = get_devices(ctx, sess_arg.session, NULL, &shm_size, func);
  108. if (rc < 0 || !shm_size)
  109. goto out_sess;
  110. device_shm = tee_shm_alloc_kernel_buf(ctx, shm_size);
  111. if (IS_ERR(device_shm)) {
  112. pr_err("tee_shm_alloc_kernel_buf failed\n");
  113. rc = PTR_ERR(device_shm);
  114. goto out_sess;
  115. }
  116. rc = get_devices(ctx, sess_arg.session, device_shm, &shm_size, func);
  117. if (rc < 0)
  118. goto out_shm;
  119. device_uuid = tee_shm_get_va(device_shm, 0);
  120. if (IS_ERR(device_uuid)) {
  121. pr_err("tee_shm_get_va failed\n");
  122. rc = PTR_ERR(device_uuid);
  123. goto out_shm;
  124. }
  125. num_devices = shm_size / sizeof(uuid_t);
  126. for (idx = 0; idx < num_devices; idx++) {
  127. rc = optee_register_device(&device_uuid[idx], func);
  128. if (rc)
  129. goto out_shm;
  130. }
  131. out_shm:
  132. tee_shm_free(device_shm);
  133. out_sess:
  134. tee_client_close_session(ctx, sess_arg.session);
  135. out_ctx:
  136. tee_client_close_context(ctx);
  137. return rc;
  138. }
  139. int optee_enumerate_devices(u32 func)
  140. {
  141. return __optee_enumerate_devices(func);
  142. }
  143. static int __optee_unregister_device(struct device *dev, void *data)
  144. {
  145. if (!strncmp(dev_name(dev), "optee-ta", strlen("optee-ta")))
  146. device_unregister(dev);
  147. return 0;
  148. }
  149. void optee_unregister_devices(void)
  150. {
  151. bus_for_each_dev(&tee_bus_type, NULL, NULL,
  152. __optee_unregister_device);
  153. }