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