| #ifndef _X86_VM_H_ | |
| #define _X86_VM_H_ | |
| #include "processor.h" | |
| #include "vmalloc.h" | |
| #include "asm/page.h" | |
| #include "asm/io.h" | |
| #include "asm/bitops.h" | |
| void setup_5level_page_table(void); | |
| struct pte_search { | |
| int level; | |
| pteval_t *pte; | |
| }; | |
| static inline bool found_huge_pte(struct pte_search search) | |
| { | |
| return (search.level == 2 || search.level == 3) && | |
| (*search.pte & PT_PRESENT_MASK) && | |
| (*search.pte & PT_PAGE_SIZE_MASK); | |
| } | |
| static inline bool found_leaf_pte(struct pte_search search) | |
| { | |
| return search.level == 1 || found_huge_pte(search); | |
| } | |
| struct pte_search find_pte_level(pgd_t *cr3, void *virt, | |
| int lowest_level); | |
| pteval_t *get_pte(pgd_t *cr3, void *virt); | |
| pteval_t *get_pte_level(pgd_t *cr3, void *virt, int pte_level); | |
| pteval_t *install_pte(pgd_t *cr3, | |
| int pte_level, | |
| void *virt, | |
| pteval_t pte, | |
| pteval_t *pt_page); | |
| pteval_t *install_large_page(pgd_t *cr3, phys_addr_t phys, void *virt); | |
| void install_pages(pgd_t *cr3, phys_addr_t phys, size_t len, void *virt); | |
| bool any_present_pages(pgd_t *cr3, void *virt, size_t len); | |
| void set_pte_opt_mask(void); | |
| void reset_pte_opt_mask(void); | |
| enum x86_mmu_flags { | |
| X86_MMU_MAP_USER = BIT(0), | |
| X86_MMU_MAP_HUGE = BIT(1), | |
| }; | |
| void __setup_mmu_range(pgd_t *cr3, phys_addr_t start, size_t len, | |
| enum x86_mmu_flags mmu_flags); | |
| static inline void *current_page_table(void) | |
| { | |
| return phys_to_virt(read_cr3()); | |
| } | |
| void split_large_page(unsigned long *ptep, int level); | |
| void force_4k_page(void *addr); | |
| struct vm_vcpu_info { | |
| u64 cr3; | |
| u64 cr4; | |
| u64 cr0; | |
| }; | |
| typedef void (*pte_callback_t)(struct pte_search search, void *va); | |
| void walk_pte(void *virt, size_t len, pte_callback_t callback); | |
| #endif |