diff options
Diffstat (limited to 'include/linux/tee_drv.h')
-rw-r--r-- | include/linux/tee_drv.h | 196 |
1 files changed, 193 insertions, 3 deletions
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index cb889afe576b..a2b3dfcee0b5 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/idr.h> | 19 | #include <linux/idr.h> |
20 | #include <linux/kref.h> | ||
20 | #include <linux/list.h> | 21 | #include <linux/list.h> |
21 | #include <linux/tee.h> | 22 | #include <linux/tee.h> |
22 | 23 | ||
@@ -25,8 +26,12 @@ | |||
25 | * specific TEE driver. | 26 | * specific TEE driver. |
26 | */ | 27 | */ |
27 | 28 | ||
28 | #define TEE_SHM_MAPPED 0x1 /* Memory mapped by the kernel */ | 29 | #define TEE_SHM_MAPPED BIT(0) /* Memory mapped by the kernel */ |
29 | #define TEE_SHM_DMA_BUF 0x2 /* Memory with dma-buf handle */ | 30 | #define TEE_SHM_DMA_BUF BIT(1) /* Memory with dma-buf handle */ |
31 | #define TEE_SHM_EXT_DMA_BUF BIT(2) /* Memory with dma-buf handle */ | ||
32 | #define TEE_SHM_REGISTER BIT(3) /* Memory registered in secure world */ | ||
33 | #define TEE_SHM_USER_MAPPED BIT(4) /* Memory mapped in user space */ | ||
34 | #define TEE_SHM_POOL BIT(5) /* Memory allocated from pool */ | ||
30 | 35 | ||
31 | struct device; | 36 | struct device; |
32 | struct tee_device; | 37 | struct tee_device; |
@@ -38,11 +43,17 @@ struct tee_shm_pool; | |||
38 | * @teedev: pointer to this drivers struct tee_device | 43 | * @teedev: pointer to this drivers struct tee_device |
39 | * @list_shm: List of shared memory object owned by this context | 44 | * @list_shm: List of shared memory object owned by this context |
40 | * @data: driver specific context data, managed by the driver | 45 | * @data: driver specific context data, managed by the driver |
46 | * @refcount: reference counter for this structure | ||
47 | * @releasing: flag that indicates if context is being released right now. | ||
48 | * It is needed to break circular dependency on context during | ||
49 | * shared memory release. | ||
41 | */ | 50 | */ |
42 | struct tee_context { | 51 | struct tee_context { |
43 | struct tee_device *teedev; | 52 | struct tee_device *teedev; |
44 | struct list_head list_shm; | 53 | struct list_head list_shm; |
45 | void *data; | 54 | void *data; |
55 | struct kref refcount; | ||
56 | bool releasing; | ||
46 | }; | 57 | }; |
47 | 58 | ||
48 | struct tee_param_memref { | 59 | struct tee_param_memref { |
@@ -76,6 +87,8 @@ struct tee_param { | |||
76 | * @cancel_req: request cancel of an ongoing invoke or open | 87 | * @cancel_req: request cancel of an ongoing invoke or open |
77 | * @supp_revc: called for supplicant to get a command | 88 | * @supp_revc: called for supplicant to get a command |
78 | * @supp_send: called for supplicant to send a response | 89 | * @supp_send: called for supplicant to send a response |
90 | * @shm_register: register shared memory buffer in TEE | ||
91 | * @shm_unregister: unregister shared memory buffer in TEE | ||
79 | */ | 92 | */ |
80 | struct tee_driver_ops { | 93 | struct tee_driver_ops { |
81 | void (*get_version)(struct tee_device *teedev, | 94 | void (*get_version)(struct tee_device *teedev, |
@@ -94,6 +107,10 @@ struct tee_driver_ops { | |||
94 | struct tee_param *param); | 107 | struct tee_param *param); |
95 | int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params, | 108 | int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params, |
96 | struct tee_param *param); | 109 | struct tee_param *param); |
110 | int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm, | ||
111 | struct page **pages, size_t num_pages, | ||
112 | unsigned long start); | ||
113 | int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm); | ||
97 | }; | 114 | }; |
98 | 115 | ||
99 | /** | 116 | /** |
@@ -150,6 +167,97 @@ int tee_device_register(struct tee_device *teedev); | |||
150 | void tee_device_unregister(struct tee_device *teedev); | 167 | void tee_device_unregister(struct tee_device *teedev); |
151 | 168 | ||
152 | /** | 169 | /** |
170 | * struct tee_shm - shared memory object | ||
171 | * @teedev: device used to allocate the object | ||
172 | * @ctx: context using the object, if NULL the context is gone | ||
173 | * @link link element | ||
174 | * @paddr: physical address of the shared memory | ||
175 | * @kaddr: virtual address of the shared memory | ||
176 | * @size: size of shared memory | ||
177 | * @offset: offset of buffer in user space | ||
178 | * @pages: locked pages from userspace | ||
179 | * @num_pages: number of locked pages | ||
180 | * @dmabuf: dmabuf used to for exporting to user space | ||
181 | * @flags: defined by TEE_SHM_* in tee_drv.h | ||
182 | * @id: unique id of a shared memory object on this device | ||
183 | * | ||
184 | * This pool is only supposed to be accessed directly from the TEE | ||
185 | * subsystem and from drivers that implements their own shm pool manager. | ||
186 | */ | ||
187 | struct tee_shm { | ||
188 | struct tee_device *teedev; | ||
189 | struct tee_context *ctx; | ||
190 | struct list_head link; | ||
191 | phys_addr_t paddr; | ||
192 | void *kaddr; | ||
193 | size_t size; | ||
194 | unsigned int offset; | ||
195 | struct page **pages; | ||
196 | size_t num_pages; | ||
197 | struct dma_buf *dmabuf; | ||
198 | u32 flags; | ||
199 | int id; | ||
200 | }; | ||
201 | |||
202 | /** | ||
203 | * struct tee_shm_pool_mgr - shared memory manager | ||
204 | * @ops: operations | ||
205 | * @private_data: private data for the shared memory manager | ||
206 | */ | ||
207 | struct tee_shm_pool_mgr { | ||
208 | const struct tee_shm_pool_mgr_ops *ops; | ||
209 | void *private_data; | ||
210 | }; | ||
211 | |||
212 | /** | ||
213 | * struct tee_shm_pool_mgr_ops - shared memory pool manager operations | ||
214 | * @alloc: called when allocating shared memory | ||
215 | * @free: called when freeing shared memory | ||
216 | * @destroy_poolmgr: called when destroying the pool manager | ||
217 | */ | ||
218 | struct tee_shm_pool_mgr_ops { | ||
219 | int (*alloc)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm, | ||
220 | size_t size); | ||
221 | void (*free)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm); | ||
222 | void (*destroy_poolmgr)(struct tee_shm_pool_mgr *poolmgr); | ||
223 | }; | ||
224 | |||
225 | /** | ||
226 | * tee_shm_pool_alloc() - Create a shared memory pool from shm managers | ||
227 | * @priv_mgr: manager for driver private shared memory allocations | ||
228 | * @dmabuf_mgr: manager for dma-buf shared memory allocations | ||
229 | * | ||
230 | * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied | ||
231 | * in @dmabuf, others will use the range provided by @priv. | ||
232 | * | ||
233 | * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure. | ||
234 | */ | ||
235 | struct tee_shm_pool *tee_shm_pool_alloc(struct tee_shm_pool_mgr *priv_mgr, | ||
236 | struct tee_shm_pool_mgr *dmabuf_mgr); | ||
237 | |||
238 | /* | ||
239 | * tee_shm_pool_mgr_alloc_res_mem() - Create a shm manager for reserved | ||
240 | * memory | ||
241 | * @vaddr: Virtual address of start of pool | ||
242 | * @paddr: Physical address of start of pool | ||
243 | * @size: Size in bytes of the pool | ||
244 | * | ||
245 | * @returns pointer to a 'struct tee_shm_pool_mgr' or an ERR_PTR on failure. | ||
246 | */ | ||
247 | struct tee_shm_pool_mgr *tee_shm_pool_mgr_alloc_res_mem(unsigned long vaddr, | ||
248 | phys_addr_t paddr, | ||
249 | size_t size, | ||
250 | int min_alloc_order); | ||
251 | |||
252 | /** | ||
253 | * tee_shm_pool_mgr_destroy() - Free a shared memory manager | ||
254 | */ | ||
255 | static inline void tee_shm_pool_mgr_destroy(struct tee_shm_pool_mgr *poolm) | ||
256 | { | ||
257 | poolm->ops->destroy_poolmgr(poolm); | ||
258 | } | ||
259 | |||
260 | /** | ||
153 | * struct tee_shm_pool_mem_info - holds information needed to create a shared | 261 | * struct tee_shm_pool_mem_info - holds information needed to create a shared |
154 | * memory pool | 262 | * memory pool |
155 | * @vaddr: Virtual address of start of pool | 263 | * @vaddr: Virtual address of start of pool |
@@ -211,6 +319,40 @@ void *tee_get_drvdata(struct tee_device *teedev); | |||
211 | struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags); | 319 | struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags); |
212 | 320 | ||
213 | /** | 321 | /** |
322 | * tee_shm_priv_alloc() - Allocate shared memory privately | ||
323 | * @dev: Device that allocates the shared memory | ||
324 | * @size: Requested size of shared memory | ||
325 | * | ||
326 | * Allocates shared memory buffer that is not associated with any client | ||
327 | * context. Such buffers are owned by TEE driver and used for internal calls. | ||
328 | * | ||
329 | * @returns a pointer to 'struct tee_shm' | ||
330 | */ | ||
331 | struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size); | ||
332 | |||
333 | /** | ||
334 | * tee_shm_register() - Register shared memory buffer | ||
335 | * @ctx: Context that registers the shared memory | ||
336 | * @addr: Address is userspace of the shared buffer | ||
337 | * @length: Length of the shared buffer | ||
338 | * @flags: Flags setting properties for the requested shared memory. | ||
339 | * | ||
340 | * @returns a pointer to 'struct tee_shm' | ||
341 | */ | ||
342 | struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, | ||
343 | size_t length, u32 flags); | ||
344 | |||
345 | /** | ||
346 | * tee_shm_is_registered() - Check if shared memory object in registered in TEE | ||
347 | * @shm: Shared memory handle | ||
348 | * @returns true if object is registered in TEE | ||
349 | */ | ||
350 | static inline bool tee_shm_is_registered(struct tee_shm *shm) | ||
351 | { | ||
352 | return shm && (shm->flags & TEE_SHM_REGISTER); | ||
353 | } | ||
354 | |||
355 | /** | ||
214 | * tee_shm_free() - Free shared memory | 356 | * tee_shm_free() - Free shared memory |
215 | * @shm: Handle to shared memory to free | 357 | * @shm: Handle to shared memory to free |
216 | */ | 358 | */ |
@@ -260,11 +402,47 @@ void *tee_shm_get_va(struct tee_shm *shm, size_t offs); | |||
260 | int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa); | 402 | int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa); |
261 | 403 | ||
262 | /** | 404 | /** |
405 | * tee_shm_get_size() - Get size of shared memory buffer | ||
406 | * @shm: Shared memory handle | ||
407 | * @returns size of shared memory | ||
408 | */ | ||
409 | static inline size_t tee_shm_get_size(struct tee_shm *shm) | ||
410 | { | ||
411 | return shm->size; | ||
412 | } | ||
413 | |||
414 | /** | ||
415 | * tee_shm_get_pages() - Get list of pages that hold shared buffer | ||
416 | * @shm: Shared memory handle | ||
417 | * @num_pages: Number of pages will be stored there | ||
418 | * @returns pointer to pages array | ||
419 | */ | ||
420 | static inline struct page **tee_shm_get_pages(struct tee_shm *shm, | ||
421 | size_t *num_pages) | ||
422 | { | ||
423 | *num_pages = shm->num_pages; | ||
424 | return shm->pages; | ||
425 | } | ||
426 | |||
427 | /** | ||
428 | * tee_shm_get_page_offset() - Get shared buffer offset from page start | ||
429 | * @shm: Shared memory handle | ||
430 | * @returns page offset of shared buffer | ||
431 | */ | ||
432 | static inline size_t tee_shm_get_page_offset(struct tee_shm *shm) | ||
433 | { | ||
434 | return shm->offset; | ||
435 | } | ||
436 | |||
437 | /** | ||
263 | * tee_shm_get_id() - Get id of a shared memory object | 438 | * tee_shm_get_id() - Get id of a shared memory object |
264 | * @shm: Shared memory handle | 439 | * @shm: Shared memory handle |
265 | * @returns id | 440 | * @returns id |
266 | */ | 441 | */ |
267 | int tee_shm_get_id(struct tee_shm *shm); | 442 | static inline int tee_shm_get_id(struct tee_shm *shm) |
443 | { | ||
444 | return shm->id; | ||
445 | } | ||
268 | 446 | ||
269 | /** | 447 | /** |
270 | * tee_shm_get_from_id() - Find shared memory object and increase reference | 448 | * tee_shm_get_from_id() - Find shared memory object and increase reference |
@@ -275,4 +453,16 @@ int tee_shm_get_id(struct tee_shm *shm); | |||
275 | */ | 453 | */ |
276 | struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id); | 454 | struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id); |
277 | 455 | ||
456 | static inline bool tee_param_is_memref(struct tee_param *param) | ||
457 | { | ||
458 | switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { | ||
459 | case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: | ||
460 | case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: | ||
461 | case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: | ||
462 | return true; | ||
463 | default: | ||
464 | return false; | ||
465 | } | ||
466 | } | ||
467 | |||
278 | #endif /*__TEE_DRV_H*/ | 468 | #endif /*__TEE_DRV_H*/ |