primordial_obj.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  4. */
  5. #include <linux/delay.h>
  6. #include "qcomtee.h"
  7. /**
  8. * DOC: Primordial Object
  9. *
  10. * After boot, the kernel provides a static object of type
  11. * %QCOMTEE_OBJECT_TYPE_CB called the primordial object. This object is used
  12. * for native kernel services or privileged operations.
  13. *
  14. * We support:
  15. * - %QCOMTEE_OBJECT_OP_MAP_REGION to map a memory object and return mapping
  16. * object and mapping information (see qcomtee_mem_object_map()).
  17. * - %QCOMTEE_OBJECT_OP_YIELD to yield by the thread running in QTEE.
  18. * - %QCOMTEE_OBJECT_OP_SLEEP to wait for a period of time.
  19. */
  20. #define QCOMTEE_OBJECT_OP_MAP_REGION 0
  21. #define QCOMTEE_OBJECT_OP_YIELD 1
  22. #define QCOMTEE_OBJECT_OP_SLEEP 2
  23. /* Mapping information format as expected by QTEE. */
  24. struct qcomtee_mapping_info {
  25. u64 paddr;
  26. u64 len;
  27. u32 perms;
  28. } __packed;
  29. static int
  30. qcomtee_primordial_obj_dispatch(struct qcomtee_object_invoke_ctx *oic,
  31. struct qcomtee_object *primordial_object_unused,
  32. u32 op, struct qcomtee_arg *args)
  33. {
  34. struct qcomtee_mapping_info *map_info;
  35. struct qcomtee_object *mem_object;
  36. struct qcomtee_object *map_object;
  37. int err = 0;
  38. switch (op) {
  39. case QCOMTEE_OBJECT_OP_YIELD:
  40. cond_resched();
  41. /* No output object. */
  42. oic->data = NULL;
  43. break;
  44. case QCOMTEE_OBJECT_OP_SLEEP:
  45. /* Check message format matched QCOMTEE_OBJECT_OP_SLEEP op. */
  46. if (qcomtee_args_len(args) != 1 ||
  47. args[0].type != QCOMTEE_ARG_TYPE_IB ||
  48. args[0].b.size < sizeof(u32))
  49. return -EINVAL;
  50. msleep(*(u32 *)(args[0].b.addr));
  51. /* No output object. */
  52. oic->data = NULL;
  53. break;
  54. case QCOMTEE_OBJECT_OP_MAP_REGION:
  55. if (qcomtee_args_len(args) != 3 ||
  56. args[0].type != QCOMTEE_ARG_TYPE_OB ||
  57. args[1].type != QCOMTEE_ARG_TYPE_IO ||
  58. args[2].type != QCOMTEE_ARG_TYPE_OO ||
  59. args[0].b.size < sizeof(struct qcomtee_mapping_info))
  60. return -EINVAL;
  61. map_info = args[0].b.addr;
  62. mem_object = args[1].o;
  63. qcomtee_mem_object_map(mem_object, &map_object,
  64. &map_info->paddr, &map_info->len,
  65. &map_info->perms);
  66. args[2].o = map_object;
  67. /* One output object; pass it for cleanup to notify. */
  68. oic->data = map_object;
  69. qcomtee_object_put(mem_object);
  70. break;
  71. default:
  72. err = -EINVAL;
  73. }
  74. return err;
  75. }
  76. /* Called after submitting the callback response. */
  77. static void qcomtee_primordial_obj_notify(struct qcomtee_object_invoke_ctx *oic,
  78. struct qcomtee_object *unused,
  79. int err)
  80. {
  81. struct qcomtee_object *object = oic->data;
  82. /* If err, QTEE did not obtain mapping object. Drop it. */
  83. if (object && err)
  84. qcomtee_object_put(object);
  85. }
  86. static struct qcomtee_object_operations qcomtee_primordial_obj_ops = {
  87. .dispatch = qcomtee_primordial_obj_dispatch,
  88. .notify = qcomtee_primordial_obj_notify,
  89. };
  90. struct qcomtee_object qcomtee_primordial_object = {
  91. .name = "primordial",
  92. .object_type = QCOMTEE_OBJECT_TYPE_CB,
  93. .ops = &qcomtee_primordial_obj_ops
  94. };