162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#define DISABLE_BRANCH_PROFILING 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/kasan.h> 662306a36Sopenharmony_ci#include <linux/memblock.h> 762306a36Sopenharmony_ci#include <mm/mmu_decl.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciint __init kasan_init_region(void *start, size_t size) 1062306a36Sopenharmony_ci{ 1162306a36Sopenharmony_ci unsigned long k_start = (unsigned long)kasan_mem_to_shadow(start); 1262306a36Sopenharmony_ci unsigned long k_end = (unsigned long)kasan_mem_to_shadow(start + size); 1362306a36Sopenharmony_ci unsigned long k_nobat = k_start; 1462306a36Sopenharmony_ci unsigned long k_cur; 1562306a36Sopenharmony_ci phys_addr_t phys; 1662306a36Sopenharmony_ci int ret; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci while (k_nobat < k_end) { 1962306a36Sopenharmony_ci unsigned int k_size = bat_block_size(k_nobat, k_end); 2062306a36Sopenharmony_ci int idx = find_free_bat(); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci if (idx == -1) 2362306a36Sopenharmony_ci break; 2462306a36Sopenharmony_ci if (k_size < SZ_128K) 2562306a36Sopenharmony_ci break; 2662306a36Sopenharmony_ci phys = memblock_phys_alloc_range(k_size, k_size, 0, 2762306a36Sopenharmony_ci MEMBLOCK_ALLOC_ANYWHERE); 2862306a36Sopenharmony_ci if (!phys) 2962306a36Sopenharmony_ci break; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci setbat(idx, k_nobat, phys, k_size, PAGE_KERNEL); 3262306a36Sopenharmony_ci k_nobat += k_size; 3362306a36Sopenharmony_ci } 3462306a36Sopenharmony_ci if (k_nobat != k_start) 3562306a36Sopenharmony_ci update_bats(); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci if (k_nobat < k_end) { 3862306a36Sopenharmony_ci phys = memblock_phys_alloc_range(k_end - k_nobat, PAGE_SIZE, 0, 3962306a36Sopenharmony_ci MEMBLOCK_ALLOC_ANYWHERE); 4062306a36Sopenharmony_ci if (!phys) 4162306a36Sopenharmony_ci return -ENOMEM; 4262306a36Sopenharmony_ci } 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci ret = kasan_init_shadow_page_tables(k_start, k_end); 4562306a36Sopenharmony_ci if (ret) 4662306a36Sopenharmony_ci return ret; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci kasan_update_early_region(k_start, k_nobat, __pte(0)); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci for (k_cur = k_nobat; k_cur < k_end; k_cur += PAGE_SIZE) { 5162306a36Sopenharmony_ci pmd_t *pmd = pmd_off_k(k_cur); 5262306a36Sopenharmony_ci pte_t pte = pfn_pte(PHYS_PFN(phys + k_cur - k_nobat), PAGE_KERNEL); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci __set_pte_at(&init_mm, k_cur, pte_offset_kernel(pmd, k_cur), pte, 0); 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci flush_tlb_kernel_range(k_start, k_end); 5762306a36Sopenharmony_ci memset(kasan_mem_to_shadow(start), 0, k_end - k_start); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci return 0; 6062306a36Sopenharmony_ci} 61