blob: 4b714bad7403531bca7d6d00889e2c612b40add8 [file] [log] [blame]
#ifndef _X86_VM_H_
#define _X86_VM_H_
#include "processor.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