File Index
Files and directories
Sign in
FILE

primordial_obj.c

File preview with syntax highlighting.

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