18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#define DISABLE_BRANCH_PROFILING 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/kasan.h> 68c2ecf20Sopenharmony_ci#include <linux/memblock.h> 78c2ecf20Sopenharmony_ci#include <mm/mmu_decl.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ciint __init kasan_init_region(void *start, size_t size) 108c2ecf20Sopenharmony_ci{ 118c2ecf20Sopenharmony_ci unsigned long k_start = (unsigned long)kasan_mem_to_shadow(start); 128c2ecf20Sopenharmony_ci unsigned long k_end = (unsigned long)kasan_mem_to_shadow(start + size); 138c2ecf20Sopenharmony_ci unsigned long k_nobat = k_start; 148c2ecf20Sopenharmony_ci unsigned long k_cur; 158c2ecf20Sopenharmony_ci phys_addr_t phys; 168c2ecf20Sopenharmony_ci int ret; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci while (k_nobat < k_end) { 198c2ecf20Sopenharmony_ci unsigned int k_size = bat_block_size(k_nobat, k_end); 208c2ecf20Sopenharmony_ci int idx = find_free_bat(); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci if (idx == -1) 238c2ecf20Sopenharmony_ci break; 248c2ecf20Sopenharmony_ci if (k_size < SZ_128K) 258c2ecf20Sopenharmony_ci break; 268c2ecf20Sopenharmony_ci phys = memblock_phys_alloc_range(k_size, k_size, 0, 278c2ecf20Sopenharmony_ci MEMBLOCK_ALLOC_ANYWHERE); 288c2ecf20Sopenharmony_ci if (!phys) 298c2ecf20Sopenharmony_ci break; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci setbat(idx, k_nobat, phys, k_size, PAGE_KERNEL); 328c2ecf20Sopenharmony_ci k_nobat += k_size; 338c2ecf20Sopenharmony_ci } 348c2ecf20Sopenharmony_ci if (k_nobat != k_start) 358c2ecf20Sopenharmony_ci update_bats(); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (k_nobat < k_end) { 388c2ecf20Sopenharmony_ci phys = memblock_phys_alloc_range(k_end - k_nobat, PAGE_SIZE, 0, 398c2ecf20Sopenharmony_ci MEMBLOCK_ALLOC_ANYWHERE); 408c2ecf20Sopenharmony_ci if (!phys) 418c2ecf20Sopenharmony_ci return -ENOMEM; 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci ret = kasan_init_shadow_page_tables(k_start, k_end); 458c2ecf20Sopenharmony_ci if (ret) 468c2ecf20Sopenharmony_ci return ret; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci kasan_update_early_region(k_start, k_nobat, __pte(0)); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci for (k_cur = k_nobat; k_cur < k_end; k_cur += PAGE_SIZE) { 518c2ecf20Sopenharmony_ci pmd_t *pmd = pmd_off_k(k_cur); 528c2ecf20Sopenharmony_ci pte_t pte = pfn_pte(PHYS_PFN(phys + k_cur - k_nobat), PAGE_KERNEL); 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci __set_pte_at(&init_mm, k_cur, pte_offset_kernel(pmd, k_cur), pte, 0); 558c2ecf20Sopenharmony_ci } 568c2ecf20Sopenharmony_ci flush_tlb_kernel_range(k_start, k_end); 578c2ecf20Sopenharmony_ci memset(kasan_mem_to_shadow(start), 0, k_end - k_start); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci return 0; 608c2ecf20Sopenharmony_ci} 61