blob: dadc2e600f9a232cef944768f4455e5be3520ccc [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* s390x mmu functions
*
* Copyright (c) 2018 IBM Corp
*
* Authors:
* Janosch Frank <frankja@linux.ibm.com>
*/
#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_ */