/* SPDX-License-Identifier: GPL-2.0-only */ /* * s390x mmu functions * * Copyright (c) 2018 IBM Corp * * Authors: * Janosch Frank */ #ifndef _S390X_MMU_H_ #define _S390X_MMU_H_ enum pgt_level { pgtable_level_pgd = 1, pgtable_level_p4d, pgtable_level_pud, pgtable_level_pmd, pgtable_level_pte, }; /* * Splits the pagetables down to the given DAT tables level. * Returns a pointer to the DAT table entry of the given level. * @pgtable root of the page table tree * @vaddr address whose page tables are to split * @level 3 (for 2GB pud), 4 (for 1 MB pmd) or 5 (for 4KB pages) */ void *split_page(pgd_t *pgtable, void *vaddr, enum pgt_level level); /* * Applies the given protection bits to the given DAT tables level, * splitting if necessary. * @pgtable root of the page table tree * @vaddr address whose protection bits are to be changed * @prot the protection bits to set * @level 3 (for 2GB pud), 4 (for 1MB pmd) or 5 (for 4KB pages) */ void protect_dat_entry(void *vaddr, unsigned long prot, enum pgt_level level); /* * Clears the given protection bits from the given DAT tables level, * splitting if necessary. * @pgtable root of the page table tree * @vaddr address whose protection bits are to be changed * @prot the protection bits to clear * @level 3 (for 2GB pud), 4 (for 1MB pmd) or 5 (for 4kB pages) */ void unprotect_dat_entry(void *vaddr, unsigned long prot, enum pgt_level level); /* * Applies the given protection bits to the given 4kB pages range, * splitting if necessary. * @start starting address whose protection bits are to be changed * @len size in bytes * @prot the protection bits to set */ void protect_range(void *start, unsigned long len, unsigned long prot); /* * Clears the given protection bits from the given 4kB pages range, * splitting if necessary. * @start starting address whose protection bits are to be changed * @len size in bytes * @prot the protection bits to set */ void unprotect_range(void *start, unsigned long len, unsigned long prot); /* Similar to install_page, maps the virtual address to the physical address * for the given page tables, using 1MB large pages. * Returns a pointer to the DAT table entry. * @pgtable root of the page table tree * @phys physical address to map, must be 1MB aligned! * @vaddr virtual address to map, must be 1MB aligned! */ pmdval_t *install_large_page(pgd_t *pgtable, phys_addr_t phys, void *vaddr); /* Similar to install_page, maps the virtual address to the physical address * for the given page tables, using 2GB huge pages. * Returns a pointer to the DAT table entry. * @pgtable root of the page table tree * @phys physical address to map, must be 2GB aligned! * @vaddr virtual address to map, must be 2GB aligned! */ pudval_t *install_huge_page(pgd_t *pgtable, phys_addr_t phys, void *vaddr); static inline void protect_page(void *vaddr, unsigned long prot) { protect_dat_entry(vaddr, prot, pgtable_level_pte); } static inline void unprotect_page(void *vaddr, unsigned long prot) { unprotect_dat_entry(vaddr, prot, pgtable_level_pte); } void *get_dat_entry(pgd_t *pgtable, void *vaddr, enum pgt_level level); #endif /* _ASMS390X_MMU_H_ */