xref: /linux/arch/powerpc/include/asm/kfence.h (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
190cbac0eSChristophe Leroy /* SPDX-License-Identifier: GPL-2.0 */
290cbac0eSChristophe Leroy /*
390cbac0eSChristophe Leroy  * powerpc KFENCE support.
490cbac0eSChristophe Leroy  *
590cbac0eSChristophe Leroy  * Copyright (C) 2020 CS GROUP France
690cbac0eSChristophe Leroy  */
790cbac0eSChristophe Leroy 
890cbac0eSChristophe Leroy #ifndef __ASM_POWERPC_KFENCE_H
990cbac0eSChristophe Leroy #define __ASM_POWERPC_KFENCE_H
1090cbac0eSChristophe Leroy 
1190cbac0eSChristophe Leroy #include <linux/mm.h>
1290cbac0eSChristophe Leroy #include <asm/pgtable.h>
1390cbac0eSChristophe Leroy 
14a5edf981SNicholas Miehlbradt #ifdef CONFIG_PPC64_ELF_ABI_V1
15a5edf981SNicholas Miehlbradt #define ARCH_FUNC_PREFIX "."
16a5edf981SNicholas Miehlbradt #endif
17a5edf981SNicholas Miehlbradt 
1890cbac0eSChristophe Leroy extern bool kfence_early_init;
1990cbac0eSChristophe Leroy extern bool kfence_disabled;
2090cbac0eSChristophe Leroy 
disable_kfence(void)2190cbac0eSChristophe Leroy static inline void disable_kfence(void)
2290cbac0eSChristophe Leroy {
23a5edf981SNicholas Miehlbradt 	kfence_disabled = true;
24a5edf981SNicholas Miehlbradt }
25a5edf981SNicholas Miehlbradt 
arch_kfence_init_pool(void)26*58b6fed8SLinus Walleij static inline bool arch_kfence_init_pool(void)
27a5edf981SNicholas Miehlbradt {
28a5edf981SNicholas Miehlbradt 	return !kfence_disabled;
29a5edf981SNicholas Miehlbradt }
30a5edf981SNicholas Miehlbradt 
kfence_early_init_enabled(void)31a5edf981SNicholas Miehlbradt static inline bool kfence_early_init_enabled(void)
32a5edf981SNicholas Miehlbradt {
3390cbac0eSChristophe Leroy 	return IS_ENABLED(CONFIG_KFENCE) && kfence_early_init;
3490cbac0eSChristophe Leroy }
3590cbac0eSChristophe Leroy 
3690cbac0eSChristophe Leroy #ifdef CONFIG_PPC64
kfence_protect_page(unsigned long addr,bool protect)3790cbac0eSChristophe Leroy static inline bool kfence_protect_page(unsigned long addr, bool protect)
3890cbac0eSChristophe Leroy {
3990cbac0eSChristophe Leroy 	struct page *page = virt_to_page((void *)addr);
4090cbac0eSChristophe Leroy 
4190cbac0eSChristophe Leroy 	__kernel_map_pages(page, 1, !protect);
4290cbac0eSChristophe Leroy 
4390cbac0eSChristophe Leroy 	return true;
4490cbac0eSChristophe Leroy }
4590cbac0eSChristophe Leroy #else
kfence_protect_page(unsigned long addr,bool protect)46a5edf981SNicholas Miehlbradt static inline bool kfence_protect_page(unsigned long addr, bool protect)
4790cbac0eSChristophe Leroy {
4890cbac0eSChristophe Leroy 	pte_t *kpte = virt_to_kpte(addr);
49 
50 	if (protect) {
51 		pte_update(&init_mm, addr, kpte, _PAGE_PRESENT, 0, 0);
52 		flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
53 	} else {
54 		pte_update(&init_mm, addr, kpte, 0, _PAGE_PRESENT, 0);
55 	}
56 
57 	return true;
58 }
59 #endif
60 
61 #endif /* __ASM_POWERPC_KFENCE_H */
62