xref: /optee_os/core/include/mm/mobj.h (revision c1bdf4fc0c68e4555eaddbc7c1944d48d4637287)
1185b4595SMarouene Boubakri /* SPDX-License-Identifier: BSD-2-Clause */
2185b4595SMarouene Boubakri /*
3185b4595SMarouene Boubakri  * Copyright (c) 2016-2017, Linaro Limited
4185b4595SMarouene Boubakri  */
5185b4595SMarouene Boubakri 
6185b4595SMarouene Boubakri #ifndef __MM_MOBJ_H
7185b4595SMarouene Boubakri #define __MM_MOBJ_H
8185b4595SMarouene Boubakri 
9185b4595SMarouene Boubakri #include <compiler.h>
10185b4595SMarouene Boubakri #include <mm/core_memprot.h>
11185b4595SMarouene Boubakri #include <mm/file.h>
12185b4595SMarouene Boubakri #include <mm/fobj.h>
13185b4595SMarouene Boubakri #include <string_ext.h>
14185b4595SMarouene Boubakri #include <sys/queue.h>
15185b4595SMarouene Boubakri #include <tee_api_types.h>
16185b4595SMarouene Boubakri #include <types_ext.h>
17185b4595SMarouene Boubakri 
18*c1bdf4fcSJens Wiklander #include <optee_msg.h>
19*c1bdf4fcSJens Wiklander 
20185b4595SMarouene Boubakri struct mobj {
21185b4595SMarouene Boubakri 	const struct mobj_ops *ops;
22185b4595SMarouene Boubakri 	size_t size;
23185b4595SMarouene Boubakri 	size_t phys_granule;
24185b4595SMarouene Boubakri 	struct refcount refc;
25185b4595SMarouene Boubakri };
26185b4595SMarouene Boubakri 
27185b4595SMarouene Boubakri struct mobj_ops {
28185b4595SMarouene Boubakri 	void *(*get_va)(struct mobj *mobj, size_t offs);
29185b4595SMarouene Boubakri 	TEE_Result (*get_pa)(struct mobj *mobj, size_t offs, size_t granule,
30185b4595SMarouene Boubakri 			     paddr_t *pa);
31185b4595SMarouene Boubakri 	size_t (*get_phys_offs)(struct mobj *mobj, size_t granule);
32185b4595SMarouene Boubakri 	TEE_Result (*get_cattr)(struct mobj *mobj, uint32_t *cattr);
33185b4595SMarouene Boubakri 	bool (*matches)(struct mobj *mobj, enum buf_is_attr attr);
34185b4595SMarouene Boubakri 	void (*free)(struct mobj *mobj);
35185b4595SMarouene Boubakri 	uint64_t (*get_cookie)(struct mobj *mobj);
36185b4595SMarouene Boubakri 	struct fobj *(*get_fobj)(struct mobj *mobj);
37185b4595SMarouene Boubakri 	TEE_Result (*inc_map)(struct mobj *mobj);
38185b4595SMarouene Boubakri 	TEE_Result (*dec_map)(struct mobj *mobj);
39185b4595SMarouene Boubakri };
40185b4595SMarouene Boubakri 
41185b4595SMarouene Boubakri extern struct mobj mobj_virt;
42185b4595SMarouene Boubakri extern struct mobj *mobj_sec_ddr;
43185b4595SMarouene Boubakri extern struct mobj *mobj_tee_ram;
44185b4595SMarouene Boubakri 
45185b4595SMarouene Boubakri static inline void *mobj_get_va(struct mobj *mobj, size_t offset)
46185b4595SMarouene Boubakri {
47185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_va)
48185b4595SMarouene Boubakri 		return mobj->ops->get_va(mobj, offset);
49185b4595SMarouene Boubakri 	return NULL;
50185b4595SMarouene Boubakri }
51185b4595SMarouene Boubakri 
52185b4595SMarouene Boubakri static inline TEE_Result mobj_get_pa(struct mobj *mobj, size_t offs,
53185b4595SMarouene Boubakri 				     size_t granule, paddr_t *pa)
54185b4595SMarouene Boubakri {
55185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_pa)
56185b4595SMarouene Boubakri 		return mobj->ops->get_pa(mobj, offs, granule, pa);
57185b4595SMarouene Boubakri 	return TEE_ERROR_GENERIC;
58185b4595SMarouene Boubakri }
59185b4595SMarouene Boubakri 
60185b4595SMarouene Boubakri static inline size_t mobj_get_phys_offs(struct mobj *mobj, size_t granule)
61185b4595SMarouene Boubakri {
62185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_phys_offs)
63185b4595SMarouene Boubakri 		return mobj->ops->get_phys_offs(mobj, granule);
64185b4595SMarouene Boubakri 	return 0;
65185b4595SMarouene Boubakri }
66185b4595SMarouene Boubakri 
67185b4595SMarouene Boubakri static inline TEE_Result mobj_get_cattr(struct mobj *mobj, uint32_t *cattr)
68185b4595SMarouene Boubakri {
69185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_cattr)
70185b4595SMarouene Boubakri 		return mobj->ops->get_cattr(mobj, cattr);
71185b4595SMarouene Boubakri 	return TEE_ERROR_GENERIC;
72185b4595SMarouene Boubakri }
73185b4595SMarouene Boubakri 
74185b4595SMarouene Boubakri static inline bool mobj_matches(struct mobj *mobj, enum buf_is_attr attr)
75185b4595SMarouene Boubakri {
76185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->matches)
77185b4595SMarouene Boubakri 		return mobj->ops->matches(mobj, attr);
78185b4595SMarouene Boubakri 	return false;
79185b4595SMarouene Boubakri }
80185b4595SMarouene Boubakri 
81185b4595SMarouene Boubakri /**
82185b4595SMarouene Boubakri  * mobj_inc_map() - increase map count
83185b4595SMarouene Boubakri  * @mobj:	pointer to a MOBJ
84185b4595SMarouene Boubakri  *
85185b4595SMarouene Boubakri  * Maps the MOBJ if it isn't mapped already and increases the map count
86185b4595SMarouene Boubakri  * Each call to mobj_inc_map() is supposed to be matches by a call to
87185b4595SMarouene Boubakri  * mobj_dec_map().
88185b4595SMarouene Boubakri  *
89185b4595SMarouene Boubakri  * Returns TEE_SUCCESS on success or an error code on failure
90185b4595SMarouene Boubakri  */
91185b4595SMarouene Boubakri static inline TEE_Result mobj_inc_map(struct mobj *mobj)
92185b4595SMarouene Boubakri {
93185b4595SMarouene Boubakri 	if (mobj && mobj->ops) {
94185b4595SMarouene Boubakri 		if (mobj->ops->inc_map)
95185b4595SMarouene Boubakri 			return mobj->ops->inc_map(mobj);
96185b4595SMarouene Boubakri 		return TEE_SUCCESS;
97185b4595SMarouene Boubakri 	}
98185b4595SMarouene Boubakri 	return TEE_ERROR_GENERIC;
99185b4595SMarouene Boubakri }
100185b4595SMarouene Boubakri 
101185b4595SMarouene Boubakri /**
102185b4595SMarouene Boubakri  * mobj_dec_map() - decrease map count
103185b4595SMarouene Boubakri  * @mobj:	pointer to a MOBJ
104185b4595SMarouene Boubakri  *
105185b4595SMarouene Boubakri  * Decreases the map count and also unmaps the MOBJ if the map count
106185b4595SMarouene Boubakri  * reaches 0.  Each call to mobj_inc_map() is supposed to be matched by a
107185b4595SMarouene Boubakri  * call to mobj_dec_map().
108185b4595SMarouene Boubakri  *
109185b4595SMarouene Boubakri  * Returns TEE_SUCCESS on success or an error code on failure
110185b4595SMarouene Boubakri  */
111185b4595SMarouene Boubakri static inline TEE_Result mobj_dec_map(struct mobj *mobj)
112185b4595SMarouene Boubakri {
113185b4595SMarouene Boubakri 	if (mobj && mobj->ops) {
114185b4595SMarouene Boubakri 		if (mobj->ops->dec_map)
115185b4595SMarouene Boubakri 			return mobj->ops->dec_map(mobj);
116185b4595SMarouene Boubakri 		return TEE_SUCCESS;
117185b4595SMarouene Boubakri 	}
118185b4595SMarouene Boubakri 	return TEE_ERROR_GENERIC;
119185b4595SMarouene Boubakri }
120185b4595SMarouene Boubakri 
121185b4595SMarouene Boubakri /**
122185b4595SMarouene Boubakri  * mobj_get() - get a MOBJ
123185b4595SMarouene Boubakri  * @mobj:	Pointer to a MOBJ or NULL
124185b4595SMarouene Boubakri  *
125185b4595SMarouene Boubakri  * Increases reference counter of the @mobj
126185b4595SMarouene Boubakri  *
127185b4595SMarouene Boubakri  * Returns @mobj with reference counter increased or NULL if @mobj was NULL
128185b4595SMarouene Boubakri  */
129185b4595SMarouene Boubakri static inline struct mobj *mobj_get(struct mobj *mobj)
130185b4595SMarouene Boubakri {
131185b4595SMarouene Boubakri 	if (mobj && !refcount_inc(&mobj->refc))
132185b4595SMarouene Boubakri 		panic();
133185b4595SMarouene Boubakri 
134185b4595SMarouene Boubakri 	return mobj;
135185b4595SMarouene Boubakri }
136185b4595SMarouene Boubakri 
137185b4595SMarouene Boubakri /**
138185b4595SMarouene Boubakri  * mobj_put() - put a MOBJ
139185b4595SMarouene Boubakri  * @mobj:	Pointer to a MOBJ or NULL
140185b4595SMarouene Boubakri  *
141185b4595SMarouene Boubakri  * Decreases reference counter of the @mobj and frees it if the counter
142185b4595SMarouene Boubakri  * reaches 0.
143185b4595SMarouene Boubakri  */
144185b4595SMarouene Boubakri static inline void mobj_put(struct mobj *mobj)
145185b4595SMarouene Boubakri {
146185b4595SMarouene Boubakri 	if (mobj && refcount_dec(&mobj->refc))
147185b4595SMarouene Boubakri 		mobj->ops->free(mobj);
148185b4595SMarouene Boubakri }
149185b4595SMarouene Boubakri 
150185b4595SMarouene Boubakri /**
151185b4595SMarouene Boubakri  * mobj_put_wipe() - wipe and put a MOBJ
152185b4595SMarouene Boubakri  * @mobj:	Pointer to a MOBJ or NULL
153185b4595SMarouene Boubakri  *
154185b4595SMarouene Boubakri  * Clears the memory represented by the mobj and then puts it.
155185b4595SMarouene Boubakri  */
156185b4595SMarouene Boubakri static inline void mobj_put_wipe(struct mobj *mobj)
157185b4595SMarouene Boubakri {
158185b4595SMarouene Boubakri 	void *buf = mobj_get_va(mobj, 0);
159185b4595SMarouene Boubakri 
160185b4595SMarouene Boubakri 	if (buf)
161185b4595SMarouene Boubakri 		memzero_explicit(buf, mobj->size);
162185b4595SMarouene Boubakri 	mobj_put(mobj);
163185b4595SMarouene Boubakri }
164185b4595SMarouene Boubakri 
165185b4595SMarouene Boubakri static inline uint64_t mobj_get_cookie(struct mobj *mobj)
166185b4595SMarouene Boubakri {
167185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_cookie)
168185b4595SMarouene Boubakri 		return mobj->ops->get_cookie(mobj);
169185b4595SMarouene Boubakri 
170*c1bdf4fcSJens Wiklander #if defined(CFG_CORE_SEL1_SPMC) || defined(CFG_CORE_SEL2_SPMC)
171*c1bdf4fcSJens Wiklander 	return OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
172*c1bdf4fcSJens Wiklander #else
173185b4595SMarouene Boubakri 	return 0;
174*c1bdf4fcSJens Wiklander #endif
175185b4595SMarouene Boubakri }
176185b4595SMarouene Boubakri 
177185b4595SMarouene Boubakri static inline struct fobj *mobj_get_fobj(struct mobj *mobj)
178185b4595SMarouene Boubakri {
179185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_fobj)
180185b4595SMarouene Boubakri 		return mobj->ops->get_fobj(mobj);
181185b4595SMarouene Boubakri 
182185b4595SMarouene Boubakri 	return NULL;
183185b4595SMarouene Boubakri }
184185b4595SMarouene Boubakri 
185185b4595SMarouene Boubakri static inline bool mobj_is_nonsec(struct mobj *mobj)
186185b4595SMarouene Boubakri {
187185b4595SMarouene Boubakri 	return mobj_matches(mobj, CORE_MEM_NON_SEC);
188185b4595SMarouene Boubakri }
189185b4595SMarouene Boubakri 
190185b4595SMarouene Boubakri static inline bool mobj_is_secure(struct mobj *mobj)
191185b4595SMarouene Boubakri {
192185b4595SMarouene Boubakri 	return mobj_matches(mobj, CORE_MEM_SEC);
193185b4595SMarouene Boubakri }
194185b4595SMarouene Boubakri 
195185b4595SMarouene Boubakri static inline bool mobj_is_sdp_mem(struct mobj *mobj)
196185b4595SMarouene Boubakri {
197185b4595SMarouene Boubakri 	return mobj_matches(mobj, CORE_MEM_SDP_MEM);
198185b4595SMarouene Boubakri }
199185b4595SMarouene Boubakri 
200185b4595SMarouene Boubakri static inline size_t mobj_get_phys_granule(struct mobj *mobj)
201185b4595SMarouene Boubakri {
202185b4595SMarouene Boubakri 	if (mobj->phys_granule)
203185b4595SMarouene Boubakri 		return mobj->phys_granule;
204185b4595SMarouene Boubakri 	return mobj->size;
205185b4595SMarouene Boubakri }
206185b4595SMarouene Boubakri 
207185b4595SMarouene Boubakri struct mobj *mobj_mm_alloc(struct mobj *mobj_parent, size_t size,
208185b4595SMarouene Boubakri 			   tee_mm_pool_t *pool);
209185b4595SMarouene Boubakri 
210185b4595SMarouene Boubakri struct mobj *mobj_phys_alloc(paddr_t pa, size_t size, uint32_t cattr,
211185b4595SMarouene Boubakri 			     enum buf_is_attr battr);
212185b4595SMarouene Boubakri 
213185b4595SMarouene Boubakri #if defined(CFG_CORE_FFA)
214185b4595SMarouene Boubakri struct mobj *mobj_ffa_get_by_cookie(uint64_t cookie,
215185b4595SMarouene Boubakri 				    unsigned int internal_offs);
216185b4595SMarouene Boubakri 
217185b4595SMarouene Boubakri TEE_Result mobj_ffa_unregister_by_cookie(uint64_t cookie);
218185b4595SMarouene Boubakri 
219185b4595SMarouene Boubakri /* Functions for SPMC */
220185b4595SMarouene Boubakri #ifdef CFG_CORE_SEL1_SPMC
221185b4595SMarouene Boubakri struct mobj_ffa *mobj_ffa_sel1_spmc_new(unsigned int num_pages);
222185b4595SMarouene Boubakri void mobj_ffa_sel1_spmc_delete(struct mobj_ffa *mobj);
223185b4595SMarouene Boubakri TEE_Result mobj_ffa_sel1_spmc_reclaim(uint64_t cookie);
224185b4595SMarouene Boubakri #endif
225185b4595SMarouene Boubakri uint64_t mobj_ffa_get_cookie(struct mobj_ffa *mobj);
226185b4595SMarouene Boubakri TEE_Result mobj_ffa_add_pages_at(struct mobj_ffa *mobj, unsigned int *idx,
227185b4595SMarouene Boubakri 				 paddr_t pa, unsigned int num_pages);
228185b4595SMarouene Boubakri uint64_t mobj_ffa_push_to_inactive(struct mobj_ffa *mobj);
229185b4595SMarouene Boubakri 
230185b4595SMarouene Boubakri #elif defined(CFG_CORE_DYN_SHM)
231185b4595SMarouene Boubakri /* reg_shm represents TEE shared memory */
232185b4595SMarouene Boubakri struct mobj *mobj_reg_shm_alloc(paddr_t *pages, size_t num_pages,
233185b4595SMarouene Boubakri 				paddr_t page_offset, uint64_t cookie);
234185b4595SMarouene Boubakri 
235185b4595SMarouene Boubakri /**
236185b4595SMarouene Boubakri  * mobj_reg_shm_get_by_cookie() - get a MOBJ based on cookie
237185b4595SMarouene Boubakri  * @cookie:	Cookie used by normal world when suppling the shared memory
238185b4595SMarouene Boubakri  *
239185b4595SMarouene Boubakri  * Searches for a registered shared memory MOBJ and if one with a matching
240185b4595SMarouene Boubakri  * @cookie is found its reference counter is increased before returning
241185b4595SMarouene Boubakri  * the MOBJ.
242185b4595SMarouene Boubakri  *
243185b4595SMarouene Boubakri  * Returns a valid pointer on success or NULL on failure.
244185b4595SMarouene Boubakri  */
245185b4595SMarouene Boubakri struct mobj *mobj_reg_shm_get_by_cookie(uint64_t cookie);
246185b4595SMarouene Boubakri 
247185b4595SMarouene Boubakri TEE_Result mobj_reg_shm_release_by_cookie(uint64_t cookie);
248185b4595SMarouene Boubakri 
249185b4595SMarouene Boubakri /**
250185b4595SMarouene Boubakri  * mobj_reg_shm_unguard() - unguards a reg_shm
251185b4595SMarouene Boubakri  * @mobj:	pointer to a registered shared memory mobj
252185b4595SMarouene Boubakri  *
253185b4595SMarouene Boubakri  * A registered shared memory mobj is normally guarded against being
254185b4595SMarouene Boubakri  * released with mobj_reg_shm_try_release_by_cookie(). After this function
255185b4595SMarouene Boubakri  * has returned the mobj can be released by a call to
256185b4595SMarouene Boubakri  * mobj_reg_shm_try_release_by_cookie() if the reference counter allows it.
257185b4595SMarouene Boubakri  */
258185b4595SMarouene Boubakri void mobj_reg_shm_unguard(struct mobj *mobj);
259185b4595SMarouene Boubakri 
260185b4595SMarouene Boubakri /*
261185b4595SMarouene Boubakri  * mapped_shm represents registered shared buffer
262185b4595SMarouene Boubakri  * which is mapped into OPTEE va space
263185b4595SMarouene Boubakri  */
264185b4595SMarouene Boubakri struct mobj *mobj_mapped_shm_alloc(paddr_t *pages, size_t num_pages,
265185b4595SMarouene Boubakri 				   paddr_t page_offset, uint64_t cookie);
266185b4595SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/
267185b4595SMarouene Boubakri 
268185b4595SMarouene Boubakri #if !defined(CFG_CORE_DYN_SHM)
269185b4595SMarouene Boubakri static inline struct mobj *mobj_mapped_shm_alloc(paddr_t *pages __unused,
270185b4595SMarouene Boubakri 						 size_t num_pages __unused,
271185b4595SMarouene Boubakri 						 paddr_t page_offset __unused,
272185b4595SMarouene Boubakri 						 uint64_t cookie __unused)
273185b4595SMarouene Boubakri {
274185b4595SMarouene Boubakri 	return NULL;
275185b4595SMarouene Boubakri }
276185b4595SMarouene Boubakri #endif
277185b4595SMarouene Boubakri 
278185b4595SMarouene Boubakri struct mobj *mobj_shm_alloc(paddr_t pa, size_t size, uint64_t cookie);
279185b4595SMarouene Boubakri 
280185b4595SMarouene Boubakri #ifdef CFG_PAGED_USER_TA
281185b4595SMarouene Boubakri bool mobj_is_paged(struct mobj *mobj);
282185b4595SMarouene Boubakri #else
283185b4595SMarouene Boubakri static inline bool mobj_is_paged(struct mobj *mobj __unused)
284185b4595SMarouene Boubakri {
285185b4595SMarouene Boubakri 	return false;
286185b4595SMarouene Boubakri }
287185b4595SMarouene Boubakri #endif
288185b4595SMarouene Boubakri 
289185b4595SMarouene Boubakri struct mobj *mobj_seccpy_shm_alloc(size_t size);
290185b4595SMarouene Boubakri 
291185b4595SMarouene Boubakri struct mobj *mobj_with_fobj_alloc(struct fobj *fobj, struct file *file);
292185b4595SMarouene Boubakri 
293185b4595SMarouene Boubakri #endif /*__MM_MOBJ_H*/
294