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 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 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