diff options
Diffstat (limited to 'arch/parisc/mm/fixmap.c')
-rw-r--r-- | arch/parisc/mm/fixmap.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/parisc/mm/fixmap.c b/arch/parisc/mm/fixmap.c new file mode 100644 index 000000000..cc15d737f --- /dev/null +++ b/arch/parisc/mm/fixmap.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * fixmaps for parisc + * + * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org> + */ + +#include <linux/kprobes.h> +#include <linux/mm.h> +#include <asm/cacheflush.h> +#include <asm/fixmap.h> + +void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys) +{ + unsigned long vaddr = __fix_to_virt(idx); + pgd_t *pgd = pgd_offset_k(vaddr); + p4d_t *p4d = p4d_offset(pgd, vaddr); + pud_t *pud = pud_offset(p4d, vaddr); + pmd_t *pmd = pmd_offset(pud, vaddr); + pte_t *pte; + + if (pmd_none(*pmd)) + pte = pte_alloc_kernel(pmd, vaddr); + + pte = pte_offset_kernel(pmd, vaddr); + set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX)); + flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); +} + +void notrace clear_fixmap(enum fixed_addresses idx) +{ + unsigned long vaddr = __fix_to_virt(idx); + pte_t *pte = virt_to_kpte(vaddr); + + if (WARN_ON(pte_none(*pte))) + return; + + pte_clear(&init_mm, vaddr, pte); + + flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); +} |