Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


f18a4921394c2d0ce5eb4d7d7738939a31570c8f
[palacios.git] / palacios / include / geekos / vmm_paging.h
1 #ifndef __VMM_PAGING_H
2 #define __VMM_PAGING_H
3
4
5 #include <geekos/ktypes.h>
6
7
8
9 #include <geekos/vmm_mem.h>
10 #include <geekos/vmm_util.h>
11
12 /*
13
14 In the following, when we say "page table", we mean the whole 2 or 4 layer
15 page table (PDEs, PTEs), etc.
16
17
18 guest-visible paging state
19  This is the state that the guest thinks the machine is using
20  It consists of
21    - guest physical memory
22        The physical memory addresses the guest is allowed to use
23        (see shadow page maps, below)
24    - guest page tables 
25        (we care about when the current one changes)
26    - guest paging registers (these are never written to hardware)
27         CR0
28         CR3
29
30
31 shadow paging state
32  This the state that the machine will actually use when the guest
33  is running.  It consists of:
34    - current shadow page table
35         This is the page table actually useed when the guest is running.
36         It is changed/regenerated when the guest page table changes
37         It mostly reflects the guest page table, except that it restricts 
38         physical addresses to those the VMM allocates to the guest.
39    - shadow page maps
40         This is a mapping from guest physical memory addresses to
41         the current location of the guest physical memory content.   
42         It maps from regions of physical memory addresses to regions 
43         located in physical memory or elsewhere.  
44         (8192,16384) -> MEM(8912,...)
45         (0,8191) -> DISK(65536,..) 
46    - guest paging registers (these are written to guest state)
47         CR0
48         CR3
49
50 host paging state
51   This is the state we expect to be operative when the VMM is running.
52   Typically, this is set up by the host os into which we have embedded
53   the VMM, but we include the description here for clarity.
54     - current page table
55         This is the page table we use when we are executing in 
56         the VMM (or the host os)
57     - paging regisers
58         CR0
59         CR3
60
61
62 The reason why the shadow paging state and the host paging state are
63 distinct is to permit the guest to use any virtual address it wants,
64 irrespective of the addresses the VMM or the host os use.  These guest
65 virtual addresses are reflected in the shadow paging state.  When we
66 exit from the guest, we switch to the host paging state so that any
67 virtual addresses that overlap between the guest and VMM/host now map
68 to the physical addresses epxected by the VMM/host.  On AMD SVM, this
69 switch is done by the hardware.  On Intel VT, the switch is done
70 by the hardware as well, but we are responsible for manually updating
71 the host state in the vmcs before entering the guest.
72
73
74 */
75
76
77
78
79 #define MAX_PAGE_TABLE_ENTRIES      1024
80 #define MAX_PAGE_DIR_ENTRIES        1024
81
82 #define MAX_PAGE_TABLE_ENTRIES_64      512
83 #define MAX_PAGE_DIR_ENTRIES_64        512
84 #define MAX_PAGE_DIR_PTR_ENTRIES_64    512
85 #define MAX_PAGE_MAP_ENTRIES_64        512
86
87 #define PAGE_DIRECTORY_INDEX(x)  ((((uint_t)x) >> 22) & 0x3ff)
88 #define PAGE_TABLE_INDEX(x)      ((((uint_t)x) >> 12) & 0x3ff)
89 #define PAGE_OFFSET(x)           ((((uint_t)x) & 0xfff))
90
91 #define PAGE_ALIGNED_ADDR(x)   (((uint_t) (x)) >> 12)
92
93 #ifndef PAGE_ADDR
94 #define PAGE_ADDR(x)   (PAGE_ALIGNED_ADDR(x) << 12)
95 #endif
96
97 #define PAGE_POWER 12
98
99 #define CR3_TO_PDE(cr3) (((ulong_t)cr3) & 0xfffff000)
100 #define CR3_TO_PDPTRE(cr3) (((ulong_t)cr3) & 0xffffffe0)
101 #define CR3_TO_PML4E(cr3)  (((ullong_t)cr3) & 0x000ffffffffff000)
102
103 #define VM_WRITE     1
104 #define VM_USER      2
105 #define VM_NOCACHE   8
106 #define VM_READ      0
107 #define VM_EXEC      0
108
109
110 typedef struct pde {
111   uint_t present         : 1;
112   uint_t flags           : 4;
113   uint_t accessed        : 1;
114   uint_t reserved        : 1;
115   uint_t large_pages     : 1;
116   uint_t global_page     : 1;
117   uint_t vmm_info        : 3;
118   uint_t pt_base_addr    : 20;
119 } vmm_pde_t;
120
121 typedef struct pte {
122   uint_t present         : 1;
123   uint_t flags           : 4;
124   uint_t accessed        : 1;
125   uint_t dirty           : 1;
126   uint_t pte_attr        : 1;
127   uint_t global_page     : 1;
128   uint_t vmm_info        : 3;
129   uint_t page_base_addr  : 20;
130 } vmm_pte_t;
131
132
133
134 typedef struct pte64 {
135   uint_t present         : 1;
136   uint_t flags           : 4;
137   uint_t accessed        : 1;
138   uint_t dirty           : 1;
139   uint_t pte_attr        : 1;
140   uint_t global_page     : 1;
141   uint_t vmm_info        : 3;
142   uint_t page_base_addr_lo  : 20;
143   uint_t page_base_addr_hi : 20;
144   uint_t available       : 11;
145   uint_t no_execute      : 1;
146 } pte64_t;
147
148 typedef struct pde64 {
149   uint_t present         : 1;
150   uint_t flags           : 4;
151   uint_t accessed        : 1;
152   uint_t reserved        : 1;
153   uint_t large_pages     : 1;
154   uint_t reserved2       : 1;
155   uint_t vmm_info        : 3;
156   uint_t pt_base_addr_lo    : 20;
157   uint_t pt_base_addr_hi : 20;
158   uint_t available       : 11;
159   uint_t no_execute      : 1;
160 } pde64_t;
161
162 typedef struct pdpe64 {
163   uint_t present        : 1;
164   uint_t writable       : 1;
165   uint_t user           : 1;
166   uint_t pwt            : 1;
167   uint_t pcd            : 1;
168   uint_t accessed       : 1;
169   uint_t reserved       : 1;
170   uint_t large_pages    : 1;
171   uint_t zero           : 1;
172   uint_t vmm_info       : 3;
173   uint_t pd_base_addr_lo : 20;
174   uint_t pd_base_addr_hi : 20;
175   uint_t available      : 11;
176   uint_t no_execute     : 1;
177 } pdpe64_t;
178
179
180 typedef struct pml4e {
181   uint_t present        : 1;
182   uint_t writable       : 1;
183   uint_t user           : 1;
184   uint_t pwt            : 1;
185   uint_t pcd            : 1;
186   uint_t accessed       : 1;
187   uint_t reserved       : 1;
188   uint_t zero           : 2;
189   uint_t vmm_info       : 3;
190   uint_t pdp_base_addr_lo : 20;
191   uint_t pdp_base_addr_hi : 20;
192   uint_t available      : 11;
193   uint_t no_execute     : 1;
194 } pml4e64_t;
195
196
197
198 typedef enum { PDE32 } paging_mode_t;
199
200
201 typedef struct shadow_page_state {
202
203   // these two reflect the top-level page directory
204   // of the guest page table
205   paging_mode_t           guest_mode;
206   reg_ex_t                guest_cr3;         // points to guest's current page table
207
208   // Should thi sbe here
209   reg_ex_t                guest_cr0;
210
211   // these two reflect the top-level page directory 
212   // the shadow page table
213   paging_mode_t           shadow_mode;
214   reg_ex_t                shadow_cr3;
215
216
217 } shadow_page_state_t;
218
219
220
221 int init_shadow_page_state(shadow_page_state_t * state);
222
223 // This function will cause the shadow page table to be deleted
224 // and rewritten to reflect the guest page table and the shadow map
225 int wholesale_update_shadow_page_state(shadow_page_state_t * state, shadow_map_t * mem_map);
226
227 vmm_pde_t * create_passthrough_pde32_pts(shadow_map_t * map);
228
229 //void free_guest_page_tables(vmm_pde_t * pde);
230
231 void PrintDebugPageTables(vmm_pde_t * pde);
232
233
234 #endif