File Index
Files and directories
Sign in
FILE

qcomtee_msg.h

File preview with syntax highlighting.

linux-6.19.14/drivers/tee/qcomtee/qcomtee_msg.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  4 */
  5
  6#ifndef QCOMTEE_MSG_H
  7#define QCOMTEE_MSG_H
  8
  9#include <linux/bitfield.h>
 10
 11/**
 12 * DOC: ''Qualcomm TEE'' (QTEE) Transport Message
 13 *
 14 * There are two buffers shared with QTEE: inbound and outbound buffers.
 15 * The inbound buffer is used for direct object invocation, and the outbound
 16 * buffer is used to make a request from QTEE to the kernel; i.e., a callback
 17 * request.
 18 *
 19 * The unused tail of the outbound buffer is also used for sending and
 20 * receiving asynchronous messages. An asynchronous message is independent of
 21 * the current object invocation (i.e., contents of the inbound buffer) or
 22 * callback request (i.e., the head of the outbound buffer); see
 23 * qcomtee_get_async_buffer(). It is used by endpoints (QTEE or kernel) as an
 24 * optimization to reduce the number of context switches between the secure and
 25 * non-secure worlds.
 26 *
 27 * For instance, QTEE never sends an explicit callback request to release an
 28 * object in the kernel. Instead, it sends asynchronous release messages in the
 29 * outbound buffer when QTEE returns from the previous direct object invocation,
 30 * or appends asynchronous release messages after the current callback request.
 31 *
 32 * QTEE supports two types of arguments in a message: buffer and object
 33 * arguments. Depending on the direction of data flow, they could be input
 34 * buffer (IO) to QTEE, output buffer (OB) from QTEE, input object (IO) to QTEE,
 35 * or output object (OO) from QTEE. Object arguments hold object IDs. Buffer
 36 * arguments hold (offset, size) pairs into the inbound or outbound buffers.
 37 *
 38 * QTEE holds an object table for objects it hosts and exposes to the kernel.
 39 * An object ID is an index to the object table in QTEE.
 40 *
 41 * For the direct object invocation message format in the inbound buffer, see
 42 * &struct qcomtee_msg_object_invoke. For the callback request message format
 43 * in the outbound buffer, see &struct qcomtee_msg_callback. For the message
 44 * format for asynchronous messages in the outbound buffer, see
 45 * &struct qcomtee_async_msg_hdr.
 46 */
 47
 48/**
 49 * define QCOMTEE_MSG_OBJECT_NS_BIT - Non-secure bit
 50 *
 51 * Object ID is a globally unique 32-bit number. IDs referencing objects
 52 * in the kernel should have %QCOMTEE_MSG_OBJECT_NS_BIT set.
 53 */
 54#define QCOMTEE_MSG_OBJECT_NS_BIT BIT(31)
 55
 56/* Static object IDs recognized by QTEE. */
 57#define QCOMTEE_MSG_OBJECT_NULL (0U)
 58#define QCOMTEE_MSG_OBJECT_ROOT (1U)
 59
 60/* Definitions from QTEE as part of the transport protocol. */
 61
 62/* qcomtee_msg_arg is an argument as recognized by QTEE. */
 63union qcomtee_msg_arg {
 64	struct {
 65		u32 offset;
 66		u32 size;
 67	} b;
 68	u32 o;
 69};
 70
 71/* BI and BO payloads in QTEE messages should be at 64-bit boundaries. */
 72#define qcomtee_msg_offset_align(o) ALIGN((o), sizeof(u64))
 73
 74/* Operations for objects are 32-bit. Transport uses the upper 16 bits. */
 75#define QCOMTEE_MSG_OBJECT_OP_MASK GENMASK(15, 0)
 76
 77/* Reserved Operation IDs sent to QTEE: */
 78/* QCOMTEE_MSG_OBJECT_OP_RELEASE - Reduces the refcount and releases the object.
 79 * QCOMTEE_MSG_OBJECT_OP_RETAIN  - Increases the refcount.
 80 *
 81 * These operation IDs are valid for all objects.
 82 */
 83
 84#define QCOMTEE_MSG_OBJECT_OP_RELEASE (QCOMTEE_MSG_OBJECT_OP_MASK - 0)
 85#define QCOMTEE_MSG_OBJECT_OP_RETAIN  (QCOMTEE_MSG_OBJECT_OP_MASK - 1)
 86
 87/* Subset of operations supported by QTEE root object. */
 88
 89#define QCOMTEE_ROOT_OP_REG_WITH_CREDENTIALS	5
 90#define QCOMTEE_ROOT_OP_NOTIFY_DOMAIN_CHANGE	4
 91#define QCOMTEE_ROOT_OP_ADCI_ACCEPT		8
 92#define QCOMTEE_ROOT_OP_ADCI_SHUTDOWN		9
 93
 94/* Subset of operations supported by client_env object. */
 95
 96#define QCOMTEE_CLIENT_ENV_OPEN 0
 97
 98/* List of available QTEE service UIDs and subset of operations. */
 99
100#define QCOMTEE_FEATURE_VER_UID		2033
101#define QCOMTEE_FEATURE_VER_OP_GET	0
102/* Get QTEE version number. */
103#define QCOMTEE_FEATURE_VER_OP_GET_QTEE_ID 10
104#define QTEE_VERSION_GET_MAJOR(x) (((x) >> 22) & 0xffU)
105#define QTEE_VERSION_GET_MINOR(x) (((x) >> 12) & 0xffU)
106#define QTEE_VERSION_GET_PATCH(x) ((x) >> 0 & 0xfffU)
107
108/* Response types as returned from qcomtee_object_invoke_ctx_invoke(). */
109
110/* The message contains a callback request. */
111#define QCOMTEE_RESULT_INBOUND_REQ_NEEDED 3
112
113/**
114 * struct qcomtee_msg_object_invoke - Direct object invocation message.
115 * @ctx: object ID hosted in QTEE.
116 * @op: operation for the object.
117 * @counts: number of different types of arguments in @args.
118 * @args: array of arguments.
119 *
120 * @counts consists of 4 * 4-bit fields. Bits 0 - 3 represent the number of
121 * input buffers, bits 4 - 7 represent the number of output buffers,
122 * bits 8 - 11 represent the number of input objects, and bits 12 - 15
123 * represent the number of output objects. The remaining bits should be zero.
124 *
125 *    15            12 11             8 7              4 3              0
126 *   +----------------+----------------+----------------+----------------+
127 *   |  #OO objects   |  #IO objects   |  #OB buffers   |  #IB buffers   |
128 *   +----------------+----------------+----------------+----------------+
129 *
130 * The maximum number of arguments of each type is defined by
131 * %QCOMTEE_ARGS_PER_TYPE.
132 */
133struct qcomtee_msg_object_invoke {
134	u32 cxt;
135	u32 op;
136	u32 counts;
137	union qcomtee_msg_arg args[];
138};
139
140/* Bit masks for the four 4-bit nibbles holding the counts. */
141#define QCOMTEE_MASK_IB GENMASK(3, 0)
142#define QCOMTEE_MASK_OB GENMASK(7, 4)
143#define QCOMTEE_MASK_IO GENMASK(11, 8)
144#define QCOMTEE_MASK_OO GENMASK(15, 12)
145
146/**
147 * struct qcomtee_msg_callback - Callback request message.
148 * @result: result of operation @op on the object referenced by @cxt.
149 * @cxt: object ID hosted in the kernel.
150 * @op: operation for the object.
151 * @counts: number of different types of arguments in @args.
152 * @args: array of arguments.
153 *
154 * For details of @counts, see &qcomtee_msg_object_invoke.counts.
155 */
156struct qcomtee_msg_callback {
157	u32 result;
158	u32 cxt;
159	u32 op;
160	u32 counts;
161	union qcomtee_msg_arg args[];
162};
163
164/* Offset in the message for the beginning of the buffer argument's contents. */
165#define qcomtee_msg_buffer_args(t, n) \
166	qcomtee_msg_offset_align(struct_size_t(t, args, n))
167/* Pointer to the beginning of a buffer argument's content at an offset. */
168#define qcomtee_msg_offset_to_ptr(m, off) ((void *)&((char *)(m))[(off)])
169
170/* Some helpers to manage msg.counts. */
171
172static inline unsigned int qcomtee_msg_num_ib(u32 counts)
173{
174	return FIELD_GET(QCOMTEE_MASK_IB, counts);
175}
176
177static inline unsigned int qcomtee_msg_num_ob(u32 counts)
178{
179	return FIELD_GET(QCOMTEE_MASK_OB, counts);
180}
181
182static inline unsigned int qcomtee_msg_num_io(u32 counts)
183{
184	return FIELD_GET(QCOMTEE_MASK_IO, counts);
185}
186
187static inline unsigned int qcomtee_msg_num_oo(u32 counts)
188{
189	return FIELD_GET(QCOMTEE_MASK_OO, counts);
190}
191
192static inline unsigned int qcomtee_msg_idx_ib(u32 counts)
193{
194	return 0;
195}
196
197static inline unsigned int qcomtee_msg_idx_ob(u32 counts)
198{
199	return qcomtee_msg_num_ib(counts);
200}
201
202static inline unsigned int qcomtee_msg_idx_io(u32 counts)
203{
204	return qcomtee_msg_idx_ob(counts) + qcomtee_msg_num_ob(counts);
205}
206
207static inline unsigned int qcomtee_msg_idx_oo(u32 counts)
208{
209	return qcomtee_msg_idx_io(counts) + qcomtee_msg_num_io(counts);
210}
211
212#define qcomtee_msg_for_each(i, first, num) \
213	for ((i) = (first); (i) < (first) + (num); (i)++)
214
215#define qcomtee_msg_for_each_input_buffer(i, m)                  \
216	qcomtee_msg_for_each(i, qcomtee_msg_idx_ib((m)->counts), \
217			     qcomtee_msg_num_ib((m)->counts))
218
219#define qcomtee_msg_for_each_output_buffer(i, m)                 \
220	qcomtee_msg_for_each(i, qcomtee_msg_idx_ob((m)->counts), \
221			     qcomtee_msg_num_ob((m)->counts))
222
223#define qcomtee_msg_for_each_input_object(i, m)                  \
224	qcomtee_msg_for_each(i, qcomtee_msg_idx_io((m)->counts), \
225			     qcomtee_msg_num_io((m)->counts))
226
227#define qcomtee_msg_for_each_output_object(i, m)                 \
228	qcomtee_msg_for_each(i, qcomtee_msg_idx_oo((m)->counts), \
229			     qcomtee_msg_num_oo((m)->counts))
230
231/* Sum of arguments in a message. */
232#define qcomtee_msg_args(m) \
233	(qcomtee_msg_idx_oo((m)->counts) + qcomtee_msg_num_oo((m)->counts))
234
235static inline void qcomtee_msg_init(struct qcomtee_msg_object_invoke *msg,
236				    u32 cxt, u32 op, int in_buffer,
237				    int out_buffer, int in_object,
238				    int out_object)
239{
240	u32 counts = 0;
241
242	counts |= (in_buffer & 0xfU);
243	counts |= ((out_buffer - in_buffer) & 0xfU) << 4;
244	counts |= ((in_object - out_buffer) & 0xfU) << 8;
245	counts |= ((out_object - in_object) & 0xfU) << 12;
246
247	msg->cxt = cxt;
248	msg->op = op;
249	msg->counts = counts;
250}
251
252/* Generic error codes. */
253#define QCOMTEE_MSG_OK			0 /* non-specific success code. */
254#define QCOMTEE_MSG_ERROR		1 /* non-specific error. */
255#define QCOMTEE_MSG_ERROR_INVALID	2 /* unsupported/unrecognized request. */
256#define QCOMTEE_MSG_ERROR_SIZE_IN	3 /* supplied buffer/string too large. */
257#define QCOMTEE_MSG_ERROR_SIZE_OUT	4 /* supplied output buffer too small. */
258#define QCOMTEE_MSG_ERROR_USERBASE	10 /* start of user-defined error range. */
259
260/* Transport layer error codes. */
261#define QCOMTEE_MSG_ERROR_DEFUNCT	-90 /* object no longer exists. */
262#define QCOMTEE_MSG_ERROR_ABORT		-91 /* calling thread must exit. */
263#define QCOMTEE_MSG_ERROR_BADOBJ	-92 /* invalid object context. */
264#define QCOMTEE_MSG_ERROR_NOSLOTS	-93 /* caller's object table full. */
265#define QCOMTEE_MSG_ERROR_MAXARGS	-94 /* too many args. */
266#define QCOMTEE_MSG_ERROR_MAXDATA	-95 /* buffers too large. */
267#define QCOMTEE_MSG_ERROR_UNAVAIL	-96 /* the request could not be processed. */
268#define QCOMTEE_MSG_ERROR_KMEM		-97 /* kernel out of memory. */
269#define QCOMTEE_MSG_ERROR_REMOTE	-98 /* local method sent to remote object. */
270#define QCOMTEE_MSG_ERROR_BUSY		-99 /* Object is busy. */
271#define QCOMTEE_MSG_ERROR_TIMEOUT	-103 /* Call Back Object invocation timed out. */
272
273static inline void qcomtee_msg_set_result(struct qcomtee_msg_callback *cb_msg,
274					  int err)
275{
276	if (!err) {
277		cb_msg->result = QCOMTEE_MSG_OK;
278	} else if (err < 0) {
279		/* If err < 0, then it is a transport error. */
280		switch (err) {
281		case -ENOMEM:
282			cb_msg->result = QCOMTEE_MSG_ERROR_KMEM;
283			break;
284		case -ENODEV:
285			cb_msg->result = QCOMTEE_MSG_ERROR_DEFUNCT;
286			break;
287		case -ENOSPC:
288		case -EBUSY:
289			cb_msg->result = QCOMTEE_MSG_ERROR_BUSY;
290			break;
291		case -EBADF:
292		case -EINVAL:
293			cb_msg->result = QCOMTEE_MSG_ERROR_UNAVAIL;
294			break;
295		default:
296			cb_msg->result = QCOMTEE_MSG_ERROR;
297		}
298	} else {
299		/* If err > 0, then it is user defined error, pass it as is. */
300		cb_msg->result = err;
301	}
302}
303
304#endif /* QCOMTEE_MSG_H */
~/ Read-only file preview.