Path: blob/master/arch/powerpc/mm/kasan/init_book3e_64.c
26481 views
// SPDX-License-Identifier: GPL-2.01/*2* KASAN for 64-bit Book3e powerpc3*4* Copyright 2022, Christophe Leroy, CS GROUP France5*/67#define DISABLE_BRANCH_PROFILING89#include <linux/kasan.h>10#include <linux/printk.h>11#include <linux/memblock.h>12#include <linux/set_memory.h>1314#include <asm/pgalloc.h>1516static inline bool kasan_pud_table(p4d_t p4d)17{18return p4d_page(p4d) == virt_to_page(lm_alias(kasan_early_shadow_pud));19}2021static inline bool kasan_pmd_table(pud_t pud)22{23return pud_page(pud) == virt_to_page(lm_alias(kasan_early_shadow_pmd));24}2526static inline bool kasan_pte_table(pmd_t pmd)27{28return pmd_page(pmd) == virt_to_page(lm_alias(kasan_early_shadow_pte));29}3031static int __init kasan_map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot)32{33pgd_t *pgdp;34p4d_t *p4dp;35pud_t *pudp;36pmd_t *pmdp;37pte_t *ptep;3839pgdp = pgd_offset_k(ea);40p4dp = p4d_offset(pgdp, ea);41if (kasan_pud_table(*p4dp)) {42pudp = memblock_alloc_or_panic(PUD_TABLE_SIZE, PUD_TABLE_SIZE);43memcpy(pudp, kasan_early_shadow_pud, PUD_TABLE_SIZE);44p4d_populate(&init_mm, p4dp, pudp);45}46pudp = pud_offset(p4dp, ea);47if (kasan_pmd_table(*pudp)) {48pmdp = memblock_alloc_or_panic(PMD_TABLE_SIZE, PMD_TABLE_SIZE);49memcpy(pmdp, kasan_early_shadow_pmd, PMD_TABLE_SIZE);50pud_populate(&init_mm, pudp, pmdp);51}52pmdp = pmd_offset(pudp, ea);53if (kasan_pte_table(*pmdp)) {54ptep = memblock_alloc_or_panic(PTE_TABLE_SIZE, PTE_TABLE_SIZE);55memcpy(ptep, kasan_early_shadow_pte, PTE_TABLE_SIZE);56pmd_populate_kernel(&init_mm, pmdp, ptep);57}58ptep = pte_offset_kernel(pmdp, ea);5960__set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, prot), 0);6162return 0;63}6465static void __init kasan_init_phys_region(void *start, void *end)66{67unsigned long k_start, k_end, k_cur;68void *va;6970if (start >= end)71return;7273k_start = ALIGN_DOWN((unsigned long)kasan_mem_to_shadow(start), PAGE_SIZE);74k_end = ALIGN((unsigned long)kasan_mem_to_shadow(end), PAGE_SIZE);7576va = memblock_alloc_or_panic(k_end - k_start, PAGE_SIZE);77for (k_cur = k_start; k_cur < k_end; k_cur += PAGE_SIZE, va += PAGE_SIZE)78kasan_map_kernel_page(k_cur, __pa(va), PAGE_KERNEL);79}8081void __init kasan_early_init(void)82{83int i;84unsigned long addr;85pgd_t *pgd = pgd_offset_k(KASAN_SHADOW_START);86pte_t zero_pte = pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL);8788BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));89BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));9091for (i = 0; i < PTRS_PER_PTE; i++)92__set_pte_at(&init_mm, (unsigned long)kasan_early_shadow_page,93&kasan_early_shadow_pte[i], zero_pte, 0);9495for (i = 0; i < PTRS_PER_PMD; i++)96pmd_populate_kernel(&init_mm, &kasan_early_shadow_pmd[i],97kasan_early_shadow_pte);9899for (i = 0; i < PTRS_PER_PUD; i++)100pud_populate(&init_mm, &kasan_early_shadow_pud[i],101kasan_early_shadow_pmd);102103for (addr = KASAN_SHADOW_START; addr != KASAN_SHADOW_END; addr += PGDIR_SIZE)104p4d_populate(&init_mm, p4d_offset(pgd++, addr), kasan_early_shadow_pud);105}106107void __init kasan_init(void)108{109phys_addr_t start, end;110u64 i;111pte_t zero_pte = pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL_RO);112113for_each_mem_range(i, &start, &end)114kasan_init_phys_region(phys_to_virt(start), phys_to_virt(end));115116if (IS_ENABLED(CONFIG_KASAN_VMALLOC))117kasan_remove_zero_shadow((void *)VMALLOC_START, VMALLOC_SIZE);118119for (i = 0; i < PTRS_PER_PTE; i++)120__set_pte_at(&init_mm, (unsigned long)kasan_early_shadow_page,121&kasan_early_shadow_pte[i], zero_pte, 0);122123flush_tlb_kernel_range(KASAN_SHADOW_START, KASAN_SHADOW_END);124125memset(kasan_early_shadow_page, 0, PAGE_SIZE);126127/* Enable error messages */128init_task.kasan_depth = 0;129pr_info("KASAN init done\n");130}131132void __init kasan_late_init(void) { }133134135