xref: /optee_os/core/arch/riscv/mm/core_mmu_arch.c (revision 42f39b523d2280a7551085517ffe74b3f3945570)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2022-2023 NXP
4  */
5 
6 #include <assert.h>
7 #include <bitstring.h>
8 #include <config.h>
9 #include <kernel/boot.h>
10 #include <kernel/cache_helpers.h>
11 #include <kernel/misc.h>
12 #include <kernel/panic.h>
13 #include <kernel/spinlock.h>
14 #include <kernel/tee_l2cc_mutex.h>
15 #include <kernel/tee_misc.h>
16 #include <kernel/tlb_helpers.h>
17 #include <mm/core_memprot.h>
18 #include <mm/core_mmu.h>
19 #include <mm/phys_mem.h>
20 #include <platform_config.h>
21 #include <riscv.h>
22 #include <stdalign.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <trace.h>
26 #include <util.h>
27 
28 #ifndef RV64
29 #error implement
30 #endif
31 
32 #ifndef DEBUG_XLAT_TABLE
33 #define DEBUG_XLAT_TABLE 0
34 #endif
35 
36 #if DEBUG_XLAT_TABLE
37 #define debug_print(...) DMSG_RAW(__VA_ARGS__)
38 #else
39 #define debug_print(...) ((void)0)
40 #endif
41 
42 #define IS_PAGE_ALIGNED(addr)	IS_ALIGNED(addr, SMALL_PAGE_SIZE)
43 
44 static bitstr_t bit_decl(g_asid, RISCV_SATP_ASID_WIDTH) __nex_bss;
45 static unsigned int g_asid_spinlock __nex_bss = SPINLOCK_UNLOCK;
46 
47 struct mmu_pte {
48 	unsigned long entry;
49 };
50 
51 struct mmu_pgt {
52 	struct mmu_pte entries[RISCV_PTES_PER_PT];
53 };
54 
55 #define RISCV_MMU_PGT_SIZE	(sizeof(struct mmu_pgt))
56 
57 #ifndef CFG_DYN_CONFIG
58 static struct mmu_pgt root_pgt[CFG_TEE_CORE_NB_CORE]
59 	__aligned(RISCV_PGSIZE)
60 	__section(".nozi.mmu.root_pgt");
61 
62 static struct mmu_pgt pool_pgts[RISCV_MMU_MAX_PGTS]
63 	__aligned(RISCV_PGSIZE) __section(".nozi.mmu.pool_pgts");
64 
65 static struct mmu_pgt user_pgts[CFG_NUM_THREADS]
66 	__aligned(RISCV_PGSIZE) __section(".nozi.mmu.usr_pgts");
67 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
68 static struct mmu_pgt *user_vpn2_table_va[CFG_TEE_CORE_NB_CORE];
69 #endif
70 #endif
71 
72 static int user_va_idx __nex_data = -1;
73 
74 struct mmu_partition {
75 	struct mmu_pgt *root_pgt;
76 	struct mmu_pgt *pool_pgts;
77 	struct mmu_pgt *user_pgts;
78 	unsigned int pgts_used;
79 	unsigned int asid;
80 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
81 	struct mmu_pgt **user_vpn2_table_va;
82 #endif
83 };
84 
85 #ifdef CFG_DYN_CONFIG
86 static struct mmu_partition default_partition __nex_bss;
87 #else
88 static struct mmu_partition default_partition __nex_data  = {
89 	.root_pgt = root_pgt,
90 	.pool_pgts = pool_pgts,
91 	.user_pgts = user_pgts,
92 	.pgts_used = 0,
93 	.asid = 0,
94 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
95 	.user_vpn2_table_va = user_vpn2_table_va,
96 #endif
97 };
98 #endif
99 
core_mmu_table_get_entry(struct mmu_pgt * pgt,unsigned int idx)100 static struct mmu_pte *core_mmu_table_get_entry(struct mmu_pgt *pgt,
101 						unsigned int idx)
102 {
103 	return &pgt->entries[idx & RISCV_MMU_VPN_MASK];
104 }
105 
core_mmu_entry_set(struct mmu_pte * pte,uint64_t val)106 static void core_mmu_entry_set(struct mmu_pte *pte, uint64_t val)
107 {
108 	pte->entry = val;
109 }
110 
core_mmu_entry_get(struct mmu_pte * pte)111 static uint64_t core_mmu_entry_get(struct mmu_pte *pte)
112 {
113 	return pte->entry;
114 }
115 
core_mmu_entry_is_valid(struct mmu_pte * pte)116 static bool core_mmu_entry_is_valid(struct mmu_pte *pte)
117 {
118 	return pte->entry & PTE_V;
119 }
120 
core_mmu_entry_is_invalid(struct mmu_pte * pte)121 static bool core_mmu_entry_is_invalid(struct mmu_pte *pte)
122 {
123 	return !core_mmu_entry_is_valid(pte);
124 }
125 
core_mmu_entry_is_leaf(struct mmu_pte * pte)126 static bool core_mmu_entry_is_leaf(struct mmu_pte *pte)
127 {
128 	/* A leaf has one or more RWX bits set */
129 	return pte->entry & (PTE_R | PTE_W | PTE_X);
130 }
131 
core_mmu_entry_is_branch(struct mmu_pte * pte)132 static bool __maybe_unused core_mmu_entry_is_branch(struct mmu_pte *pte)
133 {
134 	return core_mmu_entry_is_valid(pte) && !core_mmu_entry_is_leaf(pte);
135 }
136 
core_mmu_pte_create(unsigned long ppn,uint8_t pte_bits)137 static unsigned long core_mmu_pte_create(unsigned long ppn, uint8_t pte_bits)
138 {
139 	/*
140 	 * This function may be called from core_mmu_set_entry(). There is a
141 	 * case that MM core wants to clear PTE by calling core_mmu_set_entry()
142 	 * with zero physical address and zero memory attributes, which turns
143 	 * @ppn and @pte_bits in this function to be both zero. In this case, we
144 	 * should create zero PTE without setting its V bit.
145 	 */
146 
147 	return SHIFT_U64(ppn, PTE_PPN_SHIFT) | pte_bits;
148 }
149 
core_mmu_ptp_create(unsigned long ppn)150 static unsigned long core_mmu_ptp_create(unsigned long ppn)
151 {
152 	/* Set V bit to create PTE points to next level of the page table. */
153 	return core_mmu_pte_create(ppn, PTE_V);
154 }
155 
core_mmu_pte_ppn(struct mmu_pte * pte)156 static unsigned long core_mmu_pte_ppn(struct mmu_pte *pte)
157 {
158 	return (pte->entry & PTE_PPN) >> PTE_PPN_SHIFT;
159 }
160 
pa_to_ppn(paddr_t pa)161 static unsigned long pa_to_ppn(paddr_t pa)
162 {
163 	return pa >> RISCV_PGSHIFT;
164 }
165 
pte_to_pa(struct mmu_pte * pte)166 static paddr_t pte_to_pa(struct mmu_pte *pte)
167 {
168 	return SHIFT_U64(core_mmu_pte_ppn(pte), RISCV_PGSHIFT);
169 }
170 
core_mmu_pgt_to_satp(unsigned long asid,struct mmu_pgt * pgt)171 static unsigned long core_mmu_pgt_to_satp(unsigned long asid,
172 					  struct mmu_pgt *pgt)
173 {
174 	unsigned long satp = 0;
175 	unsigned long pgt_ppn = (paddr_t)pgt >> RISCV_PGSHIFT;
176 
177 	assert(!cpu_mmu_enabled());
178 
179 	satp |= SHIFT_U64(asid, RISCV_SATP_ASID_SHIFT);
180 	satp |= SHIFT_U64(RISCV_SATP_MODE, RISCV_SATP_MODE_SHIFT);
181 	satp |= pgt_ppn;
182 
183 	return satp;
184 }
185 
pte_to_mattr(unsigned level __maybe_unused,struct mmu_pte * pte)186 static unsigned long pte_to_mattr(unsigned level __maybe_unused,
187 				  struct mmu_pte *pte)
188 {
189 	unsigned long mattr = TEE_MATTR_SECURE;
190 	unsigned long entry = core_mmu_entry_get(pte);
191 
192 	if (entry & PTE_V) {
193 		if (!(entry & (PTE_R | PTE_W | PTE_X)))
194 			return TEE_MATTR_TABLE;
195 
196 		mattr |=  TEE_MATTR_VALID_BLOCK;
197 	}
198 
199 	if (entry & PTE_U) {
200 		if (entry & PTE_R)
201 			mattr |= TEE_MATTR_UR | TEE_MATTR_PR;
202 		if (entry & PTE_W)
203 			mattr |= TEE_MATTR_UW | TEE_MATTR_PW;
204 		if (entry & PTE_X)
205 			mattr |= TEE_MATTR_UX | TEE_MATTR_PX;
206 	} else {
207 		if (entry & PTE_R)
208 			mattr |= TEE_MATTR_PR;
209 		if (entry & PTE_W)
210 			mattr |= TEE_MATTR_PW;
211 		if (entry & PTE_X)
212 			mattr |= TEE_MATTR_PX;
213 	}
214 
215 	if (entry & PTE_G)
216 		mattr |= TEE_MATTR_GLOBAL;
217 
218 	return mattr;
219 }
220 
mattr_to_pte_bits(unsigned level __maybe_unused,uint32_t attr)221 static uint8_t mattr_to_pte_bits(unsigned level __maybe_unused, uint32_t attr)
222 {
223 	unsigned long pte_bits = 0;
224 
225 	if (attr & TEE_MATTR_TABLE)
226 		return PTE_V;
227 
228 	if (attr & TEE_MATTR_VALID_BLOCK)
229 		pte_bits |= PTE_V;
230 
231 	if (attr & TEE_MATTR_UR)
232 		pte_bits |= PTE_R | PTE_U;
233 	if (attr & TEE_MATTR_UW)
234 		pte_bits |= PTE_W | PTE_U;
235 	if (attr & TEE_MATTR_UX)
236 		pte_bits |= PTE_X | PTE_U;
237 
238 	if (attr & TEE_MATTR_PR)
239 		pte_bits |= PTE_R;
240 	if (attr & TEE_MATTR_PW)
241 		pte_bits |= PTE_W | PTE_R;
242 	if (attr & TEE_MATTR_PX)
243 		pte_bits |= PTE_X | PTE_R;
244 
245 	if (attr & (TEE_MATTR_UR | TEE_MATTR_PR))
246 		pte_bits |= PTE_A;
247 
248 	if (attr & (TEE_MATTR_UW | TEE_MATTR_PW))
249 		pte_bits |= PTE_D;
250 
251 	if (attr & TEE_MATTR_GLOBAL)
252 		pte_bits |= PTE_G;
253 
254 	return pte_bits;
255 }
256 
core_mmu_pgt_idx(vaddr_t va,unsigned int level)257 static unsigned int core_mmu_pgt_idx(vaddr_t va, unsigned int level)
258 {
259 	unsigned int idx = va >> CORE_MMU_SHIFT_OF_LEVEL(level);
260 
261 	return idx & RISCV_MMU_VPN_MASK;
262 }
263 
264 /* Get the pointed VA base of specific PTE in page table */
core_mmu_pgt_get_va_base(unsigned int level,unsigned int idx)265 static inline vaddr_t core_mmu_pgt_get_va_base(unsigned int level,
266 					       unsigned int idx)
267 {
268 #ifdef RV32
269 	return SHIFT_U32(idx, CORE_MMU_SHIFT_OF_LEVEL(level));
270 #else
271 	vaddr_t va_base = SHIFT_U64(idx, CORE_MMU_SHIFT_OF_LEVEL(level));
272 	vaddr_t va_width_msb = BIT64(RISCV_MMU_VA_WIDTH - 1);
273 	vaddr_t va_extended_mask = GENMASK_64(63, RISCV_MMU_VA_WIDTH);
274 
275 	if (va_base & va_width_msb)
276 		return va_extended_mask | va_base;
277 
278 	return va_base;
279 #endif
280 }
281 
core_mmu_get_prtn(void)282 static struct mmu_partition *core_mmu_get_prtn(void)
283 {
284 	return &default_partition;
285 }
286 
core_mmu_get_root_pgt_va(struct mmu_partition * prtn,size_t core_pos)287 static struct mmu_pgt *core_mmu_get_root_pgt_va(struct mmu_partition *prtn,
288 						size_t core_pos)
289 {
290 	assert(core_pos < CFG_TEE_CORE_NB_CORE);
291 
292 	return prtn->root_pgt + core_pos;
293 }
294 
core_mmu_get_ta_pgt_va(struct mmu_partition * prtn)295 static struct mmu_pgt *core_mmu_get_ta_pgt_va(struct mmu_partition *prtn)
296 {
297 	return &prtn->user_pgts[thread_get_id()];
298 }
299 
core_mmu_pgt_alloc(struct mmu_partition * prtn)300 static struct mmu_pgt *core_mmu_pgt_alloc(struct mmu_partition *prtn)
301 {
302 	struct mmu_pgt *pgt = NULL;
303 
304 	if (IS_ENABLED(CFG_DYN_CONFIG)) {
305 		if (cpu_mmu_enabled()) {
306 			tee_mm_entry_t *mm = NULL;
307 			paddr_t pa = 0;
308 			size_t size = RISCV_MMU_PGT_SIZE;
309 
310 			if (prtn == core_mmu_get_prtn()) {
311 				mm = phys_mem_core_alloc(size);
312 				if (!mm)
313 					EMSG("Phys mem exhausted");
314 			} else {
315 				mm = nex_phys_mem_core_alloc(size);
316 				if (!mm)
317 					EMSG("Phys nex mem exhausted");
318 			}
319 			if (!mm)
320 				return NULL;
321 			pa = tee_mm_get_smem(mm);
322 
323 			pgt = phys_to_virt(pa, MEM_AREA_SEC_RAM_OVERALL,
324 					   RISCV_MMU_PGT_SIZE);
325 			assert(pgt);
326 		} else {
327 			pgt = boot_mem_alloc(RISCV_MMU_PGT_SIZE,
328 					     RISCV_MMU_PGT_SIZE);
329 			if (prtn->pool_pgts) {
330 				assert((vaddr_t)prtn->pool_pgts +
331 				       prtn->pgts_used *
332 				       RISCV_MMU_PGT_SIZE == (vaddr_t)pgt);
333 			} else {
334 				boot_mem_add_reloc(&prtn->pool_pgts);
335 				prtn->pool_pgts = pgt;
336 			}
337 		}
338 
339 		memset(pgt, 0, RISCV_MMU_PGT_SIZE);
340 
341 		prtn->pgts_used++;
342 		DMSG("pgts used %u", prtn->pgts_used);
343 	} else {
344 		if (prtn->pgts_used >= RISCV_MMU_MAX_PGTS) {
345 			debug_print("%u pgts exhausted", RISCV_MMU_MAX_PGTS);
346 			return NULL;
347 		}
348 
349 		pgt = &prtn->pool_pgts[prtn->pgts_used++];
350 
351 		memset(pgt, 0, RISCV_MMU_PGT_SIZE);
352 
353 		DMSG("pgts used %u / %u", prtn->pgts_used,
354 		     RISCV_MMU_MAX_PGTS);
355 	}
356 
357 	return pgt;
358 }
359 
360 /*
361  * Given an entry that points to a table.
362  * If mmu is disabled, returns the pa of pointed table.
363  * If mmu is enabled, returns the va of pointed table.
364  * returns NULL otherwise.
365  */
core_mmu_xlat_table_entry_pa2va(struct mmu_pte * pte,struct mmu_pgt * pgt)366 static struct mmu_pgt *core_mmu_xlat_table_entry_pa2va(struct mmu_pte *pte,
367 						       struct mmu_pgt *pgt)
368 {
369 	struct mmu_pgt *va = NULL;
370 
371 	if (core_mmu_entry_is_invalid(pte) ||
372 	    core_mmu_entry_is_leaf(pte))
373 		return NULL;
374 
375 	if (!cpu_mmu_enabled())
376 		return (struct mmu_pgt *)pte_to_pa(pte);
377 
378 	va = phys_to_virt(pte_to_pa(pte), MEM_AREA_TEE_RAM_RW_DATA,
379 			  sizeof(*pgt));
380 	if (!va)
381 		va = phys_to_virt(pte_to_pa(pte), MEM_AREA_SEC_RAM_OVERALL,
382 				  sizeof(*pgt));
383 
384 	return va;
385 }
386 
387 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
core_mmu_get_vpn2_ta_table(struct mmu_partition * prtn,size_t core_pos)388 static struct mmu_pgt *core_mmu_get_vpn2_ta_table(struct mmu_partition *prtn,
389 						  size_t core_pos)
390 {
391 	assert(core_pos < CFG_TEE_CORE_NB_CORE);
392 	return prtn->user_vpn2_table_va[core_pos];
393 }
394 
core_mmu_set_vpn2_ta_table(struct mmu_partition * prtn,size_t core_pos,struct mmu_pgt * pgt)395 static void core_mmu_set_vpn2_ta_table(struct mmu_partition *prtn,
396 				       size_t core_pos, struct mmu_pgt *pgt)
397 {
398 	assert(core_pos < CFG_TEE_CORE_NB_CORE);
399 	prtn->user_vpn2_table_va[core_pos] = pgt;
400 }
401 
402 /*
403  * Giving a page table, return the base address of next level page table from
404  * given index of entry in it.
405  */
core_mmu_get_next_level_pgt(struct mmu_pgt * pgt,unsigned int idx)406 static struct mmu_pgt *core_mmu_get_next_level_pgt(struct mmu_pgt *pgt,
407 						   unsigned int idx)
408 {
409 	struct mmu_pte *pte = NULL;
410 
411 	pte = core_mmu_table_get_entry(pgt, idx);
412 	assert(core_mmu_entry_is_branch(pte));
413 
414 	return core_mmu_xlat_table_entry_pa2va(pte, pgt);
415 }
416 #endif
417 
418 /*
419  * For a table entry that points to a table - allocate and copy to
420  * a new pointed table. This is done for the requested entry,
421  * without going deeper into the pointed table entries.
422  *
423  * A success is returned for non-table entries, as nothing to do there.
424  */
425 __maybe_unused
core_mmu_entry_copy(struct core_mmu_table_info * tbl_info,unsigned int idx)426 static bool core_mmu_entry_copy(struct core_mmu_table_info *tbl_info,
427 				unsigned int idx)
428 {
429 	struct mmu_pgt *orig_pgt = NULL;
430 	struct mmu_pgt *new_pgt = NULL;
431 	struct mmu_pte *pte = NULL;
432 	struct mmu_partition *prtn = NULL;
433 	unsigned long ptp = 0;
434 
435 	prtn = &default_partition;
436 	assert(prtn);
437 
438 	if (idx >= tbl_info->num_entries)
439 		return false;
440 
441 	orig_pgt = tbl_info->table;
442 	pte = core_mmu_table_get_entry(orig_pgt, idx);
443 
444 	/* Nothing to do for non-table entries */
445 	if (core_mmu_entry_is_leaf(pte) || tbl_info->level >= RISCV_PGLEVELS)
446 		return true;
447 
448 	new_pgt = core_mmu_pgt_alloc(prtn);
449 	if (!new_pgt)
450 		return false;
451 
452 	orig_pgt = core_mmu_xlat_table_entry_pa2va(pte, orig_pgt);
453 	if (!orig_pgt)
454 		return false;
455 
456 	/* Copy original table content to new table */
457 	memcpy(new_pgt, orig_pgt, sizeof(struct mmu_pgt));
458 
459 	/* Point to the new table */
460 	ptp = core_mmu_ptp_create(pa_to_ppn((paddr_t)new_pgt));
461 	core_mmu_entry_set(pte, ptp);
462 
463 	return true;
464 }
465 
466 /*
467  * Setup entries inside level 4, 3, and 2 page tables for TAs memory mapping
468  *
469  * Sv39 - user_va_idx is already in level 2 page table, so nothing to do.
470  * Sv48 - we need to allocate entry 0 of level 3 page table, and let it point to
471  *        level 2 page table.
472  * Sv57 - we need to allocate entry 0 of level 4 page table, and let it point to
473  *        level 3 page table. We need to further allocate entry 0 of the level 3
474  *        page table, and let it point to level 2 page table.
475  */
core_init_mmu_prtn_ta_core(struct mmu_partition * prtn __maybe_unused,unsigned int core __maybe_unused)476 static void core_init_mmu_prtn_ta_core(struct mmu_partition *prtn
477 				       __maybe_unused,
478 				       unsigned int core __maybe_unused)
479 {
480 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
481 	unsigned int level = CORE_MMU_BASE_TABLE_LEVEL;
482 	struct core_mmu_table_info tbl_info = { };
483 	struct mmu_pgt *pgt = NULL;
484 	struct mmu_pte *pte = NULL;
485 
486 	assert(user_va_idx != -1);
487 
488 	while (level > CORE_MMU_VPN2_LEVEL) {
489 		if (level == CORE_MMU_BASE_TABLE_LEVEL) {
490 			/* First level: get root page table */
491 			pgt = core_mmu_get_root_pgt_va(prtn, core);
492 		} else {
493 			/* Other levels: get table from PTE of previous level */
494 			pgt = core_mmu_get_next_level_pgt(pgt, 0);
495 		}
496 
497 		core_mmu_set_info_table(&tbl_info, level, 0, pgt);
498 
499 		/*
500 		 * If this isn't the core that created the initial tables
501 		 * mappings, then the table must be copied,
502 		 * as it will hold pointer to the next mapping table
503 		 * that changes per core.
504 		 */
505 		if (core != get_core_pos()) {
506 			if (!core_mmu_entry_copy(&tbl_info, 0))
507 				panic();
508 		}
509 
510 		if (!core_mmu_entry_to_finer_grained(&tbl_info, 0, true))
511 			panic();
512 
513 		/* Now index 0 of the table should be pointer to next level. */
514 		pte = core_mmu_table_get_entry(pgt, 0);
515 		assert(core_mmu_entry_is_branch(pte));
516 
517 		level--;
518 	}
519 
520 	pgt = core_mmu_xlat_table_entry_pa2va(pte, pgt);
521 	assert(pgt);
522 	core_mmu_set_vpn2_ta_table(prtn, core, pgt);
523 #endif
524 }
525 
core_init_mmu_prtn_ta(struct mmu_partition * prtn)526 static void core_init_mmu_prtn_ta(struct mmu_partition *prtn)
527 {
528 	unsigned int core = 0;
529 
530 	assert(core_mmu_user_va_range_is_defined());
531 
532 	memset(prtn->user_pgts, 0, CFG_NUM_THREADS * RISCV_MMU_PGT_SIZE);
533 	for (core = 0; core < CFG_TEE_CORE_NB_CORE; core++)
534 		core_init_mmu_prtn_ta_core(prtn, core);
535 }
536 
core_init_mmu_prtn_tee(struct mmu_partition * prtn,struct memory_map * mem_map)537 static void core_init_mmu_prtn_tee(struct mmu_partition *prtn,
538 				   struct memory_map *mem_map)
539 {
540 	size_t n = 0;
541 
542 	assert(prtn && mem_map);
543 
544 	for (n = 0; n < mem_map->count; n++) {
545 		struct tee_mmap_region *mm = mem_map->map + n;
546 
547 		debug_print(" %010" PRIxVA " %010" PRIxPA " %10zx %x",
548 			    mm->va, mm->pa, mm->size, mm->attr);
549 
550 		if (!IS_PAGE_ALIGNED(mm->pa) || !IS_PAGE_ALIGNED(mm->size))
551 			panic("unaligned region");
552 	}
553 
554 	/* Clear table before using it. */
555 	memset(prtn->root_pgt, 0, RISCV_MMU_PGT_SIZE * CFG_TEE_CORE_NB_CORE);
556 
557 	for (n = 0; n < mem_map->count; n++)
558 		core_mmu_map_region(prtn, mem_map->map + n);
559 
560 	/*
561 	 * Primary mapping table is ready at index `get_core_pos()`
562 	 * whose value may not be ZERO. Take this index as copy source.
563 	 */
564 	for (n = 0; n < CFG_TEE_CORE_NB_CORE; n++) {
565 		if (n == get_core_pos())
566 			continue;
567 
568 		memcpy(core_mmu_get_root_pgt_va(prtn, n),
569 		       core_mmu_get_root_pgt_va(prtn, get_core_pos()),
570 		       RISCV_MMU_PGT_SIZE);
571 	}
572 }
573 
tlbi_va_range(vaddr_t va,size_t len,size_t granule)574 void tlbi_va_range(vaddr_t va, size_t len,
575 		   size_t granule)
576 {
577 	assert(granule == CORE_MMU_PGDIR_SIZE || granule == SMALL_PAGE_SIZE);
578 	assert(!(va & (granule - 1)) && !(len & (granule - 1)));
579 
580 	/*
581 	 * Ensure operations are completed or observed before proceeding
582 	 * with TLB invalidation.
583 	 */
584 	mb();
585 	while (len) {
586 		tlbi_va_allasid(va);
587 		len -= granule;
588 		va += granule;
589 	}
590 	/*
591 	 * After invalidating TLB entries, a memory barrier is required
592 	 * to ensure that the page table entries become visible to other harts
593 	 * before subsequent memory accesses are performed.
594 	 */
595 	mb();
596 }
597 
tlbi_va_range_asid(vaddr_t va,size_t len,size_t granule,uint32_t asid)598 void tlbi_va_range_asid(vaddr_t va, size_t len,
599 			size_t granule, uint32_t asid)
600 {
601 	assert(granule == CORE_MMU_PGDIR_SIZE || granule == SMALL_PAGE_SIZE);
602 	assert(!(va & (granule - 1)) && !(len & (granule - 1)));
603 
604 	/*
605 	 * A memory barrier is necessary here to ensure the consistency
606 	 * and correctness of memory accesses.
607 	 */
608 	mb();
609 	while (len) {
610 		tlbi_va_asid(va, asid);
611 		len -= granule;
612 		va += granule;
613 	}
614 	/* Enforce ordering of memory operations and ensure that all
615 	 * preceding memory operations are completed after TLB
616 	 * invalidation.
617 	 */
618 	mb();
619 }
620 
cache_op_inner(enum cache_op op,void * va,size_t len)621 TEE_Result cache_op_inner(enum cache_op op, void *va, size_t len)
622 {
623 	switch (op) {
624 	case DCACHE_CLEAN:
625 		dcache_op_all(DCACHE_OP_CLEAN);
626 		break;
627 	case DCACHE_AREA_CLEAN:
628 		dcache_clean_range(va, len);
629 		break;
630 	case DCACHE_INVALIDATE:
631 		dcache_op_all(DCACHE_OP_INV);
632 		break;
633 	case DCACHE_AREA_INVALIDATE:
634 		dcache_inv_range(va, len);
635 		break;
636 	case ICACHE_INVALIDATE:
637 		icache_inv_all();
638 		break;
639 	case ICACHE_AREA_INVALIDATE:
640 		icache_inv_range(va, len);
641 		break;
642 	case DCACHE_CLEAN_INV:
643 		dcache_op_all(DCACHE_OP_CLEAN_INV);
644 		break;
645 	case DCACHE_AREA_CLEAN_INV:
646 		dcache_cleaninv_range(va, len);
647 		break;
648 	default:
649 		return TEE_ERROR_NOT_IMPLEMENTED;
650 	}
651 	return TEE_SUCCESS;
652 }
653 
asid_alloc(void)654 unsigned int asid_alloc(void)
655 {
656 	uint32_t exceptions = cpu_spin_lock_xsave(&g_asid_spinlock);
657 	unsigned int r = 0;
658 	int i = 0;
659 
660 	bit_ffc(g_asid, (int)RISCV_SATP_ASID_WIDTH, &i);
661 	if (i == -1) {
662 		r = 0;
663 	} else {
664 		bit_set(g_asid, i);
665 		r = i + 1;
666 	}
667 
668 	cpu_spin_unlock_xrestore(&g_asid_spinlock, exceptions);
669 
670 	return r;
671 }
672 
asid_free(unsigned int asid)673 void asid_free(unsigned int asid)
674 {
675 	uint32_t exceptions = cpu_spin_lock_xsave(&g_asid_spinlock);
676 
677 	if (asid) {
678 		unsigned int i = asid - 1;
679 
680 		assert(i < RISCV_SATP_ASID_WIDTH && bit_test(g_asid, i));
681 		bit_clear(g_asid, i);
682 	}
683 
684 	cpu_spin_unlock_xrestore(&g_asid_spinlock, exceptions);
685 }
686 
arch_va2pa_helper(void * va,paddr_t * pa)687 bool arch_va2pa_helper(void *va, paddr_t *pa)
688 {
689 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
690 	vaddr_t vaddr = (vaddr_t)va;
691 	struct mmu_pgt *pgt = NULL;
692 	struct mmu_pte *pte = NULL;
693 	int level = 0;
694 	unsigned int idx = 0;
695 	struct mmu_partition *prtn = core_mmu_get_prtn();
696 	vaddr_t offset_mask = 0;
697 
698 	assert(pa);
699 
700 	pgt = core_mmu_get_root_pgt_va(prtn, get_core_pos());
701 
702 	for (level = CORE_MMU_BASE_TABLE_LEVEL; level >= 0; level--) {
703 		idx = core_mmu_pgt_idx(vaddr, level);
704 		pte = core_mmu_table_get_entry(pgt, idx);
705 
706 		if (core_mmu_entry_is_invalid(pte)) {
707 			thread_unmask_exceptions(exceptions);
708 			return false;
709 		} else if (core_mmu_entry_is_leaf(pte)) {
710 			offset_mask = CORE_MMU_PAGE_OFFSET_MASK(level);
711 			*pa = pte_to_pa(pte) | (vaddr & offset_mask);
712 			thread_unmask_exceptions(exceptions);
713 			return true;
714 		}
715 
716 		pgt = core_mmu_xlat_table_entry_pa2va(pte, pgt);
717 	}
718 
719 	thread_unmask_exceptions(exceptions);
720 	return false;
721 }
722 
arch_aslr_base_addr(vaddr_t start_addr,uint64_t seed,unsigned int iteration_count)723 vaddr_t arch_aslr_base_addr(vaddr_t start_addr, uint64_t seed,
724 			    unsigned int iteration_count)
725 {
726 	const unsigned int va_width = core_mmu_get_va_width();
727 	const vaddr_t va_mask = GENMASK_64(63, SMALL_PAGE_SHIFT);
728 	const vaddr_t va_width_msb = BIT64(va_width - 1);
729 	const vaddr_t va_extended_mask = GENMASK_64(63, va_width);
730 	vaddr_t base_addr = start_addr + seed;
731 
732 	if (iteration_count)
733 		base_addr ^= BIT64(va_width - iteration_count);
734 
735 	/*
736 	 * If the MSB is set, map the base address to the top
737 	 * half of the virtual address space by extending 1s
738 	 * to 64-bit; otherwise, map it to the bottom half.
739 	 */
740 	if (base_addr & va_width_msb)
741 		base_addr |= va_extended_mask;
742 	else
743 		base_addr &= ~va_extended_mask;
744 
745 	return base_addr & va_mask;
746 }
747 
cpu_mmu_enabled(void)748 bool cpu_mmu_enabled(void)
749 {
750 	return read_satp();
751 }
752 
core_mmu_find_table(struct mmu_partition * prtn,vaddr_t va,unsigned int max_level,struct core_mmu_table_info * tbl_info)753 bool core_mmu_find_table(struct mmu_partition *prtn, vaddr_t va,
754 			 unsigned int max_level,
755 			 struct core_mmu_table_info *tbl_info)
756 {
757 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
758 	struct mmu_pgt *pgt = NULL;
759 	struct mmu_pte *pte = NULL;
760 	unsigned int level = CORE_MMU_BASE_TABLE_LEVEL;
761 	unsigned int idx = 0;
762 	unsigned int deepest_level = max_level;
763 	vaddr_t va_base = 0;
764 	bool ret = false;
765 
766 	if (max_level == UINT_MAX)
767 		deepest_level = 0;
768 
769 	if (!prtn)
770 		prtn = core_mmu_get_prtn();
771 
772 	pgt = core_mmu_get_root_pgt_va(prtn, get_core_pos());
773 
774 	while (true) {
775 		idx = core_mmu_pgt_idx(va - va_base, level);
776 		pte = core_mmu_table_get_entry(pgt, idx);
777 		if (level == deepest_level || level == 0 ||
778 		    core_mmu_entry_is_invalid(pte) ||
779 		    core_mmu_entry_is_leaf(pte)) {
780 			core_mmu_set_info_table(tbl_info, level, va_base, pgt);
781 			ret = true;
782 			goto out;
783 		}
784 		pgt = core_mmu_xlat_table_entry_pa2va(pte, pgt);
785 		if (!pgt)
786 			goto out;
787 		va_base += core_mmu_pgt_get_va_base(level, idx);
788 		level--;
789 	}
790 out:
791 	thread_unmask_exceptions(exceptions);
792 	return ret;
793 }
794 
core_mmu_entry_to_finer_grained(struct core_mmu_table_info * tbl_info,unsigned int idx,bool secure __unused)795 bool core_mmu_entry_to_finer_grained(struct core_mmu_table_info *tbl_info,
796 				     unsigned int idx, bool secure __unused)
797 {
798 	struct mmu_pgt *pgt = NULL;
799 	struct mmu_pte *pte = NULL;
800 	struct mmu_partition *prtn = core_mmu_get_prtn();
801 	unsigned long ptp = 0;
802 	paddr_t pgt_pa = 0;
803 
804 	if (!core_mmu_level_in_range(tbl_info->level))
805 		return false;
806 
807 	pgt = tbl_info->table;
808 	pte = core_mmu_table_get_entry(pgt, idx);
809 
810 	if (core_mmu_entry_is_invalid(pte)) {
811 		pgt = core_mmu_pgt_alloc(prtn);
812 		if (!pgt)
813 			return false;
814 
815 		if (cpu_mmu_enabled())
816 			pgt_pa = virt_to_phys(pgt);
817 		else
818 			pgt_pa = (paddr_t)pgt;
819 
820 		ptp = core_mmu_ptp_create(pa_to_ppn(pgt_pa));
821 		core_mmu_entry_set(pte, ptp);
822 	}
823 
824 	return true;
825 }
826 
core_mmu_set_info_table(struct core_mmu_table_info * tbl_info,unsigned int level,vaddr_t va_base,void * table)827 void core_mmu_set_info_table(struct core_mmu_table_info *tbl_info,
828 			     unsigned int level, vaddr_t va_base, void *table)
829 {
830 	tbl_info->level = level;
831 	tbl_info->next_level = level - 1;
832 	tbl_info->table = table;
833 	tbl_info->va_base = va_base;
834 	tbl_info->shift = CORE_MMU_SHIFT_OF_LEVEL(level);
835 	assert(level < RISCV_PGLEVELS);
836 	tbl_info->num_entries = RISCV_PTES_PER_PT;
837 }
838 
core_mmu_get_entry_primitive(const void * table,size_t level,size_t idx,paddr_t * pa,uint32_t * attr)839 void core_mmu_get_entry_primitive(const void *table, size_t level,
840 				  size_t idx, paddr_t *pa, uint32_t *attr)
841 {
842 	struct mmu_pgt *pgt = (struct mmu_pgt *)table;
843 	struct mmu_pte *pte = core_mmu_table_get_entry(pgt, idx);
844 
845 	if (core_mmu_entry_is_valid(pte)) {
846 		if (pa)
847 			*pa = pte_to_pa(pte);
848 		if (attr)
849 			*attr = pte_to_mattr(level, pte);
850 	} else {
851 		if (pa)
852 			*pa = 0;
853 		if (attr)
854 			*attr = 0;
855 	}
856 }
857 
core_mmu_set_entry_primitive(void * table,size_t level,size_t idx,paddr_t pa,uint32_t attr)858 void core_mmu_set_entry_primitive(void *table, size_t level, size_t idx,
859 				  paddr_t pa, uint32_t attr)
860 {
861 	struct mmu_pgt *pgt = (struct mmu_pgt *)table;
862 	struct mmu_pte *pte = core_mmu_table_get_entry(pgt, idx);
863 	uint8_t pte_bits = mattr_to_pte_bits(level, attr);
864 
865 	core_mmu_entry_set(pte, core_mmu_pte_create(pa_to_ppn(pa), pte_bits));
866 }
867 
868 /*
869  * Due to OP-TEE design limitation, TAs page table should be an entry
870  * inside a level 2 (VPN[2]) page table.
871  *
872  * Available options are only these:
873  * For Sv57:
874  * - base level 4 entry 0 - [0GB, 256TB[
875  *   - level 3 entry 0 - [0GB, 512GB[
876  *     - level 2 entry 0 - [0GB, 1GB[
877  *     - level 2 entry 1 - [1GB, 2GB[           <----
878  *     - level 2 entry 2 - [2GB, 3GB[           <----
879  *     - level 2 entry 3 - [3GB, 4GB[           <----
880  *     - level 2 entry 4 - [4GB, 5GB[
881  *     - ...
882  *   - ...
883  * - ...
884  *
885  * For Sv48:
886  * - base level 3 entry 0 - [0GB, 512GB[
887  *   - level 2 entry 0 - [0GB, 1GB[
888  *   - level 2 entry 1 - [1GB, 2GB[           <----
889  *   - level 2 entry 2 - [2GB, 3GB[           <----
890  *   - level 2 entry 3 - [3GB, 4GB[           <----
891  *   - level 2 entry 4 - [4GB, 5GB[
892  *   - ...
893  * - ...
894  *
895  * For Sv39:
896  * - base level 2 entry 0 - [0GB, 1GB[
897  * - base level 2 entry 1 - [1GB, 2GB[        <----
898  * - base level 2 entry 2 - [2GB, 3GB[        <----
899  * - base level 2 entry 3 - [3GB, 4GB[        <----
900  * - base level 2 entry 4 - [4GB, 5GB[
901  * - ...
902  */
set_user_va_idx(struct mmu_partition * prtn)903 static void set_user_va_idx(struct mmu_partition *prtn)
904 {
905 	struct mmu_pgt *pgt = NULL;
906 	__maybe_unused struct mmu_pte *pte = NULL;
907 	__maybe_unused unsigned int level = CORE_MMU_BASE_TABLE_LEVEL;
908 	unsigned int idx = 0;
909 
910 	pgt = core_mmu_get_root_pgt_va(prtn, get_core_pos());
911 
912 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
913 	/* Traverse from root page table to level 2 page table. */
914 	while (level > CORE_MMU_VPN2_LEVEL) {
915 		pgt = core_mmu_get_next_level_pgt(pgt, 0);
916 		assert(pgt);
917 		level--;
918 	}
919 #endif
920 
921 	for (idx = 1 ; idx < RISCV_PTES_PER_PT; idx++) {
922 		pte = core_mmu_table_get_entry(pgt, idx);
923 		if (core_mmu_entry_is_invalid(pte)) {
924 			user_va_idx = idx;
925 			return;
926 		}
927 	}
928 	if (user_va_idx < 0)
929 		panic();
930 }
931 
932 static struct mmu_pte *
core_mmu_get_user_mapping_entry(struct mmu_partition * prtn)933 core_mmu_get_user_mapping_entry(struct mmu_partition *prtn)
934 {
935 	struct mmu_pgt *pgt = NULL;
936 
937 	assert(core_mmu_user_va_range_is_defined());
938 
939 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
940 	pgt = core_mmu_get_vpn2_ta_table(prtn, get_core_pos());
941 #else
942 	pgt = core_mmu_get_root_pgt_va(prtn, get_core_pos());
943 #endif
944 	return core_mmu_table_get_entry(pgt, user_va_idx);
945 }
946 
core_mmu_set_user_map(struct core_mmu_user_map * map)947 void core_mmu_set_user_map(struct core_mmu_user_map *map)
948 {
949 	unsigned long satp = 0;
950 	uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
951 	struct mmu_partition *prtn = core_mmu_get_prtn();
952 	struct mmu_pte *pte = NULL;
953 	unsigned long ptp = 0;
954 
955 	satp = read_satp();
956 	/* Clear ASID */
957 	satp &= ~SHIFT_U64(RISCV_SATP_ASID_MASK, RISCV_SATP_ASID_SHIFT);
958 	pte = core_mmu_get_user_mapping_entry(prtn);
959 	if (map && map->user_map) {
960 		ptp = core_mmu_ptp_create(pa_to_ppn((paddr_t)map->user_map));
961 		core_mmu_entry_set(pte, ptp);
962 		core_mmu_table_write_barrier();
963 		satp |= SHIFT_U64(map->asid, RISCV_SATP_ASID_SHIFT);
964 		write_satp(satp);
965 	} else {
966 		core_mmu_entry_set(pte, 0);
967 		core_mmu_table_write_barrier();
968 	}
969 
970 	tlbi_all();
971 	thread_unmask_exceptions(exceptions);
972 }
973 
core_mmu_user_va_range_is_defined(void)974 bool core_mmu_user_va_range_is_defined(void)
975 {
976 	return user_va_idx != -1;
977 }
978 
core_mmu_get_user_va_range(vaddr_t * base,size_t * size)979 void core_mmu_get_user_va_range(vaddr_t *base, size_t *size)
980 {
981 	assert(core_mmu_user_va_range_is_defined());
982 
983 #ifdef RV64
984 	if (base)
985 		*base = SHIFT_U64(user_va_idx, CORE_MMU_VPN2_SHIFT);
986 	if (size)
987 		*size =  BIT64(CORE_MMU_VPN2_SHIFT);
988 #else
989 	if (base)
990 		*base = SHIFT_U64(user_va_idx, CORE_MMU_VPN1_SHIFT);
991 	if (size)
992 		*size =  BIT64(CORE_MMU_VPN1_SHIFT);
993 #endif
994 }
995 
core_mmu_get_user_pgdir(struct core_mmu_table_info * pgd_info)996 void core_mmu_get_user_pgdir(struct core_mmu_table_info *pgd_info)
997 {
998 	vaddr_t va_range_base = 0;
999 	struct mmu_partition *prtn = core_mmu_get_prtn();
1000 	struct mmu_pgt *pgt = core_mmu_get_ta_pgt_va(prtn);
1001 
1002 	core_mmu_get_user_va_range(&va_range_base, NULL);
1003 	core_mmu_set_info_table(pgd_info, CORE_MMU_PGDIR_LEVEL + 1,
1004 				va_range_base, pgt);
1005 }
1006 
core_mmu_create_user_map(struct user_mode_ctx * uctx,struct core_mmu_user_map * map)1007 void core_mmu_create_user_map(struct user_mode_ctx *uctx,
1008 			      struct core_mmu_user_map *map)
1009 {
1010 	struct core_mmu_table_info tbl_info = { };
1011 
1012 	core_mmu_get_user_pgdir(&tbl_info);
1013 	memset(tbl_info.table, 0, RISCV_MMU_PGT_SIZE);
1014 	core_mmu_populate_user_map(&tbl_info, uctx);
1015 	map->user_map = virt_to_phys(tbl_info.table);
1016 	map->asid = uctx->vm_info.asid;
1017 }
1018 
core_mmu_get_user_map(struct core_mmu_user_map * map)1019 void core_mmu_get_user_map(struct core_mmu_user_map *map)
1020 {
1021 	struct mmu_partition *prtn = core_mmu_get_prtn();
1022 	struct mmu_pte *pte = core_mmu_get_user_mapping_entry(prtn);
1023 
1024 	map->user_map = pte_to_pa(pte);
1025 
1026 	if (map->user_map)
1027 		map->asid = (read_satp() >> RISCV_SATP_ASID_SHIFT) &
1028 			    RISCV_SATP_ASID_MASK;
1029 	else
1030 		map->asid = 0;
1031 }
1032 
core_mmu_user_mapping_is_active(void)1033 bool core_mmu_user_mapping_is_active(void)
1034 {
1035 	struct mmu_partition *prtn = core_mmu_get_prtn();
1036 	bool ret = false;
1037 	struct mmu_pte *pte = NULL;
1038 	uint32_t exceptions = 0;
1039 
1040 	exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
1041 	pte = core_mmu_get_user_mapping_entry(prtn);
1042 	ret = core_mmu_entry_is_valid(pte);
1043 	thread_unmask_exceptions(exceptions);
1044 
1045 	return ret;
1046 }
1047 
core_init_mmu_prtn(struct mmu_partition * prtn,struct memory_map * mem_map)1048 void core_init_mmu_prtn(struct mmu_partition *prtn, struct memory_map *mem_map)
1049 {
1050 	core_init_mmu_prtn_tee(prtn, mem_map);
1051 	core_init_mmu_prtn_ta(prtn);
1052 }
1053 
core_init_mmu(struct memory_map * mem_map)1054 void core_init_mmu(struct memory_map *mem_map)
1055 {
1056 	struct mmu_partition *prtn = &default_partition;
1057 	size_t n = 0;
1058 
1059 	if (IS_ENABLED(CFG_DYN_CONFIG)) {
1060 		prtn->root_pgt = boot_mem_alloc(RISCV_MMU_PGT_SIZE *
1061 						CFG_TEE_CORE_NB_CORE,
1062 						RISCV_MMU_PGT_SIZE);
1063 		boot_mem_add_reloc(&prtn->root_pgt);
1064 
1065 		prtn->user_pgts = boot_mem_alloc(RISCV_MMU_PGT_SIZE *
1066 						 CFG_NUM_THREADS,
1067 						 RISCV_MMU_PGT_SIZE);
1068 		boot_mem_add_reloc(&prtn->user_pgts);
1069 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
1070 		prtn->user_vpn2_table_va =
1071 			boot_mem_alloc(CFG_TEE_CORE_NB_CORE *
1072 				       sizeof(struct mmu_pgt *),
1073 				       alignof(sizeof(struct mmu_pgt *)));
1074 		boot_mem_add_reloc(&prtn->user_vpn2_table_va);
1075 #endif
1076 	}
1077 
1078 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
1079 	for (n = 0; n < CFG_TEE_CORE_NB_CORE; n++)
1080 		boot_mem_add_reloc(&prtn->user_vpn2_table_va[n]);
1081 #endif
1082 
1083 	/* Initialize default pagetables */
1084 	core_init_mmu_prtn_tee(prtn, mem_map);
1085 
1086 	for (n = 0; n < mem_map->count; n++) {
1087 		if (!core_mmu_va_is_valid(mem_map->map[n].va) ||
1088 		    !core_mmu_va_is_valid(mem_map->map[n].va +
1089 					  mem_map->map[n].size - 1))
1090 			panic("Invalid VA range in memory map");
1091 	}
1092 
1093 	set_user_va_idx(prtn);
1094 
1095 	core_init_mmu_prtn_ta(prtn);
1096 }
1097 
core_init_mmu_regs(struct core_mmu_config * cfg)1098 void core_init_mmu_regs(struct core_mmu_config *cfg)
1099 {
1100 	struct mmu_partition *p = core_mmu_get_prtn();
1101 	unsigned int n = 0;
1102 
1103 	for (n = 0; n < CFG_TEE_CORE_NB_CORE; n++)
1104 		cfg->satp[n] = core_mmu_pgt_to_satp(p->asid, p->root_pgt + n);
1105 }
1106 
core_mmu_get_fault_type(uint32_t fault_descr)1107 enum core_mmu_fault core_mmu_get_fault_type(uint32_t fault_descr)
1108 {
1109 	switch (fault_descr) {
1110 	case CAUSE_MISALIGNED_FETCH:
1111 	case CAUSE_MISALIGNED_LOAD:
1112 	case CAUSE_MISALIGNED_STORE:
1113 		return CORE_MMU_FAULT_ALIGNMENT;
1114 	case CAUSE_STORE_ACCESS:
1115 	case CAUSE_LOAD_ACCESS:
1116 		return CORE_MMU_FAULT_ACCESS_BIT;
1117 	case CAUSE_FETCH_PAGE_FAULT:
1118 	case CAUSE_LOAD_PAGE_FAULT:
1119 	case CAUSE_STORE_PAGE_FAULT:
1120 	case CAUSE_FETCH_GUEST_PAGE_FAULT:
1121 	case CAUSE_LOAD_GUEST_PAGE_FAULT:
1122 	case CAUSE_STORE_GUEST_PAGE_FAULT:
1123 		return CORE_MMU_FAULT_TRANSLATION;
1124 	case CAUSE_BREAKPOINT:
1125 		return CORE_MMU_FAULT_DEBUG_EVENT;
1126 	default:
1127 		return CORE_MMU_FAULT_OTHER;
1128 	}
1129 }
1130