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 86 static inline void protect_page(void *vaddr, unsigned long prot) 87 { 88 protect_dat_entry(vaddr, prot, pgtable_level_pte); 89 } 90 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