1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
4 #include <linux/init_task.h>
5 #include <asm/pgalloc.h>
7 #define FIRST_KERNEL_PGD_NR (USER_PTRS_PER_PGD)
10 * need to get a page for level 1
13 pgd_t
*pgd_alloc(struct mm_struct
*mm
)
15 pgd_t
*new_pgd
, *init_pgd
;
18 new_pgd
= (pgd_t
*) __get_free_pages(GFP_KERNEL
, 0);
21 for (i
= 0; i
< PTRS_PER_PGD
; i
++) {
25 new_pgd
-= PTRS_PER_PGD
;
27 init_pgd
= pgd_offset_k(0);
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
));
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
),
41 void pgd_free(struct mm_struct
*mm
, pgd_t
* pgd
)
60 dec_zone_page_state(virt_to_page((unsigned long *)pgd
), NR_PAGETABLE
);
65 free_pages((unsigned long)pgd
, 0);
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
73 void setup_mm_for_reboot(char mode
)
82 if (current
->mm
&& current
->mm
->pgd
)
83 pgd
= current
->mm
->pgd
;
87 for (i
= 0; i
< USER_PTRS_PER_PGD
; i
++) {
88 pmdval
= (i
<< PGDIR_SHIFT
);
89 p4d
= p4d_offset(pgd
, i
<< PGDIR_SHIFT
);
90 pud
= pud_offset(p4d
, i
<< PGDIR_SHIFT
);
91 pmd
= pmd_offset(pud
+ i
, i
<< PGDIR_SHIFT
);
92 set_pmd(pmd
, __pmd(pmdval
));