1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
4 #include <linux/init_task.h>
6 #define __HAVE_ARCH_PGD_FREE
7 #include <asm/pgalloc.h>
9 #define FIRST_KERNEL_PGD_NR (USER_PTRS_PER_PGD)
12 * need to get a page for level 1
15 pgd_t
*pgd_alloc(struct mm_struct
*mm
)
17 pgd_t
*new_pgd
, *init_pgd
;
20 new_pgd
= (pgd_t
*) __get_free_pages(GFP_KERNEL
, 0);
23 for (i
= 0; i
< PTRS_PER_PGD
; i
++) {
27 new_pgd
-= PTRS_PER_PGD
;
29 init_pgd
= pgd_offset_k(0);
31 memcpy(new_pgd
+ FIRST_KERNEL_PGD_NR
, init_pgd
+ FIRST_KERNEL_PGD_NR
,
32 (PTRS_PER_PGD
- FIRST_KERNEL_PGD_NR
) * sizeof(pgd_t
));
34 cpu_dcache_wb_range((unsigned long)new_pgd
,
35 (unsigned long)new_pgd
+
36 PTRS_PER_PGD
* sizeof(pgd_t
));
37 inc_lruvec_page_state(virt_to_page((unsigned long *)new_pgd
),
43 void pgd_free(struct mm_struct
*mm
, pgd_t
* pgd
)
62 dec_lruvec_page_state(virt_to_page((unsigned long *)pgd
), NR_PAGETABLE
);
67 free_pages((unsigned long)pgd
, 0);
71 * In order to soft-boot, we need to insert a 1:1 mapping in place of
72 * the user-mode pages. This will then ensure that we have predictable
73 * results when turning the mmu off
75 void setup_mm_for_reboot(char mode
)
84 if (current
->mm
&& current
->mm
->pgd
)
85 pgd
= current
->mm
->pgd
;
89 for (i
= 0; i
< USER_PTRS_PER_PGD
; i
++) {
90 pmdval
= (i
<< PGDIR_SHIFT
);
91 p4d
= p4d_offset(pgd
, i
<< PGDIR_SHIFT
);
92 pud
= pud_offset(p4d
, i
<< PGDIR_SHIFT
);
93 pmd
= pmd_offset(pud
+ i
, i
<< PGDIR_SHIFT
);
94 set_pmd(pmd
, __pmd(pmdval
));