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
split_pmd_page(pmd_t * pmd,unsigned long addr)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
arch_kfence_init_pool(void)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
kfence_protect_page(unsigned long addr,bool protect)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