1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (c) 2024 Linaro Limited
4 */
5
6#ifndef __TEE_CORE_H
7#define __TEE_CORE_H
8
9#include <linux/cdev.h>
10#include <linux/device.h>
11#include <linux/idr.h>
12#include <linux/kref.h>
13#include <linux/list.h>
14#include <linux/tee.h>
15#include <linux/tee_drv.h>
16#include <linux/types.h>
17#include <linux/uuid.h>
18
19/*
20 * The file describes the API provided by the generic TEE driver to the
21 * specific TEE driver.
22 */
23
24#define TEE_SHM_DYNAMIC		BIT(0)  /* Dynamic shared memory registered */
25					/* in secure world */
26#define TEE_SHM_USER_MAPPED	BIT(1)  /* Memory mapped in user space */
27#define TEE_SHM_POOL		BIT(2)  /* Memory allocated from pool */
28#define TEE_SHM_PRIV		BIT(3)  /* Memory private to TEE driver */
29
30#define TEE_DEVICE_FLAG_REGISTERED	0x1
31#define TEE_MAX_DEV_NAME_LEN		32
32
33/**
34 * struct tee_device - TEE Device representation
35 * @name:	name of device
36 * @desc:	description of device
37 * @id:		unique id of device
38 * @flags:	represented by TEE_DEVICE_FLAG_REGISTERED above
39 * @dev:	embedded basic device structure
40 * @cdev:	embedded cdev
41 * @num_users:	number of active users of this device
42 * @c_no_user:	completion used when unregistering the device
43 * @mutex:	mutex protecting @num_users and @idr
44 * @idr:	register of user space shared memory objects allocated or
45 *		registered on this device
46 * @pool:	shared memory pool
47 */
48struct tee_device {
49	char name[TEE_MAX_DEV_NAME_LEN];
50	const struct tee_desc *desc;
51	int id;
52	unsigned int flags;
53
54	struct device dev;
55	struct cdev cdev;
56
57	size_t num_users;
58	struct completion c_no_users;
59	struct mutex mutex;	/* protects num_users and idr */
60
61	struct idr idr;
62	struct tee_shm_pool *pool;
63};
64
65/**
66 * struct tee_driver_ops - driver operations vtable
67 * @get_version:	returns version of driver
68 * @open:		called when the device file is opened
69 * @release:		release this open file
70 * @open_session:	open a new session
71 * @close_session:	close a session
72 * @system_session:	declare session as a system session
73 * @invoke_func:	invoke a trusted function
74 * @cancel_req:		request cancel of an ongoing invoke or open
75 * @supp_recv:		called for supplicant to get a command
76 * @supp_send:		called for supplicant to send a response
77 * @shm_register:	register shared memory buffer in TEE
78 * @shm_unregister:	unregister shared memory buffer in TEE
79 */
80struct tee_driver_ops {
81	void (*get_version)(struct tee_device *teedev,
82			    struct tee_ioctl_version_data *vers);
83	int (*open)(struct tee_context *ctx);
84	void (*release)(struct tee_context *ctx);
85	int (*open_session)(struct tee_context *ctx,
86			    struct tee_ioctl_open_session_arg *arg,
87			    struct tee_param *param);
88	int (*close_session)(struct tee_context *ctx, u32 session);
89	int (*system_session)(struct tee_context *ctx, u32 session);
90	int (*invoke_func)(struct tee_context *ctx,
91			   struct tee_ioctl_invoke_arg *arg,
92			   struct tee_param *param);
93	int (*cancel_req)(struct tee_context *ctx, u32 cancel_id, u32 session);
94	int (*supp_recv)(struct tee_context *ctx, u32 *func, u32 *num_params,
95			 struct tee_param *param);
96	int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params,
97			 struct tee_param *param);
98	int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm,
99			    struct page **pages, size_t num_pages,
100			    unsigned long start);
101	int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm);
102};
103
104/**
105 * struct tee_desc - Describes the TEE driver to the subsystem
106 * @name:	name of driver
107 * @ops:	driver operations vtable
108 * @owner:	module providing the driver
109 * @flags:	Extra properties of driver, defined by TEE_DESC_* below
110 */
111#define TEE_DESC_PRIVILEGED	0x1
112struct tee_desc {
113	const char *name;
114	const struct tee_driver_ops *ops;
115	struct module *owner;
116	u32 flags;
117};
118
119/**
120 * tee_device_alloc() - Allocate a new struct tee_device instance
121 * @teedesc:	Descriptor for this driver
122 * @dev:	Parent device for this device
123 * @pool:	Shared memory pool, NULL if not used
124 * @driver_data: Private driver data for this device
125 *
126 * Allocates a new struct tee_device instance. The device is
127 * removed by tee_device_unregister().
128 *
129 * @returns a pointer to a 'struct tee_device' or an ERR_PTR on failure
130 */
131struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
132				    struct device *dev,
133				    struct tee_shm_pool *pool,
134				    void *driver_data);
135
136/**
137 * tee_device_register() - Registers a TEE device
138 * @teedev:	Device to register
139 *
140 * tee_device_unregister() need to be called to remove the @teedev if
141 * this function fails.
142 *
143 * @returns < 0 on failure
144 */
145int tee_device_register(struct tee_device *teedev);
146
147/**
148 * tee_device_unregister() - Removes a TEE device
149 * @teedev:	Device to unregister
150 *
151 * This function should be called to remove the @teedev even if
152 * tee_device_register() hasn't been called yet. Does nothing if
153 * @teedev is NULL.
154 */
155void tee_device_unregister(struct tee_device *teedev);
156
157/**
158 * tee_session_calc_client_uuid() - Calculates client UUID for session
159 * @uuid:		Resulting UUID
160 * @connection_method:	Connection method for session (TEE_IOCTL_LOGIN_*)
161 * @connectuon_data:	Connection data for opening session
162 *
163 * Based on connection method calculates UUIDv5 based client UUID.
164 *
165 * For group based logins verifies that calling process has specified
166 * credentials.
167 *
168 * @return < 0 on failure
169 */
170int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
171				 const u8 connection_data[TEE_IOCTL_UUID_LEN]);
172
173/**
174 * struct tee_shm_pool - shared memory pool
175 * @ops:		operations
176 * @private_data:	private data for the shared memory manager
177 */
178struct tee_shm_pool {
179	const struct tee_shm_pool_ops *ops;
180	void *private_data;
181};
182
183/**
184 * struct tee_shm_pool_ops - shared memory pool operations
185 * @alloc:		called when allocating shared memory
186 * @free:		called when freeing shared memory
187 * @destroy_pool:	called when destroying the pool
188 */
189struct tee_shm_pool_ops {
190	int (*alloc)(struct tee_shm_pool *pool, struct tee_shm *shm,
191		     size_t size, size_t align);
192	void (*free)(struct tee_shm_pool *pool, struct tee_shm *shm);
193	void (*destroy_pool)(struct tee_shm_pool *pool);
194};
195
196/*
197 * tee_shm_pool_alloc_res_mem() - Create a shm manager for reserved memory
198 * @vaddr:	Virtual address of start of pool
199 * @paddr:	Physical address of start of pool
200 * @size:	Size in bytes of the pool
201 *
202 * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
203 */
204struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
205						phys_addr_t paddr, size_t size,
206						int min_alloc_order);
207
208/**
209 * tee_shm_pool_free() - Free a shared memory pool
210 * @pool:	The shared memory pool to free
211 *
212 * The must be no remaining shared memory allocated from this pool when
213 * this function is called.
214 */
215static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
216{
217	pool->ops->destroy_pool(pool);
218}
219
220/**
221 * tee_get_drvdata() - Return driver_data pointer
222 * @returns the driver_data pointer supplied to tee_register().
223 */
224void *tee_get_drvdata(struct tee_device *teedev);
225
226/**
227 * tee_shm_alloc_priv_buf() - Allocate shared memory for private use by specific
228 *                            TEE driver
229 * @ctx:	The TEE context for shared memory allocation
230 * @size:	Shared memory allocation size
231 * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
232 */
233struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size);
234
235int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align,
236			     int (*shm_register)(struct tee_context *ctx,
237						 struct tee_shm *shm,
238						 struct page **pages,
239						 size_t num_pages,
240						 unsigned long start));
241void tee_dyn_shm_free_helper(struct tee_shm *shm,
242			     int (*shm_unregister)(struct tee_context *ctx,
243						   struct tee_shm *shm));
244
245/**
246 * tee_shm_is_dynamic() - Check if shared memory object is of the dynamic kind
247 * @shm:	Shared memory handle
248 * @returns true if object is dynamic shared memory
249 */
250static inline bool tee_shm_is_dynamic(struct tee_shm *shm)
251{
252	return shm && (shm->flags & TEE_SHM_DYNAMIC);
253}
254
255/**
256 * tee_shm_put() - Decrease reference count on a shared memory handle
257 * @shm:	Shared memory handle
258 */
259void tee_shm_put(struct tee_shm *shm);
260
261/**
262 * tee_shm_get_id() - Get id of a shared memory object
263 * @shm:	Shared memory handle
264 * @returns id
265 */
266static inline int tee_shm_get_id(struct tee_shm *shm)
267{
268	return shm->id;
269}
270
271/**
272 * tee_shm_get_from_id() - Find shared memory object and increase reference
273 * count
274 * @ctx:	Context owning the shared memory
275 * @id:		Id of shared memory object
276 * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
277 */
278struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
279
280static inline bool tee_param_is_memref(struct tee_param *param)
281{
282	switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
283	case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
284	case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
285	case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
286		return true;
287	default:
288		return false;
289	}
290}
291
292/**
293 * teedev_open() - Open a struct tee_device
294 * @teedev:	Device to open
295 *
296 * @return a pointer to struct tee_context on success or an ERR_PTR on failure.
297 */
298struct tee_context *teedev_open(struct tee_device *teedev);
299
300/**
301 * teedev_close_context() - closes a struct tee_context
302 * @ctx:	The struct tee_context to close
303 */
304void teedev_close_context(struct tee_context *ctx);
305
306#endif /*__TEE_CORE_H*/
307