xref: /optee_os/core/include/mm/pgt_cache.h (revision 2f4d97e7664270c92f4fd9d35fcddcfa4fd5f667)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2016, Linaro Limited
4  */
5 #ifndef MM_PGT_CACHE_H
6 #define MM_PGT_CACHE_H
7 
8 #ifdef CFG_WITH_LPAE
9 #define PGT_SIZE	(4 * 1024)
10 #define PGT_NUM_PGT_PER_PAGE	1
11 #else
12 #define PGT_SIZE	(1 * 1024)
13 #define PGT_NUM_PGT_PER_PAGE	4
14 #endif
15 
16 #include <assert.h>
17 #include <kernel/tee_ta_manager.h>
18 #include <sys/queue.h>
19 #include <types_ext.h>
20 #include <util.h>
21 
22 struct ts_ctx;
23 
24 struct pgt {
25 	void *tbl;
26 	vaddr_t vabase;
27 #if defined(CFG_PAGED_USER_TA)
28 	struct ts_ctx *ctx;
29 	size_t num_used_entries;
30 #endif
31 #if defined(CFG_WITH_PAGER)
32 #if !defined(CFG_WITH_LPAE)
33 	struct pgt_parent *parent;
34 #endif
35 #endif
36 	SLIST_ENTRY(pgt) link;
37 };
38 
39 /*
40  * A proper value for PGT_CACHE_SIZE depends on many factors: CFG_WITH_LPAE,
41  * CFG_TA_ASLR, size of TA, size of memrefs passed to TA, CFG_ULIBS_SHARED and
42  * possibly others. The value is based on the number of threads as an indicator
43  * on how large the system might be.
44  */
45 #if CFG_NUM_THREADS < 2
46 #define PGT_CACHE_SIZE	4
47 #elif (CFG_NUM_THREADS == 2 && !defined(CFG_WITH_LPAE))
48 #define PGT_CACHE_SIZE	8
49 #else
50 #define PGT_CACHE_SIZE	ROUNDUP(CFG_NUM_THREADS * 2, PGT_NUM_PGT_PER_PAGE)
51 #endif
52 
53 SLIST_HEAD(pgt_cache, pgt);
54 
55 bool pgt_check_avail(struct vm_info *vm_info);
56 
57 void pgt_alloc(struct pgt_cache *pgt_cache, struct ts_ctx *owning_ctx,
58 	       struct vm_info *vm_info);
59 void pgt_free(struct pgt_cache *pgt_cache, bool save_ctx);
60 
61 void pgt_clear_ctx_range(struct pgt_cache *pgt_cache, struct ts_ctx *ctx,
62 			 vaddr_t begin, vaddr_t end);
63 #ifdef CFG_PAGED_USER_TA
64 void pgt_flush_ctx_range(struct pgt_cache *pgt_cache, struct ts_ctx *ctx,
65 			 vaddr_t begin, vaddr_t last);
66 #else
67 static inline void pgt_flush_ctx_range(struct pgt_cache *pgt_cache __unused,
68 				       struct ts_ctx *ctx __unused,
69 				       vaddr_t begin __unused,
70 				       vaddr_t last __unused)
71 {
72 }
73 #endif
74 
75 void pgt_init(void);
76 
77 #if defined(CFG_PAGED_USER_TA)
78 void pgt_flush_ctx(struct ts_ctx *ctx);
79 
80 static inline void pgt_inc_used_entries(struct pgt *pgt)
81 {
82 	pgt->num_used_entries++;
83 	assert(pgt->num_used_entries);
84 }
85 
86 static inline void pgt_dec_used_entries(struct pgt *pgt)
87 {
88 	assert(pgt->num_used_entries);
89 	pgt->num_used_entries--;
90 }
91 
92 static inline void pgt_set_used_entries(struct pgt *pgt, size_t val)
93 {
94 	pgt->num_used_entries = val;
95 }
96 
97 #else
98 static inline void pgt_flush_ctx(struct ts_ctx *ctx __unused)
99 {
100 }
101 
102 static inline void pgt_inc_used_entries(struct pgt *pgt __unused)
103 {
104 }
105 
106 static inline void pgt_dec_used_entries(struct pgt *pgt __unused)
107 {
108 }
109 
110 static inline void pgt_set_used_entries(struct pgt *pgt __unused,
111 					size_t val __unused)
112 {
113 }
114 
115 #endif
116 
117 #endif /*MM_PGT_CACHE_H*/
118