1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef QCOMTEE_H
#define QCOMTEE_H
#include <linux/kobject.h>
#include <linux/tee_core.h>
#include "qcomtee_msg.h"
#include "qcomtee_object.h"
/* Flags relating to object reference. */
#define QCOMTEE_OBJREF_FLAG_TEE BIT(0)
#define QCOMTEE_OBJREF_FLAG_USER BIT(1)
#define QCOMTEE_OBJREF_FLAG_MEM BIT(2)
/**
* struct qcomtee - Main service struct.
* @teedev: client device.
* @pool: shared memory pool.
* @ctx: driver private context.
* @oic: context to use for the current driver invocation.
* @wq: workqueue for QTEE async operations.
* @xa_local_objects: array of objects exported to QTEE.
* @xa_last_id: next ID to allocate.
* @qtee_version: QTEE version.
*/
struct qcomtee {
struct tee_device *teedev;
struct tee_shm_pool *pool;
struct tee_context *ctx;
struct qcomtee_object_invoke_ctx oic;
struct workqueue_struct *wq;
struct xarray xa_local_objects;
u32 xa_last_id;
u32 qtee_version;
};
void qcomtee_fetch_async_reqs(struct qcomtee_object_invoke_ctx *oic);
struct qcomtee_object *qcomtee_idx_erase(struct qcomtee_object_invoke_ctx *oic,
u32 idx);
struct tee_shm_pool *qcomtee_shm_pool_alloc(void);
void qcomtee_msg_buffers_free(struct qcomtee_object_invoke_ctx *oic);
int qcomtee_msg_buffers_alloc(struct qcomtee_object_invoke_ctx *oic,
struct qcomtee_arg *u);
/**
* qcomtee_object_do_invoke_internal() - Submit an invocation for an object.
* @oic: context to use for the current invocation.
* @object: object being invoked.
* @op: requested operation on the object.
* @u: array of arguments for the current invocation.
* @result: result returned from QTEE.
*
* The caller is responsible for keeping track of the refcount for each
* object, including @object. On return, the caller loses ownership of all
* input objects of type %QCOMTEE_OBJECT_TYPE_CB.
*
* Return: On success, returns 0; on failure, returns < 0.
*/
int qcomtee_object_do_invoke_internal(struct qcomtee_object_invoke_ctx *oic,
struct qcomtee_object *object, u32 op,
struct qcomtee_arg *u, int *result);
/**
* struct qcomtee_context_data - Clients' or supplicants' context.
* @qtee_objects_idr: QTEE objects in this context.
* @qtee_lock: mutex for @qtee_objects_idr.
* @reqs_idr: requests in this context that hold ID.
* @reqs_list: FIFO for requests in PROCESSING or QUEUED state.
* @reqs_lock: mutex for @reqs_idr, @reqs_list and request states.
* @req_c: completion used when the supplicant is waiting for requests.
* @released: state of this context.
*/
struct qcomtee_context_data {
struct idr qtee_objects_idr;
/* Synchronize access to @qtee_objects_idr. */
struct mutex qtee_lock;
struct idr reqs_idr;
struct list_head reqs_list;
/* Synchronize access to @reqs_idr, @reqs_list and updating requests states. */
struct mutex reqs_lock;
struct completion req_c;
bool released;
};
int qcomtee_context_add_qtee_object(struct tee_param *param,
struct qcomtee_object *object,
struct tee_context *ctx);
int qcomtee_context_find_qtee_object(struct qcomtee_object **object,
struct tee_param *param,
struct tee_context *ctx);
void qcomtee_context_del_qtee_object(struct tee_param *param,
struct tee_context *ctx);
int qcomtee_objref_to_arg(struct qcomtee_arg *arg, struct tee_param *param,
struct tee_context *ctx);
int qcomtee_objref_from_arg(struct tee_param *param, struct qcomtee_arg *arg,
struct tee_context *ctx);
/* OBJECTS: */
/* (1) User Object API. */
int is_qcomtee_user_object(struct qcomtee_object *object);
void qcomtee_user_object_set_notify(struct qcomtee_object *object, bool notify);
void qcomtee_requests_destroy(struct qcomtee_context_data *ctxdata);
int qcomtee_user_param_to_object(struct qcomtee_object **object,
struct tee_param *param,
struct tee_context *ctx);
int qcomtee_user_param_from_object(struct tee_param *param,
struct qcomtee_object *object,
struct tee_context *ctx);
/**
* struct qcomtee_user_object_request_data - Data for user object request.
* @id: ID assigned to the request.
* @object_id: Object ID being invoked by QTEE.
* @op: Requested operation on object.
* @np: Number of parameters in the request.
*/
struct qcomtee_user_object_request_data {
int id;
u64 object_id;
u32 op;
int np;
};
int qcomtee_user_object_select(struct tee_context *ctx,
struct tee_param *params, int num_params,
void __user *uaddr, size_t size,
struct qcomtee_user_object_request_data *data);
int qcomtee_user_object_submit(struct tee_context *ctx,
struct tee_param *params, int num_params,
int req_id, int errno);
/* (2) Primordial Object. */
extern struct qcomtee_object qcomtee_primordial_object;
/* (3) Memory Object API. */
/* Is it a memory object using tee_shm? */
int is_qcomtee_memobj_object(struct qcomtee_object *object);
/**
* qcomtee_memobj_param_to_object() - OBJREF parameter to &struct qcomtee_object.
* @object: object returned.
* @param: TEE parameter.
* @ctx: context in which the conversion should happen.
*
* @param is an OBJREF with %QCOMTEE_OBJREF_FLAG_MEM flags.
*
* Return: On success return 0 or <0 on failure.
*/
int qcomtee_memobj_param_to_object(struct qcomtee_object **object,
struct tee_param *param,
struct tee_context *ctx);
/* Reverse what qcomtee_memobj_param_to_object() does. */
int qcomtee_memobj_param_from_object(struct tee_param *param,
struct qcomtee_object *object,
struct tee_context *ctx);
/**
* qcomtee_mem_object_map() - Map a memory object.
* @object: memory object.
* @map_object: created mapping object.
* @mem_paddr: physical address of the memory.
* @mem_size: size of the memory.
* @perms: QTEE access permissions.
*
* Return: On success return 0 or <0 on failure.
*/
int qcomtee_mem_object_map(struct qcomtee_object *object,
struct qcomtee_object **map_object, u64 *mem_paddr,
u64 *mem_size, u32 *perms);
#endif /* QCOMTEE_H */
|