root/arch/nds32/mm/mm-nds32.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pgd_alloc
  2. pgd_free
  3. setup_mm_for_reboot

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (C) 2005-2017 Andes Technology Corporation
   3 
   4 #include <linux/init_task.h>
   5 #include <asm/pgalloc.h>
   6 
   7 #define FIRST_KERNEL_PGD_NR     (USER_PTRS_PER_PGD)
   8 
   9 /*
  10  * need to get a page for level 1
  11  */
  12 
  13 pgd_t *pgd_alloc(struct mm_struct *mm)
  14 {
  15         pgd_t *new_pgd, *init_pgd;
  16         int i;
  17 
  18         new_pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, 0);
  19         if (!new_pgd)
  20                 return NULL;
  21         for (i = 0; i < PTRS_PER_PGD; i++) {
  22                 (*new_pgd) = 1;
  23                 new_pgd++;
  24         }
  25         new_pgd -= PTRS_PER_PGD;
  26 
  27         init_pgd = pgd_offset_k(0);
  28 
  29         memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
  30                (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
  31 
  32         cpu_dcache_wb_range((unsigned long)new_pgd,
  33                             (unsigned long)new_pgd +
  34                             PTRS_PER_PGD * sizeof(pgd_t));
  35         inc_zone_page_state(virt_to_page((unsigned long *)new_pgd),
  36                             NR_PAGETABLE);
  37 
  38         return new_pgd;
  39 }
  40 
  41 void pgd_free(struct mm_struct *mm, pgd_t * pgd)
  42 {
  43         pmd_t *pmd;
  44         struct page *pte;
  45 
  46         if (!pgd)
  47                 return;
  48 
  49         pmd = (pmd_t *) pgd;
  50         if (pmd_none(*pmd))
  51                 goto free;
  52         if (pmd_bad(*pmd)) {
  53                 pmd_ERROR(*pmd);
  54                 pmd_clear(pmd);
  55                 goto free;
  56         }
  57 
  58         pte = pmd_page(*pmd);
  59         pmd_clear(pmd);
  60         dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
  61         pte_free(mm, pte);
  62         mm_dec_nr_ptes(mm);
  63         pmd_free(mm, pmd);
  64 free:
  65         free_pages((unsigned long)pgd, 0);
  66 }
  67 
  68 /*
  69  * In order to soft-boot, we need to insert a 1:1 mapping in place of
  70  * the user-mode pages.  This will then ensure that we have predictable
  71  * results when turning the mmu off
  72  */
  73 void setup_mm_for_reboot(char mode)
  74 {
  75         unsigned long pmdval;
  76         pgd_t *pgd;
  77         pmd_t *pmd;
  78         int i;
  79 
  80         if (current->mm && current->mm->pgd)
  81                 pgd = current->mm->pgd;
  82         else
  83                 pgd = init_mm.pgd;
  84 
  85         for (i = 0; i < USER_PTRS_PER_PGD; i++) {
  86                 pmdval = (i << PGDIR_SHIFT);
  87                 pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
  88                 set_pmd(pmd, __pmd(pmdval));
  89         }
  90 }

/* [<][>][^][v][top][bottom][index][help] */