1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2016, Linaro Limited 4 * Copyright (c) 2014, STMicroelectronics International N.V. 5 */ 6 7 #include <arm.h> 8 #include <assert.h> 9 #include <crypto/crypto.h> 10 #include <crypto/internal_aes-gcm.h> 11 #include <io.h> 12 #include <keep.h> 13 #include <kernel/abort.h> 14 #include <kernel/asan.h> 15 #include <kernel/panic.h> 16 #include <kernel/spinlock.h> 17 #include <kernel/tee_misc.h> 18 #include <kernel/tee_ta_manager.h> 19 #include <kernel/thread.h> 20 #include <kernel/tlb_helpers.h> 21 #include <mm/core_memprot.h> 22 #include <mm/tee_mm.h> 23 #include <mm/tee_pager.h> 24 #include <stdlib.h> 25 #include <sys/queue.h> 26 #include <tee_api_defines.h> 27 #include <trace.h> 28 #include <types_ext.h> 29 #include <utee_defines.h> 30 #include <util.h> 31 32 #define PAGER_AE_KEY_BITS 256 33 34 struct pager_aes_gcm_iv { 35 uint32_t iv[3]; 36 }; 37 38 #define PAGER_AES_GCM_TAG_LEN 16 39 40 struct pager_rw_pstate { 41 uint64_t iv; 42 uint8_t tag[PAGER_AES_GCM_TAG_LEN]; 43 }; 44 45 enum area_type { 46 AREA_TYPE_RO, 47 AREA_TYPE_RW, 48 AREA_TYPE_LOCK, 49 }; 50 51 struct tee_pager_area { 52 union { 53 const uint8_t *hashes; 54 struct pager_rw_pstate *rwp; 55 } u; 56 uint8_t *store; 57 enum area_type type; 58 uint32_t flags; 59 vaddr_t base; 60 size_t size; 61 struct pgt *pgt; 62 TAILQ_ENTRY(tee_pager_area) link; 63 }; 64 65 TAILQ_HEAD(tee_pager_area_head, tee_pager_area); 66 67 static struct tee_pager_area_head tee_pager_area_head = 68 TAILQ_HEAD_INITIALIZER(tee_pager_area_head); 69 70 #define INVALID_PGIDX UINT_MAX 71 72 /* 73 * struct tee_pager_pmem - Represents a physical page used for paging. 74 * 75 * @pgidx an index of the entry in area->ti. 76 * @va_alias Virtual address where the physical page always is aliased. 77 * Used during remapping of the page when the content need to 78 * be updated before it's available at the new location. 79 * @area a pointer to the pager area 80 */ 81 struct tee_pager_pmem { 82 unsigned pgidx; 83 void *va_alias; 84 struct tee_pager_area *area; 85 TAILQ_ENTRY(tee_pager_pmem) link; 86 }; 87 88 /* The list of physical pages. The first page in the list is the oldest */ 89 TAILQ_HEAD(tee_pager_pmem_head, tee_pager_pmem); 90 91 static struct tee_pager_pmem_head tee_pager_pmem_head = 92 TAILQ_HEAD_INITIALIZER(tee_pager_pmem_head); 93 94 static struct tee_pager_pmem_head tee_pager_lock_pmem_head = 95 TAILQ_HEAD_INITIALIZER(tee_pager_lock_pmem_head); 96 97 static struct internal_aes_gcm_key pager_ae_key; 98 99 /* number of pages hidden */ 100 #define TEE_PAGER_NHIDE (tee_pager_npages / 3) 101 102 /* Number of registered physical pages, used hiding pages. */ 103 static size_t tee_pager_npages; 104 105 #ifdef CFG_WITH_STATS 106 static struct tee_pager_stats pager_stats; 107 108 static inline void incr_ro_hits(void) 109 { 110 pager_stats.ro_hits++; 111 } 112 113 static inline void incr_rw_hits(void) 114 { 115 pager_stats.rw_hits++; 116 } 117 118 static inline void incr_hidden_hits(void) 119 { 120 pager_stats.hidden_hits++; 121 } 122 123 static inline void incr_zi_released(void) 124 { 125 pager_stats.zi_released++; 126 } 127 128 static inline void incr_npages_all(void) 129 { 130 pager_stats.npages_all++; 131 } 132 133 static inline void set_npages(void) 134 { 135 pager_stats.npages = tee_pager_npages; 136 } 137 138 void tee_pager_get_stats(struct tee_pager_stats *stats) 139 { 140 *stats = pager_stats; 141 142 pager_stats.hidden_hits = 0; 143 pager_stats.ro_hits = 0; 144 pager_stats.rw_hits = 0; 145 pager_stats.zi_released = 0; 146 } 147 148 #else /* CFG_WITH_STATS */ 149 static inline void incr_ro_hits(void) { } 150 static inline void incr_rw_hits(void) { } 151 static inline void incr_hidden_hits(void) { } 152 static inline void incr_zi_released(void) { } 153 static inline void incr_npages_all(void) { } 154 static inline void set_npages(void) { } 155 156 void tee_pager_get_stats(struct tee_pager_stats *stats) 157 { 158 memset(stats, 0, sizeof(struct tee_pager_stats)); 159 } 160 #endif /* CFG_WITH_STATS */ 161 162 #define TBL_NUM_ENTRIES (CORE_MMU_PGDIR_SIZE / SMALL_PAGE_SIZE) 163 #define TBL_LEVEL CORE_MMU_PGDIR_LEVEL 164 #define TBL_SHIFT SMALL_PAGE_SHIFT 165 166 #define EFFECTIVE_VA_SIZE \ 167 (ROUNDUP(TEE_RAM_VA_START + TEE_RAM_VA_SIZE, \ 168 CORE_MMU_PGDIR_SIZE) - \ 169 ROUNDDOWN(TEE_RAM_VA_START, CORE_MMU_PGDIR_SIZE)) 170 171 static struct pager_table { 172 struct pgt pgt; 173 struct core_mmu_table_info tbl_info; 174 } pager_tables[EFFECTIVE_VA_SIZE / CORE_MMU_PGDIR_SIZE]; 175 176 static unsigned pager_spinlock = SPINLOCK_UNLOCK; 177 178 /* Defines the range of the alias area */ 179 static tee_mm_entry_t *pager_alias_area; 180 /* 181 * Physical pages are added in a stack like fashion to the alias area, 182 * @pager_alias_next_free gives the address of next free entry if 183 * @pager_alias_next_free is != 0 184 */ 185 static uintptr_t pager_alias_next_free; 186 187 #ifdef CFG_TEE_CORE_DEBUG 188 #define pager_lock(ai) pager_lock_dldetect(__func__, __LINE__, ai) 189 190 static uint32_t pager_lock_dldetect(const char *func, const int line, 191 struct abort_info *ai) 192 { 193 uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); 194 unsigned int retries = 0; 195 unsigned int reminder = 0; 196 197 while (!cpu_spin_trylock(&pager_spinlock)) { 198 retries++; 199 if (!retries) { 200 /* wrapped, time to report */ 201 trace_printf(func, line, TRACE_ERROR, true, 202 "possible spinlock deadlock reminder %u", 203 reminder); 204 if (reminder < UINT_MAX) 205 reminder++; 206 if (ai) 207 abort_print(ai); 208 } 209 } 210 211 return exceptions; 212 } 213 #else 214 static uint32_t pager_lock(struct abort_info __unused *ai) 215 { 216 return cpu_spin_lock_xsave(&pager_spinlock); 217 } 218 #endif 219 220 static uint32_t pager_lock_check_stack(size_t stack_size) 221 { 222 if (stack_size) { 223 int8_t buf[stack_size]; 224 size_t n; 225 226 /* 227 * Make sure to touch all pages of the stack that we expect 228 * to use with this lock held. We need to take eventual 229 * page faults before the lock is taken or we'll deadlock 230 * the pager. The pages that are populated in this way will 231 * eventually be released at certain save transitions of 232 * the thread. 233 */ 234 for (n = 0; n < stack_size; n += SMALL_PAGE_SIZE) 235 io_write8((vaddr_t)buf + n, 1); 236 io_write8((vaddr_t)buf + stack_size - 1, 1); 237 } 238 239 return pager_lock(NULL); 240 } 241 242 static void pager_unlock(uint32_t exceptions) 243 { 244 cpu_spin_unlock_xrestore(&pager_spinlock, exceptions); 245 } 246 247 void *tee_pager_phys_to_virt(paddr_t pa) 248 { 249 struct core_mmu_table_info ti; 250 unsigned idx; 251 uint32_t a; 252 paddr_t p; 253 vaddr_t v; 254 size_t n; 255 256 /* 257 * Most addresses are mapped lineary, try that first if possible. 258 */ 259 if (!tee_pager_get_table_info(pa, &ti)) 260 return NULL; /* impossible pa */ 261 idx = core_mmu_va2idx(&ti, pa); 262 core_mmu_get_entry(&ti, idx, &p, &a); 263 if ((a & TEE_MATTR_VALID_BLOCK) && p == pa) 264 return (void *)core_mmu_idx2va(&ti, idx); 265 266 n = 0; 267 idx = core_mmu_va2idx(&pager_tables[n].tbl_info, TEE_RAM_VA_START); 268 while (true) { 269 while (idx < TBL_NUM_ENTRIES) { 270 v = core_mmu_idx2va(&pager_tables[n].tbl_info, idx); 271 if (v >= (TEE_RAM_VA_START + TEE_RAM_VA_SIZE)) 272 return NULL; 273 274 core_mmu_get_entry(&pager_tables[n].tbl_info, 275 idx, &p, &a); 276 if ((a & TEE_MATTR_VALID_BLOCK) && p == pa) 277 return (void *)v; 278 idx++; 279 } 280 281 n++; 282 if (n >= ARRAY_SIZE(pager_tables)) 283 return NULL; 284 idx = 0; 285 } 286 287 return NULL; 288 } 289 290 static struct pager_table *find_pager_table_may_fail(vaddr_t va) 291 { 292 size_t n; 293 const vaddr_t mask = CORE_MMU_PGDIR_MASK; 294 295 n = ((va & ~mask) - pager_tables[0].tbl_info.va_base) >> 296 CORE_MMU_PGDIR_SHIFT; 297 if (n >= ARRAY_SIZE(pager_tables)) 298 return NULL; 299 300 assert(va >= pager_tables[n].tbl_info.va_base && 301 va <= (pager_tables[n].tbl_info.va_base | mask)); 302 303 return pager_tables + n; 304 } 305 306 static struct pager_table *find_pager_table(vaddr_t va) 307 { 308 struct pager_table *pt = find_pager_table_may_fail(va); 309 310 assert(pt); 311 return pt; 312 } 313 314 bool tee_pager_get_table_info(vaddr_t va, struct core_mmu_table_info *ti) 315 { 316 struct pager_table *pt = find_pager_table_may_fail(va); 317 318 if (!pt) 319 return false; 320 321 *ti = pt->tbl_info; 322 return true; 323 } 324 325 static struct core_mmu_table_info *find_table_info(vaddr_t va) 326 { 327 return &find_pager_table(va)->tbl_info; 328 } 329 330 static struct pgt *find_core_pgt(vaddr_t va) 331 { 332 return &find_pager_table(va)->pgt; 333 } 334 335 void tee_pager_set_alias_area(tee_mm_entry_t *mm) 336 { 337 struct pager_table *pt; 338 unsigned idx; 339 vaddr_t smem = tee_mm_get_smem(mm); 340 size_t nbytes = tee_mm_get_bytes(mm); 341 vaddr_t v; 342 343 DMSG("0x%" PRIxVA " - 0x%" PRIxVA, smem, smem + nbytes); 344 345 assert(!pager_alias_area); 346 pager_alias_area = mm; 347 pager_alias_next_free = smem; 348 349 /* Clear all mapping in the alias area */ 350 pt = find_pager_table(smem); 351 idx = core_mmu_va2idx(&pt->tbl_info, smem); 352 while (pt <= (pager_tables + ARRAY_SIZE(pager_tables) - 1)) { 353 while (idx < TBL_NUM_ENTRIES) { 354 v = core_mmu_idx2va(&pt->tbl_info, idx); 355 if (v >= (smem + nbytes)) 356 goto out; 357 358 core_mmu_set_entry(&pt->tbl_info, idx, 0, 0); 359 idx++; 360 } 361 362 pt++; 363 idx = 0; 364 } 365 366 out: 367 tlbi_mva_range(smem, nbytes, SMALL_PAGE_SIZE); 368 } 369 370 void tee_pager_generate_authenc_key(void) 371 { 372 uint8_t key[PAGER_AE_KEY_BITS / 8]; 373 374 if (crypto_rng_read(key, sizeof(key)) != TEE_SUCCESS) 375 panic("failed to generate random"); 376 if (internal_aes_gcm_expand_enc_key(key, sizeof(key), 377 &pager_ae_key)) 378 panic("failed to expand key"); 379 } 380 381 static size_t tbl_usage_count(struct core_mmu_table_info *ti) 382 { 383 size_t n; 384 paddr_t pa; 385 size_t usage = 0; 386 387 for (n = 0; n < ti->num_entries; n++) { 388 core_mmu_get_entry(ti, n, &pa, NULL); 389 if (pa) 390 usage++; 391 } 392 return usage; 393 } 394 395 static void area_get_entry(struct tee_pager_area *area, size_t idx, 396 paddr_t *pa, uint32_t *attr) 397 { 398 assert(area->pgt); 399 assert(idx < TBL_NUM_ENTRIES); 400 core_mmu_get_entry_primitive(area->pgt->tbl, TBL_LEVEL, idx, pa, attr); 401 } 402 403 static void area_set_entry(struct tee_pager_area *area, size_t idx, 404 paddr_t pa, uint32_t attr) 405 { 406 assert(area->pgt); 407 assert(idx < TBL_NUM_ENTRIES); 408 core_mmu_set_entry_primitive(area->pgt->tbl, TBL_LEVEL, idx, pa, attr); 409 } 410 411 static size_t area_va2idx(struct tee_pager_area *area, vaddr_t va) 412 { 413 return (va - (area->base & ~CORE_MMU_PGDIR_MASK)) >> SMALL_PAGE_SHIFT; 414 } 415 416 static vaddr_t area_idx2va(struct tee_pager_area *area, size_t idx) 417 { 418 return (idx << SMALL_PAGE_SHIFT) + (area->base & ~CORE_MMU_PGDIR_MASK); 419 } 420 421 void tee_pager_early_init(void) 422 { 423 size_t n; 424 425 /* 426 * Note that this depends on add_pager_vaspace() adding vaspace 427 * after end of memory. 428 */ 429 for (n = 0; n < ARRAY_SIZE(pager_tables); n++) { 430 if (!core_mmu_find_table(NULL, TEE_RAM_VA_START + 431 n * CORE_MMU_PGDIR_SIZE, UINT_MAX, 432 &pager_tables[n].tbl_info)) 433 panic("can't find mmu tables"); 434 435 if (pager_tables[n].tbl_info.shift != TBL_SHIFT) 436 panic("Unsupported page size in translation table"); 437 assert(pager_tables[n].tbl_info.num_entries == TBL_NUM_ENTRIES); 438 assert(pager_tables[n].tbl_info.level == TBL_LEVEL); 439 440 pager_tables[n].pgt.tbl = pager_tables[n].tbl_info.table; 441 pgt_set_used_entries(&pager_tables[n].pgt, 442 tbl_usage_count(&pager_tables[n].tbl_info)); 443 } 444 } 445 446 static void *pager_add_alias_page(paddr_t pa) 447 { 448 unsigned idx; 449 struct core_mmu_table_info *ti; 450 /* Alias pages mapped without write permission: runtime will care */ 451 uint32_t attr = TEE_MATTR_VALID_BLOCK | 452 (TEE_MATTR_CACHE_CACHED << TEE_MATTR_CACHE_SHIFT) | 453 TEE_MATTR_SECURE | TEE_MATTR_PR; 454 455 DMSG("0x%" PRIxPA, pa); 456 457 ti = find_table_info(pager_alias_next_free); 458 idx = core_mmu_va2idx(ti, pager_alias_next_free); 459 core_mmu_set_entry(ti, idx, pa, attr); 460 pgt_inc_used_entries(find_core_pgt(pager_alias_next_free)); 461 pager_alias_next_free += SMALL_PAGE_SIZE; 462 if (pager_alias_next_free >= (tee_mm_get_smem(pager_alias_area) + 463 tee_mm_get_bytes(pager_alias_area))) 464 pager_alias_next_free = 0; 465 return (void *)core_mmu_idx2va(ti, idx); 466 } 467 468 static struct tee_pager_area *alloc_area(struct pgt *pgt, 469 vaddr_t base, size_t size, 470 uint32_t flags, const void *store, 471 const void *hashes) 472 { 473 struct tee_pager_area *area = calloc(1, sizeof(*area)); 474 enum area_type at; 475 tee_mm_entry_t *mm_store = NULL; 476 477 if (!area) 478 return NULL; 479 480 if (flags & (TEE_MATTR_PW | TEE_MATTR_UW)) { 481 if (flags & TEE_MATTR_LOCKED) { 482 at = AREA_TYPE_LOCK; 483 goto out; 484 } 485 mm_store = tee_mm_alloc(&tee_mm_sec_ddr, size); 486 if (!mm_store) 487 goto bad; 488 area->store = phys_to_virt(tee_mm_get_smem(mm_store), 489 MEM_AREA_TA_RAM); 490 if (!area->store) 491 goto bad; 492 area->u.rwp = calloc(size / SMALL_PAGE_SIZE, 493 sizeof(struct pager_rw_pstate)); 494 if (!area->u.rwp) 495 goto bad; 496 at = AREA_TYPE_RW; 497 } else { 498 area->store = (void *)store; 499 area->u.hashes = hashes; 500 at = AREA_TYPE_RO; 501 } 502 out: 503 area->pgt = pgt; 504 area->base = base; 505 area->size = size; 506 area->flags = flags; 507 area->type = at; 508 return area; 509 bad: 510 tee_mm_free(mm_store); 511 free(area->u.rwp); 512 free(area); 513 return NULL; 514 } 515 516 static void area_insert_tail(struct tee_pager_area *area) 517 { 518 uint32_t exceptions = pager_lock_check_stack(8); 519 520 TAILQ_INSERT_TAIL(&tee_pager_area_head, area, link); 521 522 pager_unlock(exceptions); 523 } 524 KEEP_PAGER(area_insert_tail); 525 526 void tee_pager_add_core_area(vaddr_t base, size_t size, uint32_t flags, 527 const void *store, const void *hashes) 528 { 529 struct tee_pager_area *area; 530 vaddr_t b = base; 531 size_t s = size; 532 size_t s2; 533 534 535 DMSG("0x%" PRIxPTR " - 0x%" PRIxPTR " : flags 0x%x, store %p, hashes %p", 536 base, base + size, flags, store, hashes); 537 538 if (base & SMALL_PAGE_MASK || size & SMALL_PAGE_MASK || !size) { 539 EMSG("invalid pager area [%" PRIxVA " +0x%zx]", base, size); 540 panic(); 541 } 542 543 if (!(flags & TEE_MATTR_PW) && (!store || !hashes)) 544 panic("write pages cannot provide store or hashes"); 545 546 if ((flags & TEE_MATTR_PW) && (store || hashes)) 547 panic("non-write pages must provide store and hashes"); 548 549 while (s) { 550 s2 = MIN(CORE_MMU_PGDIR_SIZE - (b & CORE_MMU_PGDIR_MASK), s); 551 area = alloc_area(find_core_pgt(b), b, s2, flags, 552 (const uint8_t *)store + b - base, 553 (const uint8_t *)hashes + (b - base) / 554 SMALL_PAGE_SIZE * 555 TEE_SHA256_HASH_SIZE); 556 if (!area) 557 panic("alloc_area"); 558 area_insert_tail(area); 559 b += s2; 560 s -= s2; 561 } 562 } 563 564 static struct tee_pager_area *find_area(struct tee_pager_area_head *areas, 565 vaddr_t va) 566 { 567 struct tee_pager_area *area; 568 569 if (!areas) 570 return NULL; 571 572 TAILQ_FOREACH(area, areas, link) { 573 if (core_is_buffer_inside(va, 1, area->base, area->size)) 574 return area; 575 } 576 return NULL; 577 } 578 579 #ifdef CFG_PAGED_USER_TA 580 static struct tee_pager_area *find_uta_area(vaddr_t va) 581 { 582 struct tee_ta_ctx *ctx = thread_get_tsd()->ctx; 583 584 if (!ctx || !is_user_ta_ctx(ctx)) 585 return NULL; 586 return find_area(to_user_ta_ctx(ctx)->areas, va); 587 } 588 #else 589 static struct tee_pager_area *find_uta_area(vaddr_t va __unused) 590 { 591 return NULL; 592 } 593 #endif /*CFG_PAGED_USER_TA*/ 594 595 596 static uint32_t get_area_mattr(uint32_t area_flags) 597 { 598 uint32_t attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_SECURE | 599 TEE_MATTR_CACHE_CACHED << TEE_MATTR_CACHE_SHIFT | 600 (area_flags & (TEE_MATTR_PRWX | TEE_MATTR_URWX)); 601 602 return attr; 603 } 604 605 static paddr_t get_pmem_pa(struct tee_pager_pmem *pmem) 606 { 607 struct core_mmu_table_info *ti; 608 paddr_t pa; 609 unsigned idx; 610 611 ti = find_table_info((vaddr_t)pmem->va_alias); 612 idx = core_mmu_va2idx(ti, (vaddr_t)pmem->va_alias); 613 core_mmu_get_entry(ti, idx, &pa, NULL); 614 return pa; 615 } 616 617 static bool decrypt_page(struct pager_rw_pstate *rwp, const void *src, 618 void *dst) 619 { 620 struct pager_aes_gcm_iv iv = { 621 { (vaddr_t)rwp, rwp->iv >> 32, rwp->iv } 622 }; 623 size_t tag_len = sizeof(rwp->tag); 624 625 return !internal_aes_gcm_dec(&pager_ae_key, &iv, sizeof(iv), 626 NULL, 0, src, SMALL_PAGE_SIZE, dst, 627 rwp->tag, tag_len); 628 } 629 630 static void encrypt_page(struct pager_rw_pstate *rwp, void *src, void *dst) 631 { 632 struct pager_aes_gcm_iv iv; 633 size_t tag_len = sizeof(rwp->tag); 634 635 assert((rwp->iv + 1) > rwp->iv); 636 rwp->iv++; 637 /* 638 * IV is constructed as recommended in section "8.2.1 Deterministic 639 * Construction" of "Recommendation for Block Cipher Modes of 640 * Operation: Galois/Counter Mode (GCM) and GMAC", 641 * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf 642 */ 643 iv.iv[0] = (vaddr_t)rwp; 644 iv.iv[1] = rwp->iv >> 32; 645 iv.iv[2] = rwp->iv; 646 647 if (internal_aes_gcm_enc(&pager_ae_key, &iv, sizeof(iv), NULL, 0, 648 src, SMALL_PAGE_SIZE, dst, rwp->tag, &tag_len)) 649 panic("gcm failed"); 650 } 651 652 static void tee_pager_load_page(struct tee_pager_area *area, vaddr_t page_va, 653 void *va_alias) 654 { 655 size_t idx = (page_va - area->base) >> SMALL_PAGE_SHIFT; 656 const void *stored_page = area->store + idx * SMALL_PAGE_SIZE; 657 struct core_mmu_table_info *ti; 658 uint32_t attr_alias; 659 paddr_t pa_alias; 660 unsigned int idx_alias; 661 662 /* Insure we are allowed to write to aliased virtual page */ 663 ti = find_table_info((vaddr_t)va_alias); 664 idx_alias = core_mmu_va2idx(ti, (vaddr_t)va_alias); 665 core_mmu_get_entry(ti, idx_alias, &pa_alias, &attr_alias); 666 if (!(attr_alias & TEE_MATTR_PW)) { 667 attr_alias |= TEE_MATTR_PW; 668 core_mmu_set_entry(ti, idx_alias, pa_alias, attr_alias); 669 tlbi_mva_allasid((vaddr_t)va_alias); 670 } 671 672 asan_tag_access(va_alias, (uint8_t *)va_alias + SMALL_PAGE_SIZE); 673 switch (area->type) { 674 case AREA_TYPE_RO: 675 { 676 const void *hash = area->u.hashes + 677 idx * TEE_SHA256_HASH_SIZE; 678 679 memcpy(va_alias, stored_page, SMALL_PAGE_SIZE); 680 incr_ro_hits(); 681 682 if (hash_sha256_check(hash, va_alias, 683 SMALL_PAGE_SIZE) != TEE_SUCCESS) { 684 EMSG("PH 0x%" PRIxVA " failed", page_va); 685 panic(); 686 } 687 } 688 /* Forbid write to aliases for read-only (maybe exec) pages */ 689 attr_alias &= ~TEE_MATTR_PW; 690 core_mmu_set_entry(ti, idx_alias, pa_alias, attr_alias); 691 tlbi_mva_allasid((vaddr_t)va_alias); 692 break; 693 case AREA_TYPE_RW: 694 FMSG("Restore %p %#" PRIxVA " iv %#" PRIx64, 695 va_alias, page_va, area->u.rwp[idx].iv); 696 if (!area->u.rwp[idx].iv) 697 memset(va_alias, 0, SMALL_PAGE_SIZE); 698 else if (!decrypt_page(&area->u.rwp[idx], stored_page, 699 va_alias)) { 700 EMSG("PH 0x%" PRIxVA " failed", page_va); 701 panic(); 702 } 703 incr_rw_hits(); 704 break; 705 case AREA_TYPE_LOCK: 706 FMSG("Zero init %p %#" PRIxVA, va_alias, page_va); 707 memset(va_alias, 0, SMALL_PAGE_SIZE); 708 break; 709 default: 710 panic(); 711 } 712 asan_tag_no_access(va_alias, (uint8_t *)va_alias + SMALL_PAGE_SIZE); 713 } 714 715 static void tee_pager_save_page(struct tee_pager_pmem *pmem, uint32_t attr) 716 { 717 const uint32_t dirty_bits = TEE_MATTR_PW | TEE_MATTR_UW | 718 TEE_MATTR_HIDDEN_DIRTY_BLOCK; 719 720 if (pmem->area->type == AREA_TYPE_RW && (attr & dirty_bits)) { 721 size_t offs = pmem->area->base & CORE_MMU_PGDIR_MASK; 722 size_t idx = pmem->pgidx - (offs >> SMALL_PAGE_SHIFT); 723 void *stored_page = pmem->area->store + idx * SMALL_PAGE_SIZE; 724 725 assert(pmem->area->flags & (TEE_MATTR_PW | TEE_MATTR_UW)); 726 asan_tag_access(pmem->va_alias, 727 (uint8_t *)pmem->va_alias + SMALL_PAGE_SIZE); 728 encrypt_page(&pmem->area->u.rwp[idx], pmem->va_alias, 729 stored_page); 730 asan_tag_no_access(pmem->va_alias, 731 (uint8_t *)pmem->va_alias + SMALL_PAGE_SIZE); 732 FMSG("Saved %#" PRIxVA " iv %#" PRIx64, 733 pmem->area->base + idx * SMALL_PAGE_SIZE, 734 pmem->area->u.rwp[idx].iv); 735 } 736 } 737 738 #ifdef CFG_PAGED_USER_TA 739 static void free_area(struct tee_pager_area *area) 740 { 741 tee_mm_free(tee_mm_find(&tee_mm_sec_ddr, 742 virt_to_phys(area->store))); 743 if (area->type == AREA_TYPE_RW) 744 free(area->u.rwp); 745 free(area); 746 } 747 748 static bool pager_add_uta_area(struct user_ta_ctx *utc, vaddr_t base, 749 size_t size) 750 { 751 struct tee_pager_area *area; 752 uint32_t flags; 753 vaddr_t b = base; 754 size_t s = ROUNDUP(size, SMALL_PAGE_SIZE); 755 756 if (!utc->areas) { 757 utc->areas = malloc(sizeof(*utc->areas)); 758 if (!utc->areas) 759 return false; 760 TAILQ_INIT(utc->areas); 761 } 762 763 flags = TEE_MATTR_PRW | TEE_MATTR_URWX; 764 765 while (s) { 766 size_t s2; 767 768 if (find_area(utc->areas, b)) 769 return false; 770 771 s2 = MIN(CORE_MMU_PGDIR_SIZE - (b & CORE_MMU_PGDIR_MASK), s); 772 773 /* Table info will be set when the context is activated. */ 774 area = alloc_area(NULL, b, s2, flags, NULL, NULL); 775 if (!area) 776 return false; 777 TAILQ_INSERT_TAIL(utc->areas, area, link); 778 b += s2; 779 s -= s2; 780 } 781 782 return true; 783 } 784 785 bool tee_pager_add_uta_area(struct user_ta_ctx *utc, vaddr_t base, size_t size) 786 { 787 struct thread_specific_data *tsd = thread_get_tsd(); 788 struct tee_pager_area *area; 789 struct core_mmu_table_info dir_info = { NULL }; 790 791 if (&utc->ctx != tsd->ctx) { 792 /* 793 * Changes are to an utc that isn't active. Just add the 794 * areas page tables will be dealt with later. 795 */ 796 return pager_add_uta_area(utc, base, size); 797 } 798 799 /* 800 * Assign page tables before adding areas to be able to tell which 801 * are newly added and should be removed in case of failure. 802 */ 803 tee_pager_assign_uta_tables(utc); 804 if (!pager_add_uta_area(utc, base, size)) { 805 struct tee_pager_area *next_a; 806 807 /* Remove all added areas */ 808 TAILQ_FOREACH_SAFE(area, utc->areas, link, next_a) { 809 if (!area->pgt) { 810 TAILQ_REMOVE(utc->areas, area, link); 811 free_area(area); 812 } 813 } 814 return false; 815 } 816 817 /* 818 * Assign page tables to the new areas and make sure that the page 819 * tables are registered in the upper table. 820 */ 821 tee_pager_assign_uta_tables(utc); 822 core_mmu_get_user_pgdir(&dir_info); 823 TAILQ_FOREACH(area, utc->areas, link) { 824 paddr_t pa; 825 size_t idx; 826 uint32_t attr; 827 828 idx = core_mmu_va2idx(&dir_info, area->pgt->vabase); 829 core_mmu_get_entry(&dir_info, idx, &pa, &attr); 830 831 /* 832 * Check if the page table already is used, if it is, it's 833 * already registered. 834 */ 835 if (area->pgt->num_used_entries) { 836 assert(attr & TEE_MATTR_TABLE); 837 assert(pa == virt_to_phys(area->pgt->tbl)); 838 continue; 839 } 840 841 attr = TEE_MATTR_SECURE | TEE_MATTR_TABLE; 842 pa = virt_to_phys(area->pgt->tbl); 843 assert(pa); 844 /* 845 * Note that the update of the table entry is guaranteed to 846 * be atomic. 847 */ 848 core_mmu_set_entry(&dir_info, idx, pa, attr); 849 } 850 851 return true; 852 } 853 854 static void init_tbl_info_from_pgt(struct core_mmu_table_info *ti, 855 struct pgt *pgt) 856 { 857 assert(pgt); 858 ti->table = pgt->tbl; 859 ti->va_base = pgt->vabase; 860 ti->level = TBL_LEVEL; 861 ti->shift = TBL_SHIFT; 862 ti->num_entries = TBL_NUM_ENTRIES; 863 } 864 865 static void transpose_area(struct tee_pager_area *area, struct pgt *new_pgt, 866 vaddr_t new_base) 867 { 868 uint32_t exceptions = pager_lock_check_stack(64); 869 870 /* 871 * If there's no pgt assigned to the old area there's no pages to 872 * deal with either, just update with a new pgt and base. 873 */ 874 if (area->pgt) { 875 struct core_mmu_table_info old_ti; 876 struct core_mmu_table_info new_ti; 877 struct tee_pager_pmem *pmem; 878 879 init_tbl_info_from_pgt(&old_ti, area->pgt); 880 init_tbl_info_from_pgt(&new_ti, new_pgt); 881 882 883 TAILQ_FOREACH(pmem, &tee_pager_pmem_head, link) { 884 vaddr_t va; 885 paddr_t pa; 886 uint32_t attr; 887 888 if (pmem->area != area) 889 continue; 890 core_mmu_get_entry(&old_ti, pmem->pgidx, &pa, &attr); 891 core_mmu_set_entry(&old_ti, pmem->pgidx, 0, 0); 892 893 assert(pa == get_pmem_pa(pmem)); 894 assert(attr); 895 assert(area->pgt->num_used_entries); 896 area->pgt->num_used_entries--; 897 898 va = core_mmu_idx2va(&old_ti, pmem->pgidx); 899 va = va - area->base + new_base; 900 pmem->pgidx = core_mmu_va2idx(&new_ti, va); 901 core_mmu_set_entry(&new_ti, pmem->pgidx, pa, attr); 902 new_pgt->num_used_entries++; 903 } 904 } 905 906 area->pgt = new_pgt; 907 area->base = new_base; 908 pager_unlock(exceptions); 909 } 910 KEEP_PAGER(transpose_area); 911 912 void tee_pager_transfer_uta_region(struct user_ta_ctx *src_utc, 913 vaddr_t src_base, 914 struct user_ta_ctx *dst_utc, 915 vaddr_t dst_base, struct pgt **dst_pgt, 916 size_t size) 917 { 918 struct tee_pager_area *area; 919 struct tee_pager_area *next_a; 920 921 TAILQ_FOREACH_SAFE(area, src_utc->areas, link, next_a) { 922 vaddr_t new_area_base; 923 size_t new_idx; 924 925 if (!core_is_buffer_inside(area->base, area->size, 926 src_base, size)) 927 continue; 928 929 TAILQ_REMOVE(src_utc->areas, area, link); 930 931 new_area_base = dst_base + (src_base - area->base); 932 new_idx = (new_area_base - dst_pgt[0]->vabase) / 933 CORE_MMU_PGDIR_SIZE; 934 assert((new_area_base & ~CORE_MMU_PGDIR_MASK) == 935 dst_pgt[new_idx]->vabase); 936 transpose_area(area, dst_pgt[new_idx], new_area_base); 937 938 /* 939 * Assert that this will not cause any conflicts in the new 940 * utc. This should already be guaranteed, but a bug here 941 * could be tricky to find. 942 */ 943 assert(!find_area(dst_utc->areas, area->base)); 944 TAILQ_INSERT_TAIL(dst_utc->areas, area, link); 945 } 946 } 947 948 static void rem_area(struct tee_pager_area_head *area_head, 949 struct tee_pager_area *area) 950 { 951 struct tee_pager_pmem *pmem; 952 uint32_t exceptions; 953 954 exceptions = pager_lock_check_stack(64); 955 956 TAILQ_REMOVE(area_head, area, link); 957 958 TAILQ_FOREACH(pmem, &tee_pager_pmem_head, link) { 959 if (pmem->area == area) { 960 area_set_entry(area, pmem->pgidx, 0, 0); 961 tlbi_mva_allasid(area_idx2va(area, pmem->pgidx)); 962 pgt_dec_used_entries(area->pgt); 963 pmem->area = NULL; 964 pmem->pgidx = INVALID_PGIDX; 965 } 966 } 967 968 pager_unlock(exceptions); 969 free_area(area); 970 } 971 KEEP_PAGER(rem_area); 972 973 void tee_pager_rem_uta_region(struct user_ta_ctx *utc, vaddr_t base, 974 size_t size) 975 { 976 struct tee_pager_area *area; 977 struct tee_pager_area *next_a; 978 size_t s = ROUNDUP(size, SMALL_PAGE_SIZE); 979 980 TAILQ_FOREACH_SAFE(area, utc->areas, link, next_a) { 981 if (core_is_buffer_inside(area->base, area->size, base, s)) 982 rem_area(utc->areas, area); 983 } 984 } 985 986 void tee_pager_rem_uta_areas(struct user_ta_ctx *utc) 987 { 988 struct tee_pager_area *area; 989 990 if (!utc->areas) 991 return; 992 993 while (true) { 994 area = TAILQ_FIRST(utc->areas); 995 if (!area) 996 break; 997 TAILQ_REMOVE(utc->areas, area, link); 998 free_area(area); 999 } 1000 1001 free(utc->areas); 1002 } 1003 1004 bool tee_pager_set_uta_area_attr(struct user_ta_ctx *utc, vaddr_t base, 1005 size_t size, uint32_t flags) 1006 { 1007 bool ret; 1008 vaddr_t b = base; 1009 size_t s = size; 1010 size_t s2; 1011 struct tee_pager_area *area = find_area(utc->areas, b); 1012 uint32_t exceptions; 1013 struct tee_pager_pmem *pmem; 1014 paddr_t pa; 1015 uint32_t a; 1016 uint32_t f; 1017 1018 f = (flags & TEE_MATTR_URWX) | TEE_MATTR_UR | TEE_MATTR_PR; 1019 if (f & TEE_MATTR_UW) 1020 f |= TEE_MATTR_PW; 1021 f = get_area_mattr(f); 1022 1023 exceptions = pager_lock_check_stack(SMALL_PAGE_SIZE); 1024 1025 while (s) { 1026 s2 = MIN(CORE_MMU_PGDIR_SIZE - (b & CORE_MMU_PGDIR_MASK), s); 1027 if (!area || area->base != b || area->size != s2) { 1028 ret = false; 1029 goto out; 1030 } 1031 b += s2; 1032 s -= s2; 1033 1034 TAILQ_FOREACH(pmem, &tee_pager_pmem_head, link) { 1035 if (pmem->area != area) 1036 continue; 1037 area_get_entry(pmem->area, pmem->pgidx, &pa, &a); 1038 if (a & TEE_MATTR_VALID_BLOCK) 1039 assert(pa == get_pmem_pa(pmem)); 1040 else 1041 pa = get_pmem_pa(pmem); 1042 if (a == f) 1043 continue; 1044 area_set_entry(pmem->area, pmem->pgidx, 0, 0); 1045 tlbi_mva_allasid(area_idx2va(pmem->area, pmem->pgidx)); 1046 if (!(flags & TEE_MATTR_UW)) 1047 tee_pager_save_page(pmem, a); 1048 1049 area_set_entry(pmem->area, pmem->pgidx, pa, f); 1050 /* 1051 * Make sure the table update is visible before 1052 * continuing. 1053 */ 1054 dsb_ishst(); 1055 1056 if (flags & TEE_MATTR_UX) { 1057 void *va = (void *)area_idx2va(pmem->area, 1058 pmem->pgidx); 1059 1060 cache_op_inner(DCACHE_AREA_CLEAN, va, 1061 SMALL_PAGE_SIZE); 1062 cache_op_inner(ICACHE_AREA_INVALIDATE, va, 1063 SMALL_PAGE_SIZE); 1064 } 1065 } 1066 1067 area->flags = f; 1068 area = TAILQ_NEXT(area, link); 1069 } 1070 1071 ret = true; 1072 out: 1073 pager_unlock(exceptions); 1074 return ret; 1075 } 1076 KEEP_PAGER(tee_pager_set_uta_area_attr); 1077 #endif /*CFG_PAGED_USER_TA*/ 1078 1079 static bool tee_pager_unhide_page(vaddr_t page_va) 1080 { 1081 struct tee_pager_pmem *pmem; 1082 1083 TAILQ_FOREACH(pmem, &tee_pager_pmem_head, link) { 1084 paddr_t pa; 1085 uint32_t attr; 1086 1087 if (pmem->pgidx == INVALID_PGIDX) 1088 continue; 1089 1090 area_get_entry(pmem->area, pmem->pgidx, &pa, &attr); 1091 1092 if (!(attr & 1093 (TEE_MATTR_HIDDEN_BLOCK | TEE_MATTR_HIDDEN_DIRTY_BLOCK))) 1094 continue; 1095 1096 if (area_va2idx(pmem->area, page_va) == pmem->pgidx) { 1097 uint32_t a = get_area_mattr(pmem->area->flags); 1098 1099 /* page is hidden, show and move to back */ 1100 if (pa != get_pmem_pa(pmem)) 1101 panic("unexpected pa"); 1102 1103 /* 1104 * If it's not a dirty block, then it should be 1105 * read only. 1106 */ 1107 if (!(attr & TEE_MATTR_HIDDEN_DIRTY_BLOCK)) 1108 a &= ~(TEE_MATTR_PW | TEE_MATTR_UW); 1109 else 1110 FMSG("Unhide %#" PRIxVA, page_va); 1111 1112 if (page_va == 0x8000a000) 1113 FMSG("unhide %#" PRIxVA " a %#" PRIX32, 1114 page_va, a); 1115 area_set_entry(pmem->area, pmem->pgidx, pa, a); 1116 /* 1117 * Note that TLB invalidation isn't needed since 1118 * there wasn't a valid mapping before. We should 1119 * use a barrier though, to make sure that the 1120 * change is visible. 1121 */ 1122 dsb_ishst(); 1123 1124 TAILQ_REMOVE(&tee_pager_pmem_head, pmem, link); 1125 TAILQ_INSERT_TAIL(&tee_pager_pmem_head, pmem, link); 1126 incr_hidden_hits(); 1127 return true; 1128 } 1129 } 1130 1131 return false; 1132 } 1133 1134 static void tee_pager_hide_pages(void) 1135 { 1136 struct tee_pager_pmem *pmem; 1137 size_t n = 0; 1138 1139 TAILQ_FOREACH(pmem, &tee_pager_pmem_head, link) { 1140 paddr_t pa; 1141 uint32_t attr; 1142 uint32_t a; 1143 1144 if (n >= TEE_PAGER_NHIDE) 1145 break; 1146 n++; 1147 1148 /* we cannot hide pages when pmem->area is not defined. */ 1149 if (!pmem->area) 1150 continue; 1151 1152 area_get_entry(pmem->area, pmem->pgidx, &pa, &attr); 1153 if (!(attr & TEE_MATTR_VALID_BLOCK)) 1154 continue; 1155 1156 assert(pa == get_pmem_pa(pmem)); 1157 if (attr & (TEE_MATTR_PW | TEE_MATTR_UW)){ 1158 a = TEE_MATTR_HIDDEN_DIRTY_BLOCK; 1159 FMSG("Hide %#" PRIxVA, 1160 area_idx2va(pmem->area, pmem->pgidx)); 1161 } else 1162 a = TEE_MATTR_HIDDEN_BLOCK; 1163 1164 area_set_entry(pmem->area, pmem->pgidx, pa, a); 1165 tlbi_mva_allasid(area_idx2va(pmem->area, pmem->pgidx)); 1166 } 1167 } 1168 1169 /* 1170 * Find mapped pmem, hide and move to pageble pmem. 1171 * Return false if page was not mapped, and true if page was mapped. 1172 */ 1173 static bool tee_pager_release_one_phys(struct tee_pager_area *area, 1174 vaddr_t page_va) 1175 { 1176 struct tee_pager_pmem *pmem; 1177 unsigned pgidx; 1178 paddr_t pa; 1179 uint32_t attr; 1180 1181 pgidx = area_va2idx(area, page_va); 1182 area_get_entry(area, pgidx, &pa, &attr); 1183 1184 FMSG("%" PRIxVA " : %" PRIxPA "|%x", page_va, pa, attr); 1185 1186 TAILQ_FOREACH(pmem, &tee_pager_lock_pmem_head, link) { 1187 if (pmem->area != area || pmem->pgidx != pgidx) 1188 continue; 1189 1190 assert(pa == get_pmem_pa(pmem)); 1191 area_set_entry(area, pgidx, 0, 0); 1192 pgt_dec_used_entries(area->pgt); 1193 TAILQ_REMOVE(&tee_pager_lock_pmem_head, pmem, link); 1194 pmem->area = NULL; 1195 pmem->pgidx = INVALID_PGIDX; 1196 tee_pager_npages++; 1197 set_npages(); 1198 TAILQ_INSERT_HEAD(&tee_pager_pmem_head, pmem, link); 1199 incr_zi_released(); 1200 return true; 1201 } 1202 1203 return false; 1204 } 1205 1206 /* Finds the oldest page and unmats it from its old virtual address */ 1207 static struct tee_pager_pmem *tee_pager_get_page(struct tee_pager_area *area) 1208 { 1209 struct tee_pager_pmem *pmem; 1210 1211 pmem = TAILQ_FIRST(&tee_pager_pmem_head); 1212 if (!pmem) { 1213 EMSG("No pmem entries"); 1214 return NULL; 1215 } 1216 if (pmem->pgidx != INVALID_PGIDX) { 1217 uint32_t a; 1218 1219 assert(pmem->area && pmem->area->pgt); 1220 area_get_entry(pmem->area, pmem->pgidx, NULL, &a); 1221 area_set_entry(pmem->area, pmem->pgidx, 0, 0); 1222 pgt_dec_used_entries(pmem->area->pgt); 1223 tlbi_mva_allasid(area_idx2va(pmem->area, pmem->pgidx)); 1224 tee_pager_save_page(pmem, a); 1225 } 1226 1227 TAILQ_REMOVE(&tee_pager_pmem_head, pmem, link); 1228 pmem->pgidx = INVALID_PGIDX; 1229 pmem->area = NULL; 1230 if (area->type == AREA_TYPE_LOCK) { 1231 /* Move page to lock list */ 1232 if (tee_pager_npages <= 0) 1233 panic("running out of page"); 1234 tee_pager_npages--; 1235 set_npages(); 1236 TAILQ_INSERT_TAIL(&tee_pager_lock_pmem_head, pmem, link); 1237 } else { 1238 /* move page to back */ 1239 TAILQ_INSERT_TAIL(&tee_pager_pmem_head, pmem, link); 1240 } 1241 1242 return pmem; 1243 } 1244 1245 static bool pager_update_permissions(struct tee_pager_area *area, 1246 struct abort_info *ai, bool *handled) 1247 { 1248 unsigned int pgidx = area_va2idx(area, ai->va); 1249 uint32_t attr; 1250 paddr_t pa; 1251 1252 *handled = false; 1253 1254 area_get_entry(area, pgidx, &pa, &attr); 1255 1256 /* Not mapped */ 1257 if (!(attr & TEE_MATTR_VALID_BLOCK)) 1258 return false; 1259 1260 /* Not readable, should not happen */ 1261 if (abort_is_user_exception(ai)) { 1262 if (!(attr & TEE_MATTR_UR)) 1263 return true; 1264 } else { 1265 if (!(attr & TEE_MATTR_PR)) { 1266 abort_print_error(ai); 1267 panic(); 1268 } 1269 } 1270 1271 switch (core_mmu_get_fault_type(ai->fault_descr)) { 1272 case CORE_MMU_FAULT_TRANSLATION: 1273 case CORE_MMU_FAULT_READ_PERMISSION: 1274 if (ai->abort_type == ABORT_TYPE_PREFETCH) { 1275 /* Check attempting to execute from an NOX page */ 1276 if (abort_is_user_exception(ai)) { 1277 if (!(attr & TEE_MATTR_UX)) 1278 return true; 1279 } else { 1280 if (!(attr & TEE_MATTR_PX)) { 1281 abort_print_error(ai); 1282 panic(); 1283 } 1284 } 1285 } 1286 /* Since the page is mapped now it's OK */ 1287 break; 1288 case CORE_MMU_FAULT_WRITE_PERMISSION: 1289 /* Check attempting to write to an RO page */ 1290 if (abort_is_user_exception(ai)) { 1291 if (!(area->flags & TEE_MATTR_UW)) 1292 return true; 1293 if (!(attr & TEE_MATTR_UW)) { 1294 FMSG("Dirty %p", 1295 (void *)(ai->va & ~SMALL_PAGE_MASK)); 1296 area_set_entry(area, pgidx, pa, 1297 get_area_mattr(area->flags)); 1298 tlbi_mva_allasid(ai->va & ~SMALL_PAGE_MASK); 1299 } 1300 1301 } else { 1302 if (!(area->flags & TEE_MATTR_PW)) { 1303 abort_print_error(ai); 1304 panic(); 1305 } 1306 if (!(attr & TEE_MATTR_PW)) { 1307 FMSG("Dirty %p", 1308 (void *)(ai->va & ~SMALL_PAGE_MASK)); 1309 area_set_entry(area, pgidx, pa, 1310 get_area_mattr(area->flags)); 1311 tlbi_mva_allasid(ai->va & ~SMALL_PAGE_MASK); 1312 } 1313 } 1314 /* Since permissions has been updated now it's OK */ 1315 break; 1316 default: 1317 /* Some fault we can't deal with */ 1318 if (abort_is_user_exception(ai)) 1319 return true; 1320 abort_print_error(ai); 1321 panic(); 1322 } 1323 *handled = true; 1324 return true; 1325 } 1326 1327 #ifdef CFG_TEE_CORE_DEBUG 1328 static void stat_handle_fault(void) 1329 { 1330 static size_t num_faults; 1331 static size_t min_npages = SIZE_MAX; 1332 static size_t total_min_npages = SIZE_MAX; 1333 1334 num_faults++; 1335 if ((num_faults % 1024) == 0 || tee_pager_npages < total_min_npages) { 1336 DMSG("nfaults %zu npages %zu (min %zu)", 1337 num_faults, tee_pager_npages, min_npages); 1338 min_npages = tee_pager_npages; /* reset */ 1339 } 1340 if (tee_pager_npages < min_npages) 1341 min_npages = tee_pager_npages; 1342 if (tee_pager_npages < total_min_npages) 1343 total_min_npages = tee_pager_npages; 1344 } 1345 #else 1346 static void stat_handle_fault(void) 1347 { 1348 } 1349 #endif 1350 1351 bool tee_pager_handle_fault(struct abort_info *ai) 1352 { 1353 struct tee_pager_area *area; 1354 vaddr_t page_va = ai->va & ~SMALL_PAGE_MASK; 1355 uint32_t exceptions; 1356 bool ret; 1357 1358 #ifdef TEE_PAGER_DEBUG_PRINT 1359 abort_print(ai); 1360 #endif 1361 1362 /* 1363 * We're updating pages that can affect several active CPUs at a 1364 * time below. We end up here because a thread tries to access some 1365 * memory that isn't available. We have to be careful when making 1366 * that memory available as other threads may succeed in accessing 1367 * that address the moment after we've made it available. 1368 * 1369 * That means that we can't just map the memory and populate the 1370 * page, instead we use the aliased mapping to populate the page 1371 * and once everything is ready we map it. 1372 */ 1373 exceptions = pager_lock(ai); 1374 1375 stat_handle_fault(); 1376 1377 /* check if the access is valid */ 1378 if (abort_is_user_exception(ai)) { 1379 area = find_uta_area(ai->va); 1380 1381 } else { 1382 area = find_area(&tee_pager_area_head, ai->va); 1383 if (!area) 1384 area = find_uta_area(ai->va); 1385 } 1386 if (!area || !area->pgt) { 1387 ret = false; 1388 goto out; 1389 } 1390 1391 if (!tee_pager_unhide_page(page_va)) { 1392 struct tee_pager_pmem *pmem = NULL; 1393 uint32_t attr; 1394 paddr_t pa; 1395 1396 /* 1397 * The page wasn't hidden, but some other core may have 1398 * updated the table entry before we got here or we need 1399 * to make a read-only page read-write (dirty). 1400 */ 1401 if (pager_update_permissions(area, ai, &ret)) { 1402 /* 1403 * Nothing more to do with the abort. The problem 1404 * could already have been dealt with from another 1405 * core or if ret is false the TA will be paniced. 1406 */ 1407 goto out; 1408 } 1409 1410 pmem = tee_pager_get_page(area); 1411 if (!pmem) { 1412 abort_print(ai); 1413 panic(); 1414 } 1415 1416 /* load page code & data */ 1417 tee_pager_load_page(area, page_va, pmem->va_alias); 1418 1419 1420 pmem->area = area; 1421 pmem->pgidx = area_va2idx(area, ai->va); 1422 attr = get_area_mattr(area->flags) & 1423 ~(TEE_MATTR_PW | TEE_MATTR_UW); 1424 pa = get_pmem_pa(pmem); 1425 1426 /* 1427 * We've updated the page using the aliased mapping and 1428 * some cache maintenence is now needed if it's an 1429 * executable page. 1430 * 1431 * Since the d-cache is a Physically-indexed, 1432 * physically-tagged (PIPT) cache we can clean either the 1433 * aliased address or the real virtual address. In this 1434 * case we choose the real virtual address. 1435 * 1436 * The i-cache can also be PIPT, but may be something else 1437 * too like VIPT. The current code requires the caches to 1438 * implement the IVIPT extension, that is: 1439 * "instruction cache maintenance is required only after 1440 * writing new data to a physical address that holds an 1441 * instruction." 1442 * 1443 * To portably invalidate the icache the page has to 1444 * be mapped at the final virtual address but not 1445 * executable. 1446 */ 1447 if (area->flags & (TEE_MATTR_PX | TEE_MATTR_UX)) { 1448 uint32_t mask = TEE_MATTR_PX | TEE_MATTR_UX | 1449 TEE_MATTR_PW | TEE_MATTR_UW; 1450 1451 /* Set a temporary read-only mapping */ 1452 area_set_entry(pmem->area, pmem->pgidx, pa, 1453 attr & ~mask); 1454 tlbi_mva_allasid(page_va); 1455 1456 /* 1457 * Doing these operations to LoUIS (Level of 1458 * unification, Inner Shareable) would be enough 1459 */ 1460 cache_op_inner(DCACHE_AREA_CLEAN, (void *)page_va, 1461 SMALL_PAGE_SIZE); 1462 cache_op_inner(ICACHE_AREA_INVALIDATE, (void *)page_va, 1463 SMALL_PAGE_SIZE); 1464 1465 /* Set the final mapping */ 1466 area_set_entry(area, pmem->pgidx, pa, attr); 1467 tlbi_mva_allasid(page_va); 1468 } else { 1469 area_set_entry(area, pmem->pgidx, pa, attr); 1470 /* 1471 * No need to flush TLB for this entry, it was 1472 * invalid. We should use a barrier though, to make 1473 * sure that the change is visible. 1474 */ 1475 dsb_ishst(); 1476 } 1477 pgt_inc_used_entries(area->pgt); 1478 1479 FMSG("Mapped 0x%" PRIxVA " -> 0x%" PRIxPA, page_va, pa); 1480 1481 } 1482 1483 tee_pager_hide_pages(); 1484 ret = true; 1485 out: 1486 pager_unlock(exceptions); 1487 return ret; 1488 } 1489 1490 void tee_pager_add_pages(vaddr_t vaddr, size_t npages, bool unmap) 1491 { 1492 size_t n; 1493 1494 DMSG("0x%" PRIxVA " - 0x%" PRIxVA " : %d", 1495 vaddr, vaddr + npages * SMALL_PAGE_SIZE, (int)unmap); 1496 1497 /* setup memory */ 1498 for (n = 0; n < npages; n++) { 1499 struct core_mmu_table_info *ti; 1500 struct tee_pager_pmem *pmem; 1501 vaddr_t va = vaddr + n * SMALL_PAGE_SIZE; 1502 unsigned int pgidx; 1503 paddr_t pa; 1504 uint32_t attr; 1505 1506 ti = find_table_info(va); 1507 pgidx = core_mmu_va2idx(ti, va); 1508 /* 1509 * Note that we can only support adding pages in the 1510 * valid range of this table info, currently not a problem. 1511 */ 1512 core_mmu_get_entry(ti, pgidx, &pa, &attr); 1513 1514 /* Ignore unmapped pages/blocks */ 1515 if (!(attr & TEE_MATTR_VALID_BLOCK)) 1516 continue; 1517 1518 pmem = malloc(sizeof(struct tee_pager_pmem)); 1519 if (!pmem) 1520 panic("out of mem"); 1521 1522 pmem->va_alias = pager_add_alias_page(pa); 1523 1524 if (unmap) { 1525 pmem->area = NULL; 1526 pmem->pgidx = INVALID_PGIDX; 1527 core_mmu_set_entry(ti, pgidx, 0, 0); 1528 pgt_dec_used_entries(find_core_pgt(va)); 1529 } else { 1530 /* 1531 * The page is still mapped, let's assign the area 1532 * and update the protection bits accordingly. 1533 */ 1534 pmem->area = find_area(&tee_pager_area_head, va); 1535 assert(pmem->area->pgt == find_core_pgt(va)); 1536 pmem->pgidx = pgidx; 1537 assert(pa == get_pmem_pa(pmem)); 1538 area_set_entry(pmem->area, pgidx, pa, 1539 get_area_mattr(pmem->area->flags)); 1540 } 1541 1542 tee_pager_npages++; 1543 incr_npages_all(); 1544 set_npages(); 1545 TAILQ_INSERT_TAIL(&tee_pager_pmem_head, pmem, link); 1546 } 1547 1548 /* 1549 * As this is done at inits, invalidate all TLBs once instead of 1550 * targeting only the modified entries. 1551 */ 1552 tlbi_all(); 1553 } 1554 1555 #ifdef CFG_PAGED_USER_TA 1556 static struct pgt *find_pgt(struct pgt *pgt, vaddr_t va) 1557 { 1558 struct pgt *p = pgt; 1559 1560 while (p && (va & ~CORE_MMU_PGDIR_MASK) != p->vabase) 1561 p = SLIST_NEXT(p, link); 1562 return p; 1563 } 1564 1565 void tee_pager_assign_uta_tables(struct user_ta_ctx *utc) 1566 { 1567 struct tee_pager_area *area; 1568 struct pgt *pgt = SLIST_FIRST(&thread_get_tsd()->pgt_cache); 1569 1570 TAILQ_FOREACH(area, utc->areas, link) { 1571 if (!area->pgt) 1572 area->pgt = find_pgt(pgt, area->base); 1573 else 1574 assert(area->pgt == find_pgt(pgt, area->base)); 1575 if (!area->pgt) 1576 panic(); 1577 } 1578 } 1579 1580 static void pager_save_and_release_entry(struct tee_pager_pmem *pmem) 1581 { 1582 uint32_t attr; 1583 1584 assert(pmem->area && pmem->area->pgt); 1585 1586 area_get_entry(pmem->area, pmem->pgidx, NULL, &attr); 1587 area_set_entry(pmem->area, pmem->pgidx, 0, 0); 1588 tlbi_mva_allasid(area_idx2va(pmem->area, pmem->pgidx)); 1589 tee_pager_save_page(pmem, attr); 1590 assert(pmem->area->pgt->num_used_entries); 1591 pmem->area->pgt->num_used_entries--; 1592 pmem->pgidx = INVALID_PGIDX; 1593 pmem->area = NULL; 1594 } 1595 1596 void tee_pager_pgt_save_and_release_entries(struct pgt *pgt) 1597 { 1598 struct tee_pager_pmem *pmem; 1599 struct tee_pager_area *area; 1600 uint32_t exceptions = pager_lock_check_stack(SMALL_PAGE_SIZE); 1601 1602 if (!pgt->num_used_entries) 1603 goto out; 1604 1605 TAILQ_FOREACH(pmem, &tee_pager_pmem_head, link) { 1606 if (!pmem->area || pmem->pgidx == INVALID_PGIDX) 1607 continue; 1608 if (pmem->area->pgt == pgt) 1609 pager_save_and_release_entry(pmem); 1610 } 1611 assert(!pgt->num_used_entries); 1612 1613 out: 1614 if (is_user_ta_ctx(pgt->ctx)) { 1615 TAILQ_FOREACH(area, to_user_ta_ctx(pgt->ctx)->areas, link) { 1616 if (area->pgt == pgt) 1617 area->pgt = NULL; 1618 } 1619 } 1620 1621 pager_unlock(exceptions); 1622 } 1623 KEEP_PAGER(tee_pager_pgt_save_and_release_entries); 1624 #endif /*CFG_PAGED_USER_TA*/ 1625 1626 void tee_pager_release_phys(void *addr, size_t size) 1627 { 1628 bool unmaped = false; 1629 vaddr_t va = (vaddr_t)addr; 1630 vaddr_t begin = ROUNDUP(va, SMALL_PAGE_SIZE); 1631 vaddr_t end = ROUNDDOWN(va + size, SMALL_PAGE_SIZE); 1632 struct tee_pager_area *area; 1633 uint32_t exceptions; 1634 1635 if (end <= begin) 1636 return; 1637 1638 exceptions = pager_lock_check_stack(128); 1639 1640 for (va = begin; va < end; va += SMALL_PAGE_SIZE) { 1641 area = find_area(&tee_pager_area_head, va); 1642 if (!area) 1643 panic(); 1644 unmaped |= tee_pager_release_one_phys(area, va); 1645 } 1646 1647 if (unmaped) 1648 tlbi_mva_range(begin, end - begin, SMALL_PAGE_SIZE); 1649 1650 pager_unlock(exceptions); 1651 } 1652 KEEP_PAGER(tee_pager_release_phys); 1653 1654 void *tee_pager_alloc(size_t size, uint32_t flags) 1655 { 1656 tee_mm_entry_t *mm; 1657 uint32_t f = TEE_MATTR_PW | TEE_MATTR_PR | (flags & TEE_MATTR_LOCKED); 1658 uint8_t *smem; 1659 size_t bytes; 1660 1661 if (!size) 1662 return NULL; 1663 1664 mm = tee_mm_alloc(&tee_mm_vcore, ROUNDUP(size, SMALL_PAGE_SIZE)); 1665 if (!mm) 1666 return NULL; 1667 1668 bytes = tee_mm_get_bytes(mm); 1669 smem = (uint8_t *)tee_mm_get_smem(mm); 1670 tee_pager_add_core_area((vaddr_t)smem, bytes, f, NULL, NULL); 1671 asan_tag_access(smem, smem + bytes); 1672 1673 return smem; 1674 } 1675