xref: /optee_os/core/include/mm/mobj.h (revision 185b4595b97588a2eac575168daf128358397c14)
1*185b4595SMarouene Boubakri /* SPDX-License-Identifier: BSD-2-Clause */
2*185b4595SMarouene Boubakri /*
3*185b4595SMarouene Boubakri  * Copyright (c) 2016-2017, Linaro Limited
4*185b4595SMarouene Boubakri  */
5*185b4595SMarouene Boubakri 
6*185b4595SMarouene Boubakri #ifndef __MM_MOBJ_H
7*185b4595SMarouene Boubakri #define __MM_MOBJ_H
8*185b4595SMarouene Boubakri 
9*185b4595SMarouene Boubakri #include <compiler.h>
10*185b4595SMarouene Boubakri #include <mm/core_memprot.h>
11*185b4595SMarouene Boubakri #include <mm/file.h>
12*185b4595SMarouene Boubakri #include <mm/fobj.h>
13*185b4595SMarouene Boubakri #include <string_ext.h>
14*185b4595SMarouene Boubakri #include <sys/queue.h>
15*185b4595SMarouene Boubakri #include <tee_api_types.h>
16*185b4595SMarouene Boubakri #include <types_ext.h>
17*185b4595SMarouene Boubakri 
18*185b4595SMarouene Boubakri struct mobj {
19*185b4595SMarouene Boubakri 	const struct mobj_ops *ops;
20*185b4595SMarouene Boubakri 	size_t size;
21*185b4595SMarouene Boubakri 	size_t phys_granule;
22*185b4595SMarouene Boubakri 	struct refcount refc;
23*185b4595SMarouene Boubakri };
24*185b4595SMarouene Boubakri 
25*185b4595SMarouene Boubakri struct mobj_ops {
26*185b4595SMarouene Boubakri 	void *(*get_va)(struct mobj *mobj, size_t offs);
27*185b4595SMarouene Boubakri 	TEE_Result (*get_pa)(struct mobj *mobj, size_t offs, size_t granule,
28*185b4595SMarouene Boubakri 			     paddr_t *pa);
29*185b4595SMarouene Boubakri 	size_t (*get_phys_offs)(struct mobj *mobj, size_t granule);
30*185b4595SMarouene Boubakri 	TEE_Result (*get_cattr)(struct mobj *mobj, uint32_t *cattr);
31*185b4595SMarouene Boubakri 	bool (*matches)(struct mobj *mobj, enum buf_is_attr attr);
32*185b4595SMarouene Boubakri 	void (*free)(struct mobj *mobj);
33*185b4595SMarouene Boubakri 	uint64_t (*get_cookie)(struct mobj *mobj);
34*185b4595SMarouene Boubakri 	struct fobj *(*get_fobj)(struct mobj *mobj);
35*185b4595SMarouene Boubakri 	TEE_Result (*inc_map)(struct mobj *mobj);
36*185b4595SMarouene Boubakri 	TEE_Result (*dec_map)(struct mobj *mobj);
37*185b4595SMarouene Boubakri };
38*185b4595SMarouene Boubakri 
39*185b4595SMarouene Boubakri extern struct mobj mobj_virt;
40*185b4595SMarouene Boubakri extern struct mobj *mobj_sec_ddr;
41*185b4595SMarouene Boubakri extern struct mobj *mobj_tee_ram;
42*185b4595SMarouene Boubakri 
43*185b4595SMarouene Boubakri static inline void *mobj_get_va(struct mobj *mobj, size_t offset)
44*185b4595SMarouene Boubakri {
45*185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_va)
46*185b4595SMarouene Boubakri 		return mobj->ops->get_va(mobj, offset);
47*185b4595SMarouene Boubakri 	return NULL;
48*185b4595SMarouene Boubakri }
49*185b4595SMarouene Boubakri 
50*185b4595SMarouene Boubakri static inline TEE_Result mobj_get_pa(struct mobj *mobj, size_t offs,
51*185b4595SMarouene Boubakri 				     size_t granule, paddr_t *pa)
52*185b4595SMarouene Boubakri {
53*185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_pa)
54*185b4595SMarouene Boubakri 		return mobj->ops->get_pa(mobj, offs, granule, pa);
55*185b4595SMarouene Boubakri 	return TEE_ERROR_GENERIC;
56*185b4595SMarouene Boubakri }
57*185b4595SMarouene Boubakri 
58*185b4595SMarouene Boubakri static inline size_t mobj_get_phys_offs(struct mobj *mobj, size_t granule)
59*185b4595SMarouene Boubakri {
60*185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_phys_offs)
61*185b4595SMarouene Boubakri 		return mobj->ops->get_phys_offs(mobj, granule);
62*185b4595SMarouene Boubakri 	return 0;
63*185b4595SMarouene Boubakri }
64*185b4595SMarouene Boubakri 
65*185b4595SMarouene Boubakri static inline TEE_Result mobj_get_cattr(struct mobj *mobj, uint32_t *cattr)
66*185b4595SMarouene Boubakri {
67*185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_cattr)
68*185b4595SMarouene Boubakri 		return mobj->ops->get_cattr(mobj, cattr);
69*185b4595SMarouene Boubakri 	return TEE_ERROR_GENERIC;
70*185b4595SMarouene Boubakri }
71*185b4595SMarouene Boubakri 
72*185b4595SMarouene Boubakri static inline bool mobj_matches(struct mobj *mobj, enum buf_is_attr attr)
73*185b4595SMarouene Boubakri {
74*185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->matches)
75*185b4595SMarouene Boubakri 		return mobj->ops->matches(mobj, attr);
76*185b4595SMarouene Boubakri 	return false;
77*185b4595SMarouene Boubakri }
78*185b4595SMarouene Boubakri 
79*185b4595SMarouene Boubakri /**
80*185b4595SMarouene Boubakri  * mobj_inc_map() - increase map count
81*185b4595SMarouene Boubakri  * @mobj:	pointer to a MOBJ
82*185b4595SMarouene Boubakri  *
83*185b4595SMarouene Boubakri  * Maps the MOBJ if it isn't mapped already and increases the map count
84*185b4595SMarouene Boubakri  * Each call to mobj_inc_map() is supposed to be matches by a call to
85*185b4595SMarouene Boubakri  * mobj_dec_map().
86*185b4595SMarouene Boubakri  *
87*185b4595SMarouene Boubakri  * Returns TEE_SUCCESS on success or an error code on failure
88*185b4595SMarouene Boubakri  */
89*185b4595SMarouene Boubakri static inline TEE_Result mobj_inc_map(struct mobj *mobj)
90*185b4595SMarouene Boubakri {
91*185b4595SMarouene Boubakri 	if (mobj && mobj->ops) {
92*185b4595SMarouene Boubakri 		if (mobj->ops->inc_map)
93*185b4595SMarouene Boubakri 			return mobj->ops->inc_map(mobj);
94*185b4595SMarouene Boubakri 		return TEE_SUCCESS;
95*185b4595SMarouene Boubakri 	}
96*185b4595SMarouene Boubakri 	return TEE_ERROR_GENERIC;
97*185b4595SMarouene Boubakri }
98*185b4595SMarouene Boubakri 
99*185b4595SMarouene Boubakri /**
100*185b4595SMarouene Boubakri  * mobj_dec_map() - decrease map count
101*185b4595SMarouene Boubakri  * @mobj:	pointer to a MOBJ
102*185b4595SMarouene Boubakri  *
103*185b4595SMarouene Boubakri  * Decreases the map count and also unmaps the MOBJ if the map count
104*185b4595SMarouene Boubakri  * reaches 0.  Each call to mobj_inc_map() is supposed to be matched by a
105*185b4595SMarouene Boubakri  * call to mobj_dec_map().
106*185b4595SMarouene Boubakri  *
107*185b4595SMarouene Boubakri  * Returns TEE_SUCCESS on success or an error code on failure
108*185b4595SMarouene Boubakri  */
109*185b4595SMarouene Boubakri static inline TEE_Result mobj_dec_map(struct mobj *mobj)
110*185b4595SMarouene Boubakri {
111*185b4595SMarouene Boubakri 	if (mobj && mobj->ops) {
112*185b4595SMarouene Boubakri 		if (mobj->ops->dec_map)
113*185b4595SMarouene Boubakri 			return mobj->ops->dec_map(mobj);
114*185b4595SMarouene Boubakri 		return TEE_SUCCESS;
115*185b4595SMarouene Boubakri 	}
116*185b4595SMarouene Boubakri 	return TEE_ERROR_GENERIC;
117*185b4595SMarouene Boubakri }
118*185b4595SMarouene Boubakri 
119*185b4595SMarouene Boubakri /**
120*185b4595SMarouene Boubakri  * mobj_get() - get a MOBJ
121*185b4595SMarouene Boubakri  * @mobj:	Pointer to a MOBJ or NULL
122*185b4595SMarouene Boubakri  *
123*185b4595SMarouene Boubakri  * Increases reference counter of the @mobj
124*185b4595SMarouene Boubakri  *
125*185b4595SMarouene Boubakri  * Returns @mobj with reference counter increased or NULL if @mobj was NULL
126*185b4595SMarouene Boubakri  */
127*185b4595SMarouene Boubakri static inline struct mobj *mobj_get(struct mobj *mobj)
128*185b4595SMarouene Boubakri {
129*185b4595SMarouene Boubakri 	if (mobj && !refcount_inc(&mobj->refc))
130*185b4595SMarouene Boubakri 		panic();
131*185b4595SMarouene Boubakri 
132*185b4595SMarouene Boubakri 	return mobj;
133*185b4595SMarouene Boubakri }
134*185b4595SMarouene Boubakri 
135*185b4595SMarouene Boubakri /**
136*185b4595SMarouene Boubakri  * mobj_put() - put a MOBJ
137*185b4595SMarouene Boubakri  * @mobj:	Pointer to a MOBJ or NULL
138*185b4595SMarouene Boubakri  *
139*185b4595SMarouene Boubakri  * Decreases reference counter of the @mobj and frees it if the counter
140*185b4595SMarouene Boubakri  * reaches 0.
141*185b4595SMarouene Boubakri  */
142*185b4595SMarouene Boubakri static inline void mobj_put(struct mobj *mobj)
143*185b4595SMarouene Boubakri {
144*185b4595SMarouene Boubakri 	if (mobj && refcount_dec(&mobj->refc))
145*185b4595SMarouene Boubakri 		mobj->ops->free(mobj);
146*185b4595SMarouene Boubakri }
147*185b4595SMarouene Boubakri 
148*185b4595SMarouene Boubakri /**
149*185b4595SMarouene Boubakri  * mobj_put_wipe() - wipe and put a MOBJ
150*185b4595SMarouene Boubakri  * @mobj:	Pointer to a MOBJ or NULL
151*185b4595SMarouene Boubakri  *
152*185b4595SMarouene Boubakri  * Clears the memory represented by the mobj and then puts it.
153*185b4595SMarouene Boubakri  */
154*185b4595SMarouene Boubakri static inline void mobj_put_wipe(struct mobj *mobj)
155*185b4595SMarouene Boubakri {
156*185b4595SMarouene Boubakri 	void *buf = mobj_get_va(mobj, 0);
157*185b4595SMarouene Boubakri 
158*185b4595SMarouene Boubakri 	if (buf)
159*185b4595SMarouene Boubakri 		memzero_explicit(buf, mobj->size);
160*185b4595SMarouene Boubakri 	mobj_put(mobj);
161*185b4595SMarouene Boubakri }
162*185b4595SMarouene Boubakri 
163*185b4595SMarouene Boubakri static inline uint64_t mobj_get_cookie(struct mobj *mobj)
164*185b4595SMarouene Boubakri {
165*185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_cookie)
166*185b4595SMarouene Boubakri 		return mobj->ops->get_cookie(mobj);
167*185b4595SMarouene Boubakri 
168*185b4595SMarouene Boubakri 	return 0;
169*185b4595SMarouene Boubakri }
170*185b4595SMarouene Boubakri 
171*185b4595SMarouene Boubakri static inline struct fobj *mobj_get_fobj(struct mobj *mobj)
172*185b4595SMarouene Boubakri {
173*185b4595SMarouene Boubakri 	if (mobj && mobj->ops && mobj->ops->get_fobj)
174*185b4595SMarouene Boubakri 		return mobj->ops->get_fobj(mobj);
175*185b4595SMarouene Boubakri 
176*185b4595SMarouene Boubakri 	return NULL;
177*185b4595SMarouene Boubakri }
178*185b4595SMarouene Boubakri 
179*185b4595SMarouene Boubakri static inline bool mobj_is_nonsec(struct mobj *mobj)
180*185b4595SMarouene Boubakri {
181*185b4595SMarouene Boubakri 	return mobj_matches(mobj, CORE_MEM_NON_SEC);
182*185b4595SMarouene Boubakri }
183*185b4595SMarouene Boubakri 
184*185b4595SMarouene Boubakri static inline bool mobj_is_secure(struct mobj *mobj)
185*185b4595SMarouene Boubakri {
186*185b4595SMarouene Boubakri 	return mobj_matches(mobj, CORE_MEM_SEC);
187*185b4595SMarouene Boubakri }
188*185b4595SMarouene Boubakri 
189*185b4595SMarouene Boubakri static inline bool mobj_is_sdp_mem(struct mobj *mobj)
190*185b4595SMarouene Boubakri {
191*185b4595SMarouene Boubakri 	return mobj_matches(mobj, CORE_MEM_SDP_MEM);
192*185b4595SMarouene Boubakri }
193*185b4595SMarouene Boubakri 
194*185b4595SMarouene Boubakri static inline size_t mobj_get_phys_granule(struct mobj *mobj)
195*185b4595SMarouene Boubakri {
196*185b4595SMarouene Boubakri 	if (mobj->phys_granule)
197*185b4595SMarouene Boubakri 		return mobj->phys_granule;
198*185b4595SMarouene Boubakri 	return mobj->size;
199*185b4595SMarouene Boubakri }
200*185b4595SMarouene Boubakri 
201*185b4595SMarouene Boubakri struct mobj *mobj_mm_alloc(struct mobj *mobj_parent, size_t size,
202*185b4595SMarouene Boubakri 			   tee_mm_pool_t *pool);
203*185b4595SMarouene Boubakri 
204*185b4595SMarouene Boubakri struct mobj *mobj_phys_alloc(paddr_t pa, size_t size, uint32_t cattr,
205*185b4595SMarouene Boubakri 			     enum buf_is_attr battr);
206*185b4595SMarouene Boubakri 
207*185b4595SMarouene Boubakri #if defined(CFG_CORE_FFA)
208*185b4595SMarouene Boubakri struct mobj *mobj_ffa_get_by_cookie(uint64_t cookie,
209*185b4595SMarouene Boubakri 				    unsigned int internal_offs);
210*185b4595SMarouene Boubakri 
211*185b4595SMarouene Boubakri TEE_Result mobj_ffa_unregister_by_cookie(uint64_t cookie);
212*185b4595SMarouene Boubakri 
213*185b4595SMarouene Boubakri /* Functions for SPMC */
214*185b4595SMarouene Boubakri #ifdef CFG_CORE_SEL1_SPMC
215*185b4595SMarouene Boubakri struct mobj_ffa *mobj_ffa_sel1_spmc_new(unsigned int num_pages);
216*185b4595SMarouene Boubakri void mobj_ffa_sel1_spmc_delete(struct mobj_ffa *mobj);
217*185b4595SMarouene Boubakri TEE_Result mobj_ffa_sel1_spmc_reclaim(uint64_t cookie);
218*185b4595SMarouene Boubakri #endif
219*185b4595SMarouene Boubakri uint64_t mobj_ffa_get_cookie(struct mobj_ffa *mobj);
220*185b4595SMarouene Boubakri TEE_Result mobj_ffa_add_pages_at(struct mobj_ffa *mobj, unsigned int *idx,
221*185b4595SMarouene Boubakri 				 paddr_t pa, unsigned int num_pages);
222*185b4595SMarouene Boubakri uint64_t mobj_ffa_push_to_inactive(struct mobj_ffa *mobj);
223*185b4595SMarouene Boubakri 
224*185b4595SMarouene Boubakri #elif defined(CFG_CORE_DYN_SHM)
225*185b4595SMarouene Boubakri /* reg_shm represents TEE shared memory */
226*185b4595SMarouene Boubakri struct mobj *mobj_reg_shm_alloc(paddr_t *pages, size_t num_pages,
227*185b4595SMarouene Boubakri 				paddr_t page_offset, uint64_t cookie);
228*185b4595SMarouene Boubakri 
229*185b4595SMarouene Boubakri /**
230*185b4595SMarouene Boubakri  * mobj_reg_shm_get_by_cookie() - get a MOBJ based on cookie
231*185b4595SMarouene Boubakri  * @cookie:	Cookie used by normal world when suppling the shared memory
232*185b4595SMarouene Boubakri  *
233*185b4595SMarouene Boubakri  * Searches for a registered shared memory MOBJ and if one with a matching
234*185b4595SMarouene Boubakri  * @cookie is found its reference counter is increased before returning
235*185b4595SMarouene Boubakri  * the MOBJ.
236*185b4595SMarouene Boubakri  *
237*185b4595SMarouene Boubakri  * Returns a valid pointer on success or NULL on failure.
238*185b4595SMarouene Boubakri  */
239*185b4595SMarouene Boubakri struct mobj *mobj_reg_shm_get_by_cookie(uint64_t cookie);
240*185b4595SMarouene Boubakri 
241*185b4595SMarouene Boubakri TEE_Result mobj_reg_shm_release_by_cookie(uint64_t cookie);
242*185b4595SMarouene Boubakri 
243*185b4595SMarouene Boubakri /**
244*185b4595SMarouene Boubakri  * mobj_reg_shm_unguard() - unguards a reg_shm
245*185b4595SMarouene Boubakri  * @mobj:	pointer to a registered shared memory mobj
246*185b4595SMarouene Boubakri  *
247*185b4595SMarouene Boubakri  * A registered shared memory mobj is normally guarded against being
248*185b4595SMarouene Boubakri  * released with mobj_reg_shm_try_release_by_cookie(). After this function
249*185b4595SMarouene Boubakri  * has returned the mobj can be released by a call to
250*185b4595SMarouene Boubakri  * mobj_reg_shm_try_release_by_cookie() if the reference counter allows it.
251*185b4595SMarouene Boubakri  */
252*185b4595SMarouene Boubakri void mobj_reg_shm_unguard(struct mobj *mobj);
253*185b4595SMarouene Boubakri 
254*185b4595SMarouene Boubakri /*
255*185b4595SMarouene Boubakri  * mapped_shm represents registered shared buffer
256*185b4595SMarouene Boubakri  * which is mapped into OPTEE va space
257*185b4595SMarouene Boubakri  */
258*185b4595SMarouene Boubakri struct mobj *mobj_mapped_shm_alloc(paddr_t *pages, size_t num_pages,
259*185b4595SMarouene Boubakri 				   paddr_t page_offset, uint64_t cookie);
260*185b4595SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/
261*185b4595SMarouene Boubakri 
262*185b4595SMarouene Boubakri #if !defined(CFG_CORE_DYN_SHM)
263*185b4595SMarouene Boubakri static inline struct mobj *mobj_mapped_shm_alloc(paddr_t *pages __unused,
264*185b4595SMarouene Boubakri 						 size_t num_pages __unused,
265*185b4595SMarouene Boubakri 						 paddr_t page_offset __unused,
266*185b4595SMarouene Boubakri 						 uint64_t cookie __unused)
267*185b4595SMarouene Boubakri {
268*185b4595SMarouene Boubakri 	return NULL;
269*185b4595SMarouene Boubakri }
270*185b4595SMarouene Boubakri #endif
271*185b4595SMarouene Boubakri 
272*185b4595SMarouene Boubakri struct mobj *mobj_shm_alloc(paddr_t pa, size_t size, uint64_t cookie);
273*185b4595SMarouene Boubakri 
274*185b4595SMarouene Boubakri #ifdef CFG_PAGED_USER_TA
275*185b4595SMarouene Boubakri bool mobj_is_paged(struct mobj *mobj);
276*185b4595SMarouene Boubakri #else
277*185b4595SMarouene Boubakri static inline bool mobj_is_paged(struct mobj *mobj __unused)
278*185b4595SMarouene Boubakri {
279*185b4595SMarouene Boubakri 	return false;
280*185b4595SMarouene Boubakri }
281*185b4595SMarouene Boubakri #endif
282*185b4595SMarouene Boubakri 
283*185b4595SMarouene Boubakri struct mobj *mobj_seccpy_shm_alloc(size_t size);
284*185b4595SMarouene Boubakri 
285*185b4595SMarouene Boubakri struct mobj *mobj_with_fobj_alloc(struct fobj *fobj, struct file *file);
286*185b4595SMarouene Boubakri 
287*185b4595SMarouene Boubakri #endif /*__MM_MOBJ_H*/
288