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