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 prtn->pgts_used++;
339 DMSG("pgts used %u", prtn->pgts_used);
340 } else {
341 if (prtn->pgts_used >= RISCV_MMU_MAX_PGTS) {
342 debug_print("%u pgts exhausted", RISCV_MMU_MAX_PGTS);
343 return NULL;
344 }
345
346 pgt = &prtn->pool_pgts[prtn->pgts_used++];
347
348 memset(pgt, 0, RISCV_MMU_PGT_SIZE);
349
350 DMSG("pgts used %u / %u", prtn->pgts_used,
351 RISCV_MMU_MAX_PGTS);
352 }
353
354 return pgt;
355 }
356
357 /*
358 * Given an entry that points to a table.
359 * If mmu is disabled, returns the pa of pointed table.
360 * If mmu is enabled, returns the va of pointed table.
361 * returns NULL otherwise.
362 */
core_mmu_xlat_table_entry_pa2va(struct mmu_pte * pte,struct mmu_pgt * pgt)363 static struct mmu_pgt *core_mmu_xlat_table_entry_pa2va(struct mmu_pte *pte,
364 struct mmu_pgt *pgt)
365 {
366 struct mmu_pgt *va = NULL;
367
368 if (core_mmu_entry_is_invalid(pte) ||
369 core_mmu_entry_is_leaf(pte))
370 return NULL;
371
372 if (!cpu_mmu_enabled())
373 return (struct mmu_pgt *)pte_to_pa(pte);
374
375 va = phys_to_virt(pte_to_pa(pte), MEM_AREA_TEE_RAM_RW_DATA,
376 sizeof(*pgt));
377 if (!va)
378 va = phys_to_virt(pte_to_pa(pte), MEM_AREA_SEC_RAM_OVERALL,
379 sizeof(*pgt));
380
381 return va;
382 }
383
384 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
core_mmu_get_vpn2_ta_table(struct mmu_partition * prtn,size_t core_pos)385 static struct mmu_pgt *core_mmu_get_vpn2_ta_table(struct mmu_partition *prtn,
386 size_t core_pos)
387 {
388 assert(core_pos < CFG_TEE_CORE_NB_CORE);
389 return prtn->user_vpn2_table_va[core_pos];
390 }
391
core_mmu_set_vpn2_ta_table(struct mmu_partition * prtn,size_t core_pos,struct mmu_pgt * pgt)392 static void core_mmu_set_vpn2_ta_table(struct mmu_partition *prtn,
393 size_t core_pos, struct mmu_pgt *pgt)
394 {
395 assert(core_pos < CFG_TEE_CORE_NB_CORE);
396 prtn->user_vpn2_table_va[core_pos] = pgt;
397 }
398
399 /*
400 * Giving a page table, return the base address of next level page table from
401 * given index of entry in it.
402 */
core_mmu_get_next_level_pgt(struct mmu_pgt * pgt,unsigned int idx)403 static struct mmu_pgt *core_mmu_get_next_level_pgt(struct mmu_pgt *pgt,
404 unsigned int idx)
405 {
406 struct mmu_pte *pte = NULL;
407
408 pte = core_mmu_table_get_entry(pgt, idx);
409 assert(core_mmu_entry_is_branch(pte));
410
411 return core_mmu_xlat_table_entry_pa2va(pte, pgt);
412 }
413 #endif
414
415 /*
416 * For a table entry that points to a table - allocate and copy to
417 * a new pointed table. This is done for the requested entry,
418 * without going deeper into the pointed table entries.
419 *
420 * A success is returned for non-table entries, as nothing to do there.
421 */
422 __maybe_unused
core_mmu_entry_copy(struct core_mmu_table_info * tbl_info,unsigned int idx)423 static bool core_mmu_entry_copy(struct core_mmu_table_info *tbl_info,
424 unsigned int idx)
425 {
426 struct mmu_pgt *orig_pgt = NULL;
427 struct mmu_pgt *new_pgt = NULL;
428 struct mmu_pte *pte = NULL;
429 struct mmu_partition *prtn = NULL;
430 unsigned long ptp = 0;
431
432 prtn = &default_partition;
433 assert(prtn);
434
435 if (idx >= tbl_info->num_entries)
436 return false;
437
438 orig_pgt = tbl_info->table;
439 pte = core_mmu_table_get_entry(orig_pgt, idx);
440
441 /* Nothing to do for non-table entries */
442 if (core_mmu_entry_is_leaf(pte) || tbl_info->level >= RISCV_PGLEVELS)
443 return true;
444
445 new_pgt = core_mmu_pgt_alloc(prtn);
446 if (!new_pgt)
447 return false;
448
449 orig_pgt = core_mmu_xlat_table_entry_pa2va(pte, orig_pgt);
450 if (!orig_pgt)
451 return false;
452
453 /* Copy original table content to new table */
454 memcpy(new_pgt, orig_pgt, sizeof(struct mmu_pgt));
455
456 /* Point to the new table */
457 ptp = core_mmu_ptp_create(pa_to_ppn((paddr_t)new_pgt));
458 core_mmu_entry_set(pte, ptp);
459
460 return true;
461 }
462
463 /*
464 * Setup entries inside level 4, 3, and 2 page tables for TAs memory mapping
465 *
466 * Sv39 - user_va_idx is already in level 2 page table, so nothing to do.
467 * Sv48 - we need to allocate entry 0 of level 3 page table, and let it point to
468 * level 2 page table.
469 * Sv57 - we need to allocate entry 0 of level 4 page table, and let it point to
470 * level 3 page table. We need to further allocate entry 0 of the level 3
471 * page table, and let it point to level 2 page table.
472 */
core_init_mmu_prtn_ta_core(struct mmu_partition * prtn __maybe_unused,unsigned int core __maybe_unused)473 static void core_init_mmu_prtn_ta_core(struct mmu_partition *prtn
474 __maybe_unused,
475 unsigned int core __maybe_unused)
476 {
477 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
478 unsigned int level = CORE_MMU_BASE_TABLE_LEVEL;
479 struct core_mmu_table_info tbl_info = { };
480 struct mmu_pgt *pgt = NULL;
481 struct mmu_pte *pte = NULL;
482
483 assert(user_va_idx != -1);
484
485 while (level > CORE_MMU_VPN2_LEVEL) {
486 if (level == CORE_MMU_BASE_TABLE_LEVEL) {
487 /* First level: get root page table */
488 pgt = core_mmu_get_root_pgt_va(prtn, core);
489 } else {
490 /* Other levels: get table from PTE of previous level */
491 pgt = core_mmu_get_next_level_pgt(pgt, 0);
492 }
493
494 core_mmu_set_info_table(&tbl_info, level, 0, pgt);
495
496 /*
497 * If this isn't the core that created the initial tables
498 * mappings, then the table must be copied,
499 * as it will hold pointer to the next mapping table
500 * that changes per core.
501 */
502 if (core != get_core_pos()) {
503 if (!core_mmu_entry_copy(&tbl_info, 0))
504 panic();
505 }
506
507 if (!core_mmu_entry_to_finer_grained(&tbl_info, 0, true))
508 panic();
509
510 /* Now index 0 of the table should be pointer to next level. */
511 pte = core_mmu_table_get_entry(pgt, 0);
512 assert(core_mmu_entry_is_branch(pte));
513
514 level--;
515 }
516
517 pgt = core_mmu_xlat_table_entry_pa2va(pte, pgt);
518 assert(pgt);
519 core_mmu_set_vpn2_ta_table(prtn, core, pgt);
520 #endif
521 }
522
core_init_mmu_prtn_ta(struct mmu_partition * prtn)523 static void core_init_mmu_prtn_ta(struct mmu_partition *prtn)
524 {
525 unsigned int core = 0;
526
527 assert(core_mmu_user_va_range_is_defined());
528
529 memset(prtn->user_pgts, 0, CFG_NUM_THREADS * RISCV_MMU_PGT_SIZE);
530 for (core = 0; core < CFG_TEE_CORE_NB_CORE; core++)
531 core_init_mmu_prtn_ta_core(prtn, core);
532 }
533
core_init_mmu_prtn_tee(struct mmu_partition * prtn,struct memory_map * mem_map)534 static void core_init_mmu_prtn_tee(struct mmu_partition *prtn,
535 struct memory_map *mem_map)
536 {
537 size_t n = 0;
538
539 assert(prtn && mem_map);
540
541 for (n = 0; n < mem_map->count; n++) {
542 struct tee_mmap_region *mm = mem_map->map + n;
543
544 debug_print(" %010" PRIxVA " %010" PRIxPA " %10zx %x",
545 mm->va, mm->pa, mm->size, mm->attr);
546
547 if (!IS_PAGE_ALIGNED(mm->pa) || !IS_PAGE_ALIGNED(mm->size))
548 panic("unaligned region");
549 }
550
551 /* Clear table before using it. */
552 memset(prtn->root_pgt, 0, RISCV_MMU_PGT_SIZE * CFG_TEE_CORE_NB_CORE);
553
554 for (n = 0; n < mem_map->count; n++)
555 core_mmu_map_region(prtn, mem_map->map + n);
556
557 /*
558 * Primary mapping table is ready at index `get_core_pos()`
559 * whose value may not be ZERO. Take this index as copy source.
560 */
561 for (n = 0; n < CFG_TEE_CORE_NB_CORE; n++) {
562 if (n == get_core_pos())
563 continue;
564
565 memcpy(core_mmu_get_root_pgt_va(prtn, n),
566 core_mmu_get_root_pgt_va(prtn, get_core_pos()),
567 RISCV_MMU_PGT_SIZE);
568 }
569 }
570
tlbi_va_range(vaddr_t va,size_t len,size_t granule)571 void tlbi_va_range(vaddr_t va, size_t len,
572 size_t granule)
573 {
574 assert(granule == CORE_MMU_PGDIR_SIZE || granule == SMALL_PAGE_SIZE);
575 assert(!(va & (granule - 1)) && !(len & (granule - 1)));
576
577 /*
578 * Ensure operations are completed or observed before proceeding
579 * with TLB invalidation.
580 */
581 mb();
582 while (len) {
583 tlbi_va_allasid(va);
584 len -= granule;
585 va += granule;
586 }
587 /*
588 * After invalidating TLB entries, a memory barrier is required
589 * to ensure that the page table entries become visible to other harts
590 * before subsequent memory accesses are performed.
591 */
592 mb();
593 }
594
tlbi_va_range_asid(vaddr_t va,size_t len,size_t granule,uint32_t asid)595 void tlbi_va_range_asid(vaddr_t va, size_t len,
596 size_t granule, uint32_t asid)
597 {
598 assert(granule == CORE_MMU_PGDIR_SIZE || granule == SMALL_PAGE_SIZE);
599 assert(!(va & (granule - 1)) && !(len & (granule - 1)));
600
601 /*
602 * A memory barrier is necessary here to ensure the consistency
603 * and correctness of memory accesses.
604 */
605 mb();
606 while (len) {
607 tlbi_va_asid(va, asid);
608 len -= granule;
609 va += granule;
610 }
611 /* Enforce ordering of memory operations and ensure that all
612 * preceding memory operations are completed after TLB
613 * invalidation.
614 */
615 mb();
616 }
617
cache_op_inner(enum cache_op op,void * va,size_t len)618 TEE_Result cache_op_inner(enum cache_op op, void *va, size_t len)
619 {
620 switch (op) {
621 case DCACHE_CLEAN:
622 dcache_op_all(DCACHE_OP_CLEAN);
623 break;
624 case DCACHE_AREA_CLEAN:
625 dcache_clean_range(va, len);
626 break;
627 case DCACHE_INVALIDATE:
628 dcache_op_all(DCACHE_OP_INV);
629 break;
630 case DCACHE_AREA_INVALIDATE:
631 dcache_inv_range(va, len);
632 break;
633 case ICACHE_INVALIDATE:
634 icache_inv_all();
635 break;
636 case ICACHE_AREA_INVALIDATE:
637 icache_inv_range(va, len);
638 break;
639 case DCACHE_CLEAN_INV:
640 dcache_op_all(DCACHE_OP_CLEAN_INV);
641 break;
642 case DCACHE_AREA_CLEAN_INV:
643 dcache_cleaninv_range(va, len);
644 break;
645 default:
646 return TEE_ERROR_NOT_IMPLEMENTED;
647 }
648 return TEE_SUCCESS;
649 }
650
asid_alloc(void)651 unsigned int asid_alloc(void)
652 {
653 uint32_t exceptions = cpu_spin_lock_xsave(&g_asid_spinlock);
654 unsigned int r = 0;
655 int i = 0;
656
657 bit_ffc(g_asid, (int)RISCV_SATP_ASID_WIDTH, &i);
658 if (i == -1) {
659 r = 0;
660 } else {
661 bit_set(g_asid, i);
662 r = i + 1;
663 }
664
665 cpu_spin_unlock_xrestore(&g_asid_spinlock, exceptions);
666
667 return r;
668 }
669
asid_free(unsigned int asid)670 void asid_free(unsigned int asid)
671 {
672 uint32_t exceptions = cpu_spin_lock_xsave(&g_asid_spinlock);
673
674 if (asid) {
675 unsigned int i = asid - 1;
676
677 assert(i < RISCV_SATP_ASID_WIDTH && bit_test(g_asid, i));
678 bit_clear(g_asid, i);
679 }
680
681 cpu_spin_unlock_xrestore(&g_asid_spinlock, exceptions);
682 }
683
arch_va2pa_helper(void * va,paddr_t * pa)684 bool arch_va2pa_helper(void *va, paddr_t *pa)
685 {
686 uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
687 vaddr_t vaddr = (vaddr_t)va;
688 struct mmu_pgt *pgt = NULL;
689 struct mmu_pte *pte = NULL;
690 int level = 0;
691 unsigned int idx = 0;
692 struct mmu_partition *prtn = core_mmu_get_prtn();
693 vaddr_t offset_mask = 0;
694
695 assert(pa);
696
697 pgt = core_mmu_get_root_pgt_va(prtn, get_core_pos());
698
699 for (level = CORE_MMU_BASE_TABLE_LEVEL; level >= 0; level--) {
700 idx = core_mmu_pgt_idx(vaddr, level);
701 pte = core_mmu_table_get_entry(pgt, idx);
702
703 if (core_mmu_entry_is_invalid(pte)) {
704 thread_unmask_exceptions(exceptions);
705 return false;
706 } else if (core_mmu_entry_is_leaf(pte)) {
707 offset_mask = CORE_MMU_PAGE_OFFSET_MASK(level);
708 *pa = pte_to_pa(pte) | (vaddr & offset_mask);
709 thread_unmask_exceptions(exceptions);
710 return true;
711 }
712
713 pgt = core_mmu_xlat_table_entry_pa2va(pte, pgt);
714 }
715
716 thread_unmask_exceptions(exceptions);
717 return false;
718 }
719
arch_aslr_base_addr(vaddr_t start_addr,uint64_t seed,unsigned int iteration_count)720 vaddr_t arch_aslr_base_addr(vaddr_t start_addr, uint64_t seed,
721 unsigned int iteration_count)
722 {
723 const unsigned int va_width = core_mmu_get_va_width();
724 const vaddr_t va_mask = GENMASK_64(63, SMALL_PAGE_SHIFT);
725 const vaddr_t va_width_msb = BIT64(va_width - 1);
726 const vaddr_t va_extended_mask = GENMASK_64(63, va_width);
727 vaddr_t base_addr = start_addr + seed;
728
729 if (iteration_count)
730 base_addr ^= BIT64(va_width - iteration_count);
731
732 /*
733 * If the MSB is set, map the base address to the top
734 * half of the virtual address space by extending 1s
735 * to 64-bit; otherwise, map it to the bottom half.
736 */
737 if (base_addr & va_width_msb)
738 base_addr |= va_extended_mask;
739 else
740 base_addr &= ~va_extended_mask;
741
742 return base_addr & va_mask;
743 }
744
cpu_mmu_enabled(void)745 bool cpu_mmu_enabled(void)
746 {
747 return read_satp();
748 }
749
core_mmu_find_table(struct mmu_partition * prtn,vaddr_t va,unsigned int max_level,struct core_mmu_table_info * tbl_info)750 bool core_mmu_find_table(struct mmu_partition *prtn, vaddr_t va,
751 unsigned int max_level,
752 struct core_mmu_table_info *tbl_info)
753 {
754 uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
755 struct mmu_pgt *pgt = NULL;
756 struct mmu_pte *pte = NULL;
757 unsigned int level = CORE_MMU_BASE_TABLE_LEVEL;
758 unsigned int idx = 0;
759 unsigned int deepest_level = max_level;
760 vaddr_t va_base = 0;
761 bool ret = false;
762
763 if (max_level == UINT_MAX)
764 deepest_level = 0;
765
766 if (!prtn)
767 prtn = core_mmu_get_prtn();
768
769 pgt = core_mmu_get_root_pgt_va(prtn, get_core_pos());
770
771 while (true) {
772 idx = core_mmu_pgt_idx(va - va_base, level);
773 pte = core_mmu_table_get_entry(pgt, idx);
774 if (level == deepest_level || level == 0 ||
775 core_mmu_entry_is_invalid(pte) ||
776 core_mmu_entry_is_leaf(pte)) {
777 core_mmu_set_info_table(tbl_info, level, va_base, pgt);
778 ret = true;
779 goto out;
780 }
781 pgt = core_mmu_xlat_table_entry_pa2va(pte, pgt);
782 if (!pgt)
783 goto out;
784 va_base += core_mmu_pgt_get_va_base(level, idx);
785 level--;
786 }
787 out:
788 thread_unmask_exceptions(exceptions);
789 return ret;
790 }
791
core_mmu_entry_to_finer_grained(struct core_mmu_table_info * tbl_info,unsigned int idx,bool secure __unused)792 bool core_mmu_entry_to_finer_grained(struct core_mmu_table_info *tbl_info,
793 unsigned int idx, bool secure __unused)
794 {
795 struct mmu_pgt *pgt = NULL;
796 struct mmu_pte *pte = NULL;
797 struct mmu_partition *prtn = core_mmu_get_prtn();
798 unsigned long ptp = 0;
799 paddr_t pgt_pa = 0;
800
801 if (!core_mmu_level_in_range(tbl_info->level))
802 return false;
803
804 pgt = tbl_info->table;
805 pte = core_mmu_table_get_entry(pgt, idx);
806
807 if (core_mmu_entry_is_invalid(pte)) {
808 pgt = core_mmu_pgt_alloc(prtn);
809 if (!pgt)
810 return false;
811
812 if (cpu_mmu_enabled())
813 pgt_pa = virt_to_phys(pgt);
814 else
815 pgt_pa = (paddr_t)pgt;
816
817 ptp = core_mmu_ptp_create(pa_to_ppn(pgt_pa));
818 core_mmu_entry_set(pte, ptp);
819 }
820
821 return true;
822 }
823
core_mmu_set_info_table(struct core_mmu_table_info * tbl_info,unsigned int level,vaddr_t va_base,void * table)824 void core_mmu_set_info_table(struct core_mmu_table_info *tbl_info,
825 unsigned int level, vaddr_t va_base, void *table)
826 {
827 tbl_info->level = level;
828 tbl_info->next_level = level - 1;
829 tbl_info->table = table;
830 tbl_info->va_base = va_base;
831 tbl_info->shift = CORE_MMU_SHIFT_OF_LEVEL(level);
832 assert(level < RISCV_PGLEVELS);
833 tbl_info->num_entries = RISCV_PTES_PER_PT;
834 }
835
core_mmu_get_entry_primitive(const void * table,size_t level,size_t idx,paddr_t * pa,uint32_t * attr)836 void core_mmu_get_entry_primitive(const void *table, size_t level,
837 size_t idx, paddr_t *pa, uint32_t *attr)
838 {
839 struct mmu_pgt *pgt = (struct mmu_pgt *)table;
840 struct mmu_pte *pte = core_mmu_table_get_entry(pgt, idx);
841
842 if (core_mmu_entry_is_valid(pte)) {
843 if (pa)
844 *pa = pte_to_pa(pte);
845 if (attr)
846 *attr = pte_to_mattr(level, pte);
847 } else {
848 if (pa)
849 *pa = 0;
850 if (attr)
851 *attr = 0;
852 }
853 }
854
core_mmu_set_entry_primitive(void * table,size_t level,size_t idx,paddr_t pa,uint32_t attr)855 void core_mmu_set_entry_primitive(void *table, size_t level, size_t idx,
856 paddr_t pa, uint32_t attr)
857 {
858 struct mmu_pgt *pgt = (struct mmu_pgt *)table;
859 struct mmu_pte *pte = core_mmu_table_get_entry(pgt, idx);
860 uint8_t pte_bits = mattr_to_pte_bits(level, attr);
861
862 core_mmu_entry_set(pte, core_mmu_pte_create(pa_to_ppn(pa), pte_bits));
863 }
864
865 /*
866 * Due to OP-TEE design limitation, TAs page table should be an entry
867 * inside a level 2 (VPN[2]) page table.
868 *
869 * Available options are only these:
870 * For Sv57:
871 * - base level 4 entry 0 - [0GB, 256TB[
872 * - level 3 entry 0 - [0GB, 512GB[
873 * - level 2 entry 0 - [0GB, 1GB[
874 * - level 2 entry 1 - [1GB, 2GB[ <----
875 * - level 2 entry 2 - [2GB, 3GB[ <----
876 * - level 2 entry 3 - [3GB, 4GB[ <----
877 * - level 2 entry 4 - [4GB, 5GB[
878 * - ...
879 * - ...
880 * - ...
881 *
882 * For Sv48:
883 * - base level 3 entry 0 - [0GB, 512GB[
884 * - level 2 entry 0 - [0GB, 1GB[
885 * - level 2 entry 1 - [1GB, 2GB[ <----
886 * - level 2 entry 2 - [2GB, 3GB[ <----
887 * - level 2 entry 3 - [3GB, 4GB[ <----
888 * - level 2 entry 4 - [4GB, 5GB[
889 * - ...
890 * - ...
891 *
892 * For Sv39:
893 * - base level 2 entry 0 - [0GB, 1GB[
894 * - base level 2 entry 1 - [1GB, 2GB[ <----
895 * - base level 2 entry 2 - [2GB, 3GB[ <----
896 * - base level 2 entry 3 - [3GB, 4GB[ <----
897 * - base level 2 entry 4 - [4GB, 5GB[
898 * - ...
899 */
set_user_va_idx(struct mmu_partition * prtn)900 static void set_user_va_idx(struct mmu_partition *prtn)
901 {
902 struct mmu_pgt *pgt = NULL;
903 __maybe_unused struct mmu_pte *pte = NULL;
904 __maybe_unused unsigned int level = CORE_MMU_BASE_TABLE_LEVEL;
905 unsigned int idx = 0;
906
907 pgt = core_mmu_get_root_pgt_va(prtn, get_core_pos());
908
909 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
910 /* Traverse from root page table to level 2 page table. */
911 while (level > CORE_MMU_VPN2_LEVEL) {
912 pgt = core_mmu_get_next_level_pgt(pgt, 0);
913 assert(pgt);
914 level--;
915 }
916 #endif
917
918 for (idx = 1 ; idx < RISCV_PTES_PER_PT; idx++) {
919 pte = core_mmu_table_get_entry(pgt, idx);
920 if (core_mmu_entry_is_invalid(pte)) {
921 user_va_idx = idx;
922 return;
923 }
924 }
925 if (user_va_idx < 0)
926 panic();
927 }
928
929 static struct mmu_pte *
core_mmu_get_user_mapping_entry(struct mmu_partition * prtn)930 core_mmu_get_user_mapping_entry(struct mmu_partition *prtn)
931 {
932 struct mmu_pgt *pgt = NULL;
933
934 assert(core_mmu_user_va_range_is_defined());
935
936 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
937 pgt = core_mmu_get_vpn2_ta_table(prtn, get_core_pos());
938 #else
939 pgt = core_mmu_get_root_pgt_va(prtn, get_core_pos());
940 #endif
941 return core_mmu_table_get_entry(pgt, user_va_idx);
942 }
943
core_mmu_set_user_map(struct core_mmu_user_map * map)944 void core_mmu_set_user_map(struct core_mmu_user_map *map)
945 {
946 unsigned long satp = 0;
947 uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
948 struct mmu_partition *prtn = core_mmu_get_prtn();
949 struct mmu_pte *pte = NULL;
950 unsigned long ptp = 0;
951
952 satp = read_satp();
953 /* Clear ASID */
954 satp &= ~SHIFT_U64(RISCV_SATP_ASID_MASK, RISCV_SATP_ASID_SHIFT);
955 pte = core_mmu_get_user_mapping_entry(prtn);
956 if (map && map->user_map) {
957 ptp = core_mmu_ptp_create(pa_to_ppn((paddr_t)map->user_map));
958 core_mmu_entry_set(pte, ptp);
959 core_mmu_table_write_barrier();
960 satp |= SHIFT_U64(map->asid, RISCV_SATP_ASID_SHIFT);
961 write_satp(satp);
962 } else {
963 core_mmu_entry_set(pte, 0);
964 core_mmu_table_write_barrier();
965 }
966
967 tlbi_all();
968 thread_unmask_exceptions(exceptions);
969 }
970
core_mmu_user_va_range_is_defined(void)971 bool core_mmu_user_va_range_is_defined(void)
972 {
973 return user_va_idx != -1;
974 }
975
core_mmu_get_user_va_range(vaddr_t * base,size_t * size)976 void core_mmu_get_user_va_range(vaddr_t *base, size_t *size)
977 {
978 assert(core_mmu_user_va_range_is_defined());
979
980 #ifdef RV64
981 if (base)
982 *base = SHIFT_U64(user_va_idx, CORE_MMU_VPN2_SHIFT);
983 if (size)
984 *size = BIT64(CORE_MMU_VPN2_SHIFT);
985 #else
986 if (base)
987 *base = SHIFT_U64(user_va_idx, CORE_MMU_VPN1_SHIFT);
988 if (size)
989 *size = BIT64(CORE_MMU_VPN1_SHIFT);
990 #endif
991 }
992
core_mmu_get_user_pgdir(struct core_mmu_table_info * pgd_info)993 void core_mmu_get_user_pgdir(struct core_mmu_table_info *pgd_info)
994 {
995 vaddr_t va_range_base = 0;
996 struct mmu_partition *prtn = core_mmu_get_prtn();
997 struct mmu_pgt *pgt = core_mmu_get_ta_pgt_va(prtn);
998
999 core_mmu_get_user_va_range(&va_range_base, NULL);
1000 core_mmu_set_info_table(pgd_info, CORE_MMU_PGDIR_LEVEL + 1,
1001 va_range_base, pgt);
1002 }
1003
core_mmu_create_user_map(struct user_mode_ctx * uctx,struct core_mmu_user_map * map)1004 void core_mmu_create_user_map(struct user_mode_ctx *uctx,
1005 struct core_mmu_user_map *map)
1006 {
1007 struct core_mmu_table_info tbl_info = { };
1008
1009 core_mmu_get_user_pgdir(&tbl_info);
1010 memset(tbl_info.table, 0, RISCV_MMU_PGT_SIZE);
1011 core_mmu_populate_user_map(&tbl_info, uctx);
1012 map->user_map = virt_to_phys(tbl_info.table);
1013 map->asid = uctx->vm_info.asid;
1014 }
1015
core_mmu_get_user_map(struct core_mmu_user_map * map)1016 void core_mmu_get_user_map(struct core_mmu_user_map *map)
1017 {
1018 struct mmu_partition *prtn = core_mmu_get_prtn();
1019 struct mmu_pte *pte = core_mmu_get_user_mapping_entry(prtn);
1020
1021 map->user_map = pte_to_pa(pte);
1022
1023 if (map->user_map)
1024 map->asid = (read_satp() >> RISCV_SATP_ASID_SHIFT) &
1025 RISCV_SATP_ASID_MASK;
1026 else
1027 map->asid = 0;
1028 }
1029
core_mmu_user_mapping_is_active(void)1030 bool core_mmu_user_mapping_is_active(void)
1031 {
1032 struct mmu_partition *prtn = core_mmu_get_prtn();
1033 bool ret = false;
1034 struct mmu_pte *pte = NULL;
1035 uint32_t exceptions = 0;
1036
1037 exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
1038 pte = core_mmu_get_user_mapping_entry(prtn);
1039 ret = core_mmu_entry_is_valid(pte);
1040 thread_unmask_exceptions(exceptions);
1041
1042 return ret;
1043 }
1044
core_init_mmu_prtn(struct mmu_partition * prtn,struct memory_map * mem_map)1045 void core_init_mmu_prtn(struct mmu_partition *prtn, struct memory_map *mem_map)
1046 {
1047 core_init_mmu_prtn_tee(prtn, mem_map);
1048 core_init_mmu_prtn_ta(prtn);
1049 }
1050
core_init_mmu(struct memory_map * mem_map)1051 void core_init_mmu(struct memory_map *mem_map)
1052 {
1053 struct mmu_partition *prtn = &default_partition;
1054 size_t n = 0;
1055
1056 if (IS_ENABLED(CFG_DYN_CONFIG)) {
1057 prtn->root_pgt = boot_mem_alloc(RISCV_MMU_PGT_SIZE *
1058 CFG_TEE_CORE_NB_CORE,
1059 RISCV_MMU_PGT_SIZE);
1060 boot_mem_add_reloc(&prtn->root_pgt);
1061
1062 prtn->user_pgts = boot_mem_alloc(RISCV_MMU_PGT_SIZE *
1063 CFG_NUM_THREADS,
1064 RISCV_MMU_PGT_SIZE);
1065 boot_mem_add_reloc(&prtn->user_pgts);
1066 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
1067 prtn->user_vpn2_table_va =
1068 boot_mem_alloc(CFG_TEE_CORE_NB_CORE *
1069 sizeof(struct mmu_pgt *),
1070 alignof(sizeof(struct mmu_pgt *)));
1071 boot_mem_add_reloc(&prtn->user_vpn2_table_va);
1072 #endif
1073 }
1074
1075 #if (RISCV_SATP_MODE >= SATP_MODE_SV48)
1076 for (n = 0; n < CFG_TEE_CORE_NB_CORE; n++)
1077 boot_mem_add_reloc(&prtn->user_vpn2_table_va[n]);
1078 #endif
1079
1080 /* Initialize default pagetables */
1081 core_init_mmu_prtn_tee(prtn, mem_map);
1082
1083 for (n = 0; n < mem_map->count; n++) {
1084 if (!core_mmu_va_is_valid(mem_map->map[n].va) ||
1085 !core_mmu_va_is_valid(mem_map->map[n].va +
1086 mem_map->map[n].size - 1))
1087 panic("Invalid VA range in memory map");
1088 }
1089
1090 set_user_va_idx(prtn);
1091
1092 core_init_mmu_prtn_ta(prtn);
1093 }
1094
core_init_mmu_regs(struct core_mmu_config * cfg)1095 void core_init_mmu_regs(struct core_mmu_config *cfg)
1096 {
1097 struct mmu_partition *p = core_mmu_get_prtn();
1098 unsigned int n = 0;
1099
1100 for (n = 0; n < CFG_TEE_CORE_NB_CORE; n++)
1101 cfg->satp[n] = core_mmu_pgt_to_satp(p->asid, p->root_pgt + n);
1102 }
1103
core_mmu_get_fault_type(uint32_t fault_descr)1104 enum core_mmu_fault core_mmu_get_fault_type(uint32_t fault_descr)
1105 {
1106 switch (fault_descr) {
1107 case CAUSE_MISALIGNED_FETCH:
1108 case CAUSE_MISALIGNED_LOAD:
1109 case CAUSE_MISALIGNED_STORE:
1110 return CORE_MMU_FAULT_ALIGNMENT;
1111 case CAUSE_STORE_ACCESS:
1112 case CAUSE_LOAD_ACCESS:
1113 return CORE_MMU_FAULT_ACCESS_BIT;
1114 case CAUSE_FETCH_PAGE_FAULT:
1115 case CAUSE_LOAD_PAGE_FAULT:
1116 case CAUSE_STORE_PAGE_FAULT:
1117 case CAUSE_FETCH_GUEST_PAGE_FAULT:
1118 case CAUSE_LOAD_GUEST_PAGE_FAULT:
1119 case CAUSE_STORE_GUEST_PAGE_FAULT:
1120 return CORE_MMU_FAULT_TRANSLATION;
1121 case CAUSE_BREAKPOINT:
1122 return CORE_MMU_FAULT_DEBUG_EVENT;
1123 default:
1124 return CORE_MMU_FAULT_OTHER;
1125 }
1126 }
1127