xref: /kvm-unit-tests/lib/x86/vm.h (revision 4c8a99ca02252d4a2bee43f4558fe47ce5ab7ec0)
1 #ifndef _X86_VM_H_
2 #define _X86_VM_H_
3 
4 #include "processor.h"
5 #include "asm/page.h"
6 #include "asm/io.h"
7 #include "asm/bitops.h"
8 
9 void setup_5level_page_table(void);
10 
11 struct pte_search {
12 	int level;
13 	pteval_t *pte;
14 };
15 
16 static inline bool found_huge_pte(struct pte_search search)
17 {
18 	return (search.level == 2 || search.level == 3) &&
19 	       (*search.pte & PT_PRESENT_MASK) &&
20 	       (*search.pte & PT_PAGE_SIZE_MASK);
21 }
22 
23 static inline bool found_leaf_pte(struct pte_search search)
24 {
25 	return search.level == 1 || found_huge_pte(search);
26 }
27 
28 struct pte_search find_pte_level(pgd_t *cr3, void *virt,
29 				 int lowest_level);
30 pteval_t *get_pte(pgd_t *cr3, void *virt);
31 pteval_t *get_pte_level(pgd_t *cr3, void *virt, int pte_level);
32 pteval_t *install_pte(pgd_t *cr3,
33 		      int pte_level,
34 		      void *virt,
35 		      pteval_t pte,
36 		      pteval_t *pt_page);
37 
38 pteval_t *install_large_page(pgd_t *cr3, phys_addr_t phys, void *virt);
39 void install_pages(pgd_t *cr3, phys_addr_t phys, size_t len, void *virt);
40 bool any_present_pages(pgd_t *cr3, void *virt, size_t len);
41 void set_pte_opt_mask(void);
42 void reset_pte_opt_mask(void);
43 
44 enum x86_mmu_flags {
45 	X86_MMU_MAP_USER	= BIT(0),
46 	X86_MMU_MAP_HUGE	= BIT(1),
47 };
48 void __setup_mmu_range(pgd_t *cr3, phys_addr_t start, size_t len,
49 		       enum x86_mmu_flags mmu_flags);
50 
51 static inline void *current_page_table(void)
52 {
53 	return phys_to_virt(read_cr3());
54 }
55 
56 void split_large_page(unsigned long *ptep, int level);
57 void force_4k_page(void *addr);
58 
59 struct vm_vcpu_info {
60         u64 cr3;
61         u64 cr4;
62         u64 cr0;
63 };
64 
65 typedef void (*pte_callback_t)(struct pte_search search, void *va);
66 void walk_pte(void *virt, size_t len, pte_callback_t callback);
67 
68 #endif
69