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