1*75969686SWang Kefeng /* SPDX-License-Identifier: GPL-2.0 */ 2*75969686SWang Kefeng 3*75969686SWang Kefeng #ifndef __ASM_ARM_KFENCE_H 4*75969686SWang Kefeng #define __ASM_ARM_KFENCE_H 5*75969686SWang Kefeng 6*75969686SWang Kefeng #include <linux/kfence.h> 7*75969686SWang Kefeng 8*75969686SWang Kefeng #include <asm/pgalloc.h> 9*75969686SWang Kefeng #include <asm/set_memory.h> 10*75969686SWang Kefeng 11*75969686SWang Kefeng static inline int split_pmd_page(pmd_t *pmd, unsigned long addr) 12*75969686SWang Kefeng { 13*75969686SWang Kefeng int i; 14*75969686SWang Kefeng unsigned long pfn = PFN_DOWN(__pa(addr)); 15*75969686SWang Kefeng pte_t *pte = pte_alloc_one_kernel(&init_mm); 16*75969686SWang Kefeng 17*75969686SWang Kefeng if (!pte) 18*75969686SWang Kefeng return -ENOMEM; 19*75969686SWang Kefeng 20*75969686SWang Kefeng for (i = 0; i < PTRS_PER_PTE; i++) 21*75969686SWang Kefeng set_pte_ext(pte + i, pfn_pte(pfn + i, PAGE_KERNEL), 0); 22*75969686SWang Kefeng pmd_populate_kernel(&init_mm, pmd, pte); 23*75969686SWang Kefeng 24*75969686SWang Kefeng flush_tlb_kernel_range(addr, addr + PMD_SIZE); 25*75969686SWang Kefeng return 0; 26*75969686SWang Kefeng } 27*75969686SWang Kefeng 28*75969686SWang Kefeng static inline bool arch_kfence_init_pool(void) 29*75969686SWang Kefeng { 30*75969686SWang Kefeng unsigned long addr; 31*75969686SWang Kefeng pmd_t *pmd; 32*75969686SWang Kefeng 33*75969686SWang Kefeng for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr); 34*75969686SWang Kefeng addr += PAGE_SIZE) { 35*75969686SWang Kefeng pmd = pmd_off_k(addr); 36*75969686SWang Kefeng 37*75969686SWang Kefeng if (pmd_leaf(*pmd)) { 38*75969686SWang Kefeng if (split_pmd_page(pmd, addr & PMD_MASK)) 39*75969686SWang Kefeng return false; 40*75969686SWang Kefeng } 41*75969686SWang Kefeng } 42*75969686SWang Kefeng 43*75969686SWang Kefeng return true; 44*75969686SWang Kefeng } 45*75969686SWang Kefeng 46*75969686SWang Kefeng static inline bool kfence_protect_page(unsigned long addr, bool protect) 47*75969686SWang Kefeng { 48*75969686SWang Kefeng set_memory_valid(addr, 1, !protect); 49*75969686SWang Kefeng 50*75969686SWang Kefeng return true; 51*75969686SWang Kefeng } 52*75969686SWang Kefeng 53*75969686SWang Kefeng #endif /* __ASM_ARM_KFENCE_H */ 54