summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2017-12-21 11:23:52 -0500
committerArnd Bergmann <arnd@arndb.de>2017-12-21 11:23:52 -0500
commitbad19e0d0460564a067f901b6848c0cc0c403c52 (patch)
treea18b9f2796aee7ce366108e684c12b5fe9d95f89 /include
parentf9988fbb93c8c4de9f8ec37f63ebb7bf705c7c45 (diff)
parentef8e08d24ca84846ce639b835ebd2f15a943f42b (diff)
Merge tag 'tee-drv-dynamic-shm-for-v4.16' of https://git.linaro.org/people/jens.wiklander/linux-tee into next/drivers
Pull "tee dynamic shm for v4.16" from Jens Wiklander: This pull request enables dynamic shared memory support in the TEE subsystem as a whole and in OP-TEE in particular. Global Platform TEE specification [1] allows client applications to register part of own memory as a shared buffer between application and TEE. This allows fast zero-copy communication between TEE and REE. But current implementation of TEE in Linux does not support this feature. Also, current implementation of OP-TEE transport uses fixed size pre-shared buffer for all communications with OP-TEE OS. This is okay in the most use cases. But this prevents use of OP-TEE in virtualized environments, because: a) We can't share the same buffer between different virtual machines b) Physically contiguous memory as seen by VM can be non-contiguous in reality (and as seen by OP-TEE OS) due to second stage of MMU translation. c) Size of this pre-shared buffer is limited. So, first part of this pull request adds generic register/unregister interface to tee subsystem. The second part adds necessary features into OP-TEE driver, so it can use not only static pre-shared buffer, but whole RAM to communicate with OP-TEE OS. This change is backwards compatible allowing older secure world or user space to work with newer kernels and vice versa. [1] https://www.globalplatform.org/specificationsdevice.asp * tag 'tee-drv-dynamic-shm-for-v4.16' of https://git.linaro.org/people/jens.wiklander/linux-tee: tee: shm: inline tee_shm_get_id() tee: use reference counting for tee_context tee: optee: enable dynamic SHM support tee: optee: add optee-specific shared pool implementation tee: optee: store OP-TEE capabilities in private data tee: optee: add registered buffers handling into RPC calls tee: optee: add registered shared parameters handling tee: optee: add shared buffer registration functions tee: optee: add page list manipulation functions tee: optee: Update protocol definitions tee: shm: add page accessor functions tee: shm: add accessors for buffer size and page offset tee: add register user memory tee: flexible shared memory pool creation
Diffstat (limited to 'include')
-rw-r--r--include/linux/tee_drv.h183
-rw-r--r--include/uapi/linux/tee.h30
2 files changed, 210 insertions, 3 deletions
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index f4a0ac05ebb4..41bd4bded28c 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
31struct device; 36struct device;
32struct tee_device; 37struct 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 */
42struct tee_context { 51struct 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
48struct tee_param_memref { 59struct 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 */
80struct tee_driver_ops { 93struct tee_driver_ops {
81 void (*get_version)(struct tee_device *teedev, 94 void (*get_version)(struct tee_device *teedev,
@@ -94,6 +107,9 @@ 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 int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm);
97}; 113};
98 114
99/** 115/**
@@ -150,6 +166,97 @@ int tee_device_register(struct tee_device *teedev);
150void tee_device_unregister(struct tee_device *teedev); 166void tee_device_unregister(struct tee_device *teedev);
151 167
152/** 168/**
169 * struct tee_shm - shared memory object
170 * @teedev: device used to allocate the object
171 * @ctx: context using the object, if NULL the context is gone
172 * @link link element
173 * @paddr: physical address of the shared memory
174 * @kaddr: virtual address of the shared memory
175 * @size: size of shared memory
176 * @offset: offset of buffer in user space
177 * @pages: locked pages from userspace
178 * @num_pages: number of locked pages
179 * @dmabuf: dmabuf used to for exporting to user space
180 * @flags: defined by TEE_SHM_* in tee_drv.h
181 * @id: unique id of a shared memory object on this device
182 *
183 * This pool is only supposed to be accessed directly from the TEE
184 * subsystem and from drivers that implements their own shm pool manager.
185 */
186struct tee_shm {
187 struct tee_device *teedev;
188 struct tee_context *ctx;
189 struct list_head link;
190 phys_addr_t paddr;
191 void *kaddr;
192 size_t size;
193 unsigned int offset;
194 struct page **pages;
195 size_t num_pages;
196 struct dma_buf *dmabuf;
197 u32 flags;
198 int id;
199};
200
201/**
202 * struct tee_shm_pool_mgr - shared memory manager
203 * @ops: operations
204 * @private_data: private data for the shared memory manager
205 */
206struct tee_shm_pool_mgr {
207 const struct tee_shm_pool_mgr_ops *ops;
208 void *private_data;
209};
210
211/**
212 * struct tee_shm_pool_mgr_ops - shared memory pool manager operations
213 * @alloc: called when allocating shared memory
214 * @free: called when freeing shared memory
215 * @destroy_poolmgr: called when destroying the pool manager
216 */
217struct tee_shm_pool_mgr_ops {
218 int (*alloc)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm,
219 size_t size);
220 void (*free)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm);
221 void (*destroy_poolmgr)(struct tee_shm_pool_mgr *poolmgr);
222};
223
224/**
225 * tee_shm_pool_alloc() - Create a shared memory pool from shm managers
226 * @priv_mgr: manager for driver private shared memory allocations
227 * @dmabuf_mgr: manager for dma-buf shared memory allocations
228 *
229 * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied
230 * in @dmabuf, others will use the range provided by @priv.
231 *
232 * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
233 */
234struct tee_shm_pool *tee_shm_pool_alloc(struct tee_shm_pool_mgr *priv_mgr,
235 struct tee_shm_pool_mgr *dmabuf_mgr);
236
237/*
238 * tee_shm_pool_mgr_alloc_res_mem() - Create a shm manager for reserved
239 * memory
240 * @vaddr: Virtual address of start of pool
241 * @paddr: Physical address of start of pool
242 * @size: Size in bytes of the pool
243 *
244 * @returns pointer to a 'struct tee_shm_pool_mgr' or an ERR_PTR on failure.
245 */
246struct tee_shm_pool_mgr *tee_shm_pool_mgr_alloc_res_mem(unsigned long vaddr,
247 phys_addr_t paddr,
248 size_t size,
249 int min_alloc_order);
250
251/**
252 * tee_shm_pool_mgr_destroy() - Free a shared memory manager
253 */
254static inline void tee_shm_pool_mgr_destroy(struct tee_shm_pool_mgr *poolm)
255{
256 poolm->ops->destroy_poolmgr(poolm);
257}
258
259/**
153 * struct tee_shm_pool_mem_info - holds information needed to create a shared 260 * struct tee_shm_pool_mem_info - holds information needed to create a shared
154 * memory pool 261 * memory pool
155 * @vaddr: Virtual address of start of pool 262 * @vaddr: Virtual address of start of pool
@@ -211,6 +318,40 @@ void *tee_get_drvdata(struct tee_device *teedev);
211struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags); 318struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags);
212 319
213/** 320/**
321 * tee_shm_priv_alloc() - Allocate shared memory privately
322 * @dev: Device that allocates the shared memory
323 * @size: Requested size of shared memory
324 *
325 * Allocates shared memory buffer that is not associated with any client
326 * context. Such buffers are owned by TEE driver and used for internal calls.
327 *
328 * @returns a pointer to 'struct tee_shm'
329 */
330struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size);
331
332/**
333 * tee_shm_register() - Register shared memory buffer
334 * @ctx: Context that registers the shared memory
335 * @addr: Address is userspace of the shared buffer
336 * @length: Length of the shared buffer
337 * @flags: Flags setting properties for the requested shared memory.
338 *
339 * @returns a pointer to 'struct tee_shm'
340 */
341struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
342 size_t length, u32 flags);
343
344/**
345 * tee_shm_is_registered() - Check if shared memory object in registered in TEE
346 * @shm: Shared memory handle
347 * @returns true if object is registered in TEE
348 */
349static inline bool tee_shm_is_registered(struct tee_shm *shm)
350{
351 return shm && (shm->flags & TEE_SHM_REGISTER);
352}
353
354/**
214 * tee_shm_free() - Free shared memory 355 * tee_shm_free() - Free shared memory
215 * @shm: Handle to shared memory to free 356 * @shm: Handle to shared memory to free
216 */ 357 */
@@ -260,11 +401,47 @@ void *tee_shm_get_va(struct tee_shm *shm, size_t offs);
260int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa); 401int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa);
261 402
262/** 403/**
404 * tee_shm_get_size() - Get size of shared memory buffer
405 * @shm: Shared memory handle
406 * @returns size of shared memory
407 */
408static inline size_t tee_shm_get_size(struct tee_shm *shm)
409{
410 return shm->size;
411}
412
413/**
414 * tee_shm_get_pages() - Get list of pages that hold shared buffer
415 * @shm: Shared memory handle
416 * @num_pages: Number of pages will be stored there
417 * @returns pointer to pages array
418 */
419static inline struct page **tee_shm_get_pages(struct tee_shm *shm,
420 size_t *num_pages)
421{
422 *num_pages = shm->num_pages;
423 return shm->pages;
424}
425
426/**
427 * tee_shm_get_page_offset() - Get shared buffer offset from page start
428 * @shm: Shared memory handle
429 * @returns page offset of shared buffer
430 */
431static inline size_t tee_shm_get_page_offset(struct tee_shm *shm)
432{
433 return shm->offset;
434}
435
436/**
263 * tee_shm_get_id() - Get id of a shared memory object 437 * tee_shm_get_id() - Get id of a shared memory object
264 * @shm: Shared memory handle 438 * @shm: Shared memory handle
265 * @returns id 439 * @returns id
266 */ 440 */
267int tee_shm_get_id(struct tee_shm *shm); 441static inline int tee_shm_get_id(struct tee_shm *shm)
442{
443 return shm->id;
444}
268 445
269/** 446/**
270 * tee_shm_get_from_id() - Find shared memory object and increase reference 447 * tee_shm_get_from_id() - Find shared memory object and increase reference
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
index 267c12e7fd79..4b9eb064d7e7 100644
--- a/include/uapi/linux/tee.h
+++ b/include/uapi/linux/tee.h
@@ -50,6 +50,7 @@
50 50
51#define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */ 51#define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */
52#define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */ 52#define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */
53#define TEE_GEN_CAP_REG_MEM (1 << 2)/* Supports registering shared memory */
53 54
54/* 55/*
55 * TEE Implementation ID 56 * TEE Implementation ID
@@ -339,6 +340,35 @@ struct tee_iocl_supp_send_arg {
339#define TEE_IOC_SUPPL_SEND _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 7, \ 340#define TEE_IOC_SUPPL_SEND _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 7, \
340 struct tee_ioctl_buf_data) 341 struct tee_ioctl_buf_data)
341 342
343/**
344 * struct tee_ioctl_shm_register_data - Shared memory register argument
345 * @addr: [in] Start address of shared memory to register
346 * @length: [in/out] Length of shared memory to register
347 * @flags: [in/out] Flags to/from registration.
348 * @id: [out] Identifier of the shared memory
349 *
350 * The flags field should currently be zero as input. Updated by the call
351 * with actual flags as defined by TEE_IOCTL_SHM_* above.
352 * This structure is used as argument for TEE_IOC_SHM_REGISTER below.
353 */
354struct tee_ioctl_shm_register_data {
355 __u64 addr;
356 __u64 length;
357 __u32 flags;
358 __s32 id;
359};
360
361/**
362 * TEE_IOC_SHM_REGISTER - Register shared memory argument
363 *
364 * Registers shared memory between the user space process and secure OS.
365 *
366 * Returns a file descriptor on success or < 0 on failure
367 *
368 * The shared memory is unregisterred when the descriptor is closed.
369 */
370#define TEE_IOC_SHM_REGISTER _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
371 struct tee_ioctl_shm_register_data)
342/* 372/*
343 * Five syscalls are used when communicating with the TEE driver. 373 * Five syscalls are used when communicating with the TEE driver.
344 * open(): opens the device associated with the driver 374 * open(): opens the device associated with the driver