1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * s390x mmu functions
4 *
5 * Copyright (c) 2018 IBM Corp
6 *
7 * Authors:
8 * Janosch Frank <frankja@linux.ibm.com>
9 */
10 #ifndef _S390X_MMU_H_
11 #define _S390X_MMU_H_
12
13 enum pgt_level {
14 pgtable_level_pgd = 1,
15 pgtable_level_p4d,
16 pgtable_level_pud,
17 pgtable_level_pmd,
18 pgtable_level_pte,
19 };
20
21 /*
22 * Splits the pagetables down to the given DAT tables level.
23 * Returns a pointer to the DAT table entry of the given level.
24 * @pgtable root of the page table tree
25 * @vaddr address whose page tables are to split
26 * @level 3 (for 2GB pud), 4 (for 1 MB pmd) or 5 (for 4KB pages)
27 */
28 void *split_page(pgd_t *pgtable, void *vaddr, enum pgt_level level);
29
30 /*
31 * Applies the given protection bits to the given DAT tables level,
32 * splitting if necessary.
33 * @pgtable root of the page table tree
34 * @vaddr address whose protection bits are to be changed
35 * @prot the protection bits to set
36 * @level 3 (for 2GB pud), 4 (for 1MB pmd) or 5 (for 4KB pages)
37 */
38 void protect_dat_entry(void *vaddr, unsigned long prot, enum pgt_level level);
39
40 /*
41 * Clears the given protection bits from the given DAT tables level,
42 * splitting if necessary.
43 * @pgtable root of the page table tree
44 * @vaddr address whose protection bits are to be changed
45 * @prot the protection bits to clear
46 * @level 3 (for 2GB pud), 4 (for 1MB pmd) or 5 (for 4kB pages)
47 */
48 void unprotect_dat_entry(void *vaddr, unsigned long prot, enum pgt_level level);
49
50 /*
51 * Applies the given protection bits to the given 4kB pages range,
52 * splitting if necessary.
53 * @start starting address whose protection bits are to be changed
54 * @len size in bytes
55 * @prot the protection bits to set
56 */
57 void protect_range(void *start, unsigned long len, unsigned long prot);
58
59 /*
60 * Clears the given protection bits from the given 4kB pages range,
61 * splitting if necessary.
62 * @start starting address whose protection bits are to be changed
63 * @len size in bytes
64 * @prot the protection bits to set
65 */
66 void unprotect_range(void *start, unsigned long len, unsigned long prot);
67
68 /* Similar to install_page, maps the virtual address to the physical address
69 * for the given page tables, using 1MB large pages.
70 * Returns a pointer to the DAT table entry.
71 * @pgtable root of the page table tree
72 * @phys physical address to map, must be 1MB aligned!
73 * @vaddr virtual address to map, must be 1MB aligned!
74 */
75 pmdval_t *install_large_page(pgd_t *pgtable, phys_addr_t phys, void *vaddr);
76
77 /* Similar to install_page, maps the virtual address to the physical address
78 * for the given page tables, using 2GB huge pages.
79 * Returns a pointer to the DAT table entry.
80 * @pgtable root of the page table tree
81 * @phys physical address to map, must be 2GB aligned!
82 * @vaddr virtual address to map, must be 2GB aligned!
83 */
84 pudval_t *install_huge_page(pgd_t *pgtable, phys_addr_t phys, void *vaddr);
85
protect_page(void * vaddr,unsigned long prot)86 static inline void protect_page(void *vaddr, unsigned long prot)
87 {
88 protect_dat_entry(vaddr, prot, pgtable_level_pte);
89 }
90
unprotect_page(void * vaddr,unsigned long prot)91 static inline void unprotect_page(void *vaddr, unsigned long prot)
92 {
93 unprotect_dat_entry(vaddr, prot, pgtable_level_pte);
94 }
95
96 void *get_dat_entry(pgd_t *pgtable, void *vaddr, enum pgt_level level);
97
98 #endif /* _ASMS390X_MMU_H_ */
99