[PATCH] arm64: remove page granularity limitation from KFENCE
Alexander Potapenko
glider at google.com
Sat Sep 18 04:50:47 PDT 2021
On Sat, Sep 18, 2021 at 10:10 AM Liu Shixin <liushixin2 at huawei.com> wrote:
>
> Currently if KFENCE is enabled in arm64, the entire linear map will be
> mapped at page granularity which seems overkilled. Actually only the
> kfence pool requires to be mapped at page granularity. We can remove the
> restriction from KFENCE and force the linear mapping of the kfence pool
> at page granularity later in arch_kfence_init_pool().
There was a previous patch by Jisheng Zhang intended to remove this
requirement: https://lore.kernel.org/linux-arm-kernel/20210524180656.395e45f6@xhacker.debian/
Which of the two is more preferable?
> Signed-off-by: Liu Shixin <liushixin2 at huawei.com>
> ---
> arch/arm64/include/asm/kfence.h | 69 ++++++++++++++++++++++++++++++++-
> arch/arm64/mm/mmu.c | 4 +-
> 2 files changed, 70 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kfence.h b/arch/arm64/include/asm/kfence.h
> index aa855c6a0ae6..bee101eced0b 100644
> --- a/arch/arm64/include/asm/kfence.h
> +++ b/arch/arm64/include/asm/kfence.h
> @@ -8,9 +8,76 @@
> #ifndef __ASM_KFENCE_H
> #define __ASM_KFENCE_H
>
> +#include <linux/kfence.h>
> #include <asm/set_memory.h>
> +#include <asm/pgalloc.h>
>
> -static inline bool arch_kfence_init_pool(void) { return true; }
> +static inline int split_pud_page(pud_t *pud, unsigned long addr)
> +{
> + int i;
> + pmd_t *pmd = pmd_alloc_one(&init_mm, addr);
> + unsigned long pfn = PFN_DOWN(__pa(addr));
> +
> + if (!pmd)
> + return -ENOMEM;
> +
> + for (i = 0; i < PTRS_PER_PMD; i++)
> + set_pmd(pmd + i, pmd_mkhuge(pfn_pmd(pfn + i * PTRS_PER_PTE, PAGE_KERNEL)));
> +
> + smp_wmb(); /* See comment in __pte_alloc */
> + pud_populate(&init_mm, pud, pmd);
> + flush_tlb_kernel_range(addr, addr + PUD_SIZE);
> + return 0;
> +}
> +
> +static inline int split_pmd_page(pmd_t *pmd, unsigned long addr)
> +{
> + int i;
> + pte_t *pte = pte_alloc_one_kernel(&init_mm);
> + unsigned long pfn = PFN_DOWN(__pa(addr));
> +
> + if (!pte)
> + return -ENOMEM;
> +
> + for (i = 0; i < PTRS_PER_PTE; i++)
> + set_pte(pte + i, pfn_pte(pfn + i, PAGE_KERNEL));
> +
> + smp_wmb(); /* See comment in __pte_alloc */
> + pmd_populate_kernel(&init_mm, pmd, pte);
> +
> + flush_tlb_kernel_range(addr, addr + PMD_SIZE);
> + return 0;
> +}
> +
> +static inline bool arch_kfence_init_pool(void)
> +{
> + unsigned long addr;
> + pgd_t *pgd;
> + p4d_t *p4d;
> + pud_t *pud;
> + pmd_t *pmd;
> +
> + for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr);
> + addr += PAGE_SIZE) {
> + pgd = pgd_offset(&init_mm, addr);
> + if (pgd_leaf(*pgd))
> + return false;
> + p4d = p4d_offset(pgd, addr);
> + if (p4d_leaf(*p4d))
> + return false;
> + pud = pud_offset(p4d, addr);
> + if (pud_leaf(*pud)) {
> + if (split_pud_page(pud, addr & PUD_MASK))
> + return false;
> + }
> + pmd = pmd_offset(pud, addr);
> + if (pmd_leaf(*pmd)) {
> + if (split_pmd_page(pmd, addr & PMD_MASK))
> + return false;
> + }
> + }
> + return true;
> +}
>
> static inline bool kfence_protect_page(unsigned long addr, bool protect)
> {
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index cfd9deb347c3..b2c79ccfb1c5 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -516,7 +516,7 @@ static void __init map_mem(pgd_t *pgdp)
> */
> BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end));
>
> - if (can_set_direct_map() || crash_mem_map || IS_ENABLED(CONFIG_KFENCE))
> + if (can_set_direct_map() || crash_mem_map)
> flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
>
> /*
> @@ -1485,7 +1485,7 @@ int arch_add_memory(int nid, u64 start, u64 size,
> * KFENCE requires linear map to be mapped at page granularity, so that
> * it is possible to protect/unprotect single pages in the KFENCE pool.
> */
> - if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE))
> + if (can_set_direct_map())
> flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
>
> __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
> --
> 2.18.0.huawei.25
>
> --
> You received this message because you are subscribed to the Google Groups "kasan-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to kasan-dev+unsubscribe at googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/kasan-dev/20210918083849.2696287-1-liushixin2%40huawei.com.
--
Alexander Potapenko
Software Engineer
Google Germany GmbH
Erika-Mann-Straße, 33
80636 München
Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
More information about the linux-arm-kernel
mailing list