File Index
Files and directories
Sign in
FILE

pgtable.c

File preview with syntax highlighting.

linux-6.19.14/arch/loongarch/mm/pgtable.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4 */
  5#include <linux/init.h>
  6#include <linux/export.h>
  7#include <linux/mm.h>
  8#include <asm/pgalloc.h>
  9#include <asm/pgtable.h>
 10#include <asm/tlbflush.h>
 11
 12struct page *dmw_virt_to_page(unsigned long kaddr)
 13{
 14	return phys_to_page(__pa(kaddr));
 15}
 16EXPORT_SYMBOL(dmw_virt_to_page);
 17
 18struct page *tlb_virt_to_page(unsigned long kaddr)
 19{
 20	return phys_to_page(pfn_to_phys(pte_pfn(*virt_to_kpte(kaddr))));
 21}
 22EXPORT_SYMBOL(tlb_virt_to_page);
 23
 24pgd_t *pgd_alloc(struct mm_struct *mm)
 25{
 26	pgd_t *init, *ret;
 27
 28	ret = __pgd_alloc(mm, 0);
 29	if (ret) {
 30		init = pgd_offset(&init_mm, 0UL);
 31		pgd_init(ret);
 32		memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
 33		       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
 34	}
 35
 36	return ret;
 37}
 38EXPORT_SYMBOL_GPL(pgd_alloc);
 39
 40void pgd_init(void *addr)
 41{
 42	unsigned long *p, *end;
 43	unsigned long entry;
 44
 45#if !defined(__PAGETABLE_PUD_FOLDED)
 46	entry = (unsigned long)invalid_pud_table;
 47#elif !defined(__PAGETABLE_PMD_FOLDED)
 48	entry = (unsigned long)invalid_pmd_table;
 49#else
 50	entry = (unsigned long)invalid_pte_table;
 51#endif
 52
 53	p = (unsigned long *)addr;
 54	end = p + PTRS_PER_PGD;
 55
 56	do {
 57		p[0] = entry;
 58		p[1] = entry;
 59		p[2] = entry;
 60		p[3] = entry;
 61		p[4] = entry;
 62		p += 8;
 63		p[-3] = entry;
 64		p[-2] = entry;
 65		p[-1] = entry;
 66	} while (p != end);
 67}
 68EXPORT_SYMBOL_GPL(pgd_init);
 69
 70#ifndef __PAGETABLE_PMD_FOLDED
 71void pmd_init(void *addr)
 72{
 73	unsigned long *p, *end;
 74	unsigned long pagetable = (unsigned long)invalid_pte_table;
 75
 76	p = (unsigned long *)addr;
 77	end = p + PTRS_PER_PMD;
 78
 79	do {
 80		p[0] = pagetable;
 81		p[1] = pagetable;
 82		p[2] = pagetable;
 83		p[3] = pagetable;
 84		p[4] = pagetable;
 85		p += 8;
 86		p[-3] = pagetable;
 87		p[-2] = pagetable;
 88		p[-1] = pagetable;
 89	} while (p != end);
 90}
 91EXPORT_SYMBOL_GPL(pmd_init);
 92#endif
 93
 94#ifndef __PAGETABLE_PUD_FOLDED
 95void pud_init(void *addr)
 96{
 97	unsigned long *p, *end;
 98	unsigned long pagetable = (unsigned long)invalid_pmd_table;
 99
100	p = (unsigned long *)addr;
101	end = p + PTRS_PER_PUD;
102
103	do {
104		p[0] = pagetable;
105		p[1] = pagetable;
106		p[2] = pagetable;
107		p[3] = pagetable;
108		p[4] = pagetable;
109		p += 8;
110		p[-3] = pagetable;
111		p[-2] = pagetable;
112		p[-1] = pagetable;
113	} while (p != end);
114}
115EXPORT_SYMBOL_GPL(pud_init);
116#endif
117
118void kernel_pte_init(void *addr)
119{
120	unsigned long *p, *end;
121
122	p = (unsigned long *)addr;
123	end = p + PTRS_PER_PTE;
124
125	do {
126		p[0] = _PAGE_GLOBAL;
127		p[1] = _PAGE_GLOBAL;
128		p[2] = _PAGE_GLOBAL;
129		p[3] = _PAGE_GLOBAL;
130		p[4] = _PAGE_GLOBAL;
131		p += 8;
132		p[-3] = _PAGE_GLOBAL;
133		p[-2] = _PAGE_GLOBAL;
134		p[-1] = _PAGE_GLOBAL;
135	} while (p != end);
136}
137
138void set_pmd_at(struct mm_struct *mm, unsigned long addr,
139		pmd_t *pmdp, pmd_t pmd)
140{
141	WRITE_ONCE(*pmdp, pmd);
142	flush_tlb_all();
143}
144
145void __init pagetable_init(void)
146{
147	/* Initialize the entire pgd.  */
148	pgd_init(swapper_pg_dir);
149	pgd_init(invalid_pg_dir);
150#ifndef __PAGETABLE_PUD_FOLDED
151	pud_init(invalid_pud_table);
152#endif
153#ifndef __PAGETABLE_PMD_FOLDED
154	pmd_init(invalid_pmd_table);
155#endif
156}
~/ Read-only file preview.