linux/arch/riscv/include/asm/pgalloc.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Copyright (C) 2009 Chen Liqin <liqin.chen@sunplusct.com>
   4 * Copyright (C) 2012 Regents of the University of California
   5 */
   6
   7#ifndef _ASM_RISCV_PGALLOC_H
   8#define _ASM_RISCV_PGALLOC_H
   9
  10#include <linux/mm.h>
  11#include <asm/tlb.h>
  12
  13#ifdef CONFIG_MMU
  14#include <asm-generic/pgalloc.h>        /* for pte_{alloc,free}_one */
  15
  16static inline void pmd_populate_kernel(struct mm_struct *mm,
  17        pmd_t *pmd, pte_t *pte)
  18{
  19        unsigned long pfn = virt_to_pfn(pte);
  20
  21        set_pmd(pmd, __pmd((pfn << _PAGE_PFN_SHIFT) | _PAGE_TABLE));
  22}
  23
  24static inline void pmd_populate(struct mm_struct *mm,
  25        pmd_t *pmd, pgtable_t pte)
  26{
  27        unsigned long pfn = virt_to_pfn(page_address(pte));
  28
  29        set_pmd(pmd, __pmd((pfn << _PAGE_PFN_SHIFT) | _PAGE_TABLE));
  30}
  31
  32#ifndef __PAGETABLE_PMD_FOLDED
  33static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
  34{
  35        unsigned long pfn = virt_to_pfn(pmd);
  36
  37        set_pud(pud, __pud((pfn << _PAGE_PFN_SHIFT) | _PAGE_TABLE));
  38}
  39#endif /* __PAGETABLE_PMD_FOLDED */
  40
  41#define pmd_pgtable(pmd)        pmd_page(pmd)
  42
  43static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  44{
  45        pgd_t *pgd;
  46
  47        pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
  48        if (likely(pgd != NULL)) {
  49                memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
  50                /* Copy kernel mappings */
  51                memcpy(pgd + USER_PTRS_PER_PGD,
  52                        init_mm.pgd + USER_PTRS_PER_PGD,
  53                        (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
  54        }
  55        return pgd;
  56}
  57
  58static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
  59{
  60        free_page((unsigned long)pgd);
  61}
  62
  63#ifndef __PAGETABLE_PMD_FOLDED
  64
  65static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
  66{
  67        return (pmd_t *)__get_free_page(
  68                GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_ZERO);
  69}
  70
  71static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
  72{
  73        free_page((unsigned long)pmd);
  74}
  75
  76#define __pmd_free_tlb(tlb, pmd, addr)  pmd_free((tlb)->mm, pmd)
  77
  78#endif /* __PAGETABLE_PMD_FOLDED */
  79
  80#define __pte_free_tlb(tlb, pte, buf)   \
  81do {                                    \
  82        pgtable_pte_page_dtor(pte);     \
  83        tlb_remove_page((tlb), pte);    \
  84} while (0)
  85#endif /* CONFIG_MMU */
  86
  87#endif /* _ASM_RISCV_PGALLOC_H */
  88