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.


41d4b6f4d1b366ad08184079f621d20c606895ac
[palacios.git] / palacios / include / palacios / vmm_paging.h
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20
21 #ifndef __VMM_PAGING_H__
22 #define __VMM_PAGING_H__
23
24
25 #ifdef __V3VEE__
26
27 #include <palacios/vmm_types.h>
28 #include <palacios/vmm_util.h>
29
30 /*
31
32 In the following, when we say "page table", we mean the whole 2 or 4 layer
33 page table (PDEs, PTEs), etc.
34
35
36 guest-visible paging state
37  This is the state that the guest thinks the machine is using
38  It consists of
39    - guest physical memory
40        The physical memory addresses the guest is allowed to use
41        (see shadow page maps, below)
42    - guest page tables 
43        (we care about when the current one changes)
44    - guest paging registers (these are never written to hardware)
45         CR0
46         CR3
47
48
49 shadow paging state
50  This the state that the machine will actually use when the guest
51  is running.  It consists of:
52    - current shadow page table
53         This is the page table actually useed when the guest is running.
54         It is changed/regenerated when the guest page table changes
55         It mostly reflects the guest page table, except that it restricts 
56         physical addresses to those the VMM allocates to the guest.
57    - shadow page maps
58         This is a mapping from guest physical memory addresses to
59         the current location of the guest physical memory content.   
60         It maps from regions of physical memory addresses to regions 
61         located in physical memory or elsewhere.  
62         (8192,16384) -> MEM(8912,...)
63         (0,8191) -> DISK(65536,..) 
64    - guest paging registers (these are written to guest state)
65         CR0
66         CR3
67
68 host paging state
69   This is the state we expect to be operative when the VMM is running.
70   Typically, this is set up by the host os into which we have embedded
71   the VMM, but we include the description here for clarity.
72     - current page table
73         This is the page table we use when we are executing in 
74         the VMM (or the host os)
75     - paging regisers
76         CR0
77         CR3
78
79
80 The reason why the shadow paging state and the host paging state are
81 distinct is to permit the guest to use any virtual address it wants,
82 irrespective of the addresses the VMM or the host os use.  These guest
83 virtual addresses are reflected in the shadow paging state.  When we
84 exit from the guest, we switch to the host paging state so that any
85 virtual addresses that overlap between the guest and VMM/host now map
86 to the physical addresses epxected by the VMM/host.  On AMD SVM, this
87 switch is done by the hardware.  On Intel VT, the switch is done
88 by the hardware as well, but we are responsible for manually updating
89 the host state in the vmcs before entering the guest.
90 */
91
92
93
94
95 #define MAX_PTE32_ENTRIES          1024
96 #define MAX_PDE32_ENTRIES          1024
97
98 #define MAX_PTE32PAE_ENTRIES       512
99 #define MAX_PDE32PAE_ENTRIES       512
100 #define MAX_PDPE32PAE_ENTRIES      4
101
102 #define MAX_PTE64_ENTRIES          512
103 #define MAX_PDE64_ENTRIES          512
104 #define MAX_PDPE64_ENTRIES         512
105 #define MAX_PML4E64_ENTRIES        512
106
107
108 /* Converts an address into a page table index */
109 #define PDE32_INDEX(x)  ((((uint_t)x) >> 22) & 0x3ff)
110 #define PTE32_INDEX(x)  ((((uint_t)x) >> 12) & 0x3ff)
111
112
113 /* Gets the base address needed for a Page Table entry */
114 /* Deprecate these :*/
115 #define PD32_BASE_ADDR(x) (((uint_t)x) >> 12)
116 #define PT32_BASE_ADDR(x) (((uint_t)x) >> 12)
117 #define PD32_4MB_BASE_ADDR(x) (((uint_t)x) >> 22)
118
119 #define PML4E64_BASE_ADDR(x) (((ullong_t)x) >> 12)
120 #define PDPE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
121 #define PDE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
122 #define PTE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
123 /* Accessor functions for the page table structures */
124 #define PDE32_T_ADDR(x) (((x).pt_base_addr) << 12)
125 #define PTE32_T_ADDR(x) (((x).page_base_addr) << 12)
126 #define PDE32_4MB_T_ADDR(x) (((x).page_base_addr) << 22)
127
128 /* Replace The above with these... */
129 #define PAGE_BASE_ADDR(x) (((uint_t)x) >> 12)
130 #define LARGE_PAGE_BASE_ADDR(x) (((uint_t)x) >> 22)
131 #define BASE_TO_PAGE_ADDR(x) (((uint_t)x) << 12)
132 #define LARGE_BASE_TO_PAGE_ADDR(x) (((uint_t)x) << 22)
133
134
135
136 #define PT32_PAGE_ADDR(x)   (((uint_t)x) & 0xfffff000)
137 #define PT32_PAGE_OFFSET(x) (((uint_t)x) & 0xfff)
138 #define PT32_PAGE_POWER 12
139
140 #define PD32_4MB_PAGE_ADDR(x) (((uint_t)x) & 0xffc00000)
141 #define PD32_4MB_PAGE_OFFSET(x) (((uint_t)x) & 0x003fffff)
142 #define PAGE_SIZE_4MB (4096 * 1024)
143
144 /* The following should be phased out */
145 #define PAGE_OFFSET(x)  ((((uint_t)x) & 0xfff))
146 #define PAGE_ALIGNED_ADDR(x)   (((uint_t) (x)) >> 12)
147 #define PAGE_ADDR(x)   (PAGE_ALIGNED_ADDR(x) << 12)
148 #define PAGE_POWER 12
149 #define PAGE_SIZE 4096
150 /* ** */
151
152
153
154
155 #define CR3_TO_PDE32(cr3) (V3_VAddr((void *)(((ulong_t)cr3) & 0xfffff000)))
156 #define CR3_TO_PDPTRE(cr3) (V3_VAddr((void *)(((ulong_t)cr3) & 0xffffffe0)))
157 #define CR3_TO_PML4E64(cr3)  (V3_VAddr((void *)(((ullong_t)cr3) & 0x000ffffffffff000LL)))
158
159
160
161
162
163
164 /* Page Table Flag Values */
165 #define PT32_HOOK 0x1
166 #define PT32_GUEST_PT 0x2
167
168
169
170
171 /* PDE 32 bit PAGE STRUCTURES */
172 typedef enum {PDE32_ENTRY_NOT_PRESENT, PDE32_ENTRY_PTE32, PDE32_ENTRY_LARGE_PAGE} pde32_entry_type_t;
173 typedef enum {PT_ACCESS_OK, PT_ENTRY_NOT_PRESENT, PT_WRITE_ERROR, PT_USER_ERROR} pt_access_status_t;
174
175 typedef struct pde32 {
176   uint_t present         : 1;
177   uint_t writable        : 1;
178   uint_t user_page       : 1;
179   uint_t write_through   : 1;
180   uint_t cache_disable   : 1;
181   uint_t accessed        : 1;
182   uint_t reserved        : 1;
183   uint_t large_page     : 1;
184   uint_t global_page     : 1;
185   uint_t vmm_info        : 3;
186   uint_t pt_base_addr    : 20;
187 } __attribute__((packed))  pde32_t;
188
189 typedef struct pde32_4MB {
190   uint_t present         : 1;
191   uint_t writable        : 1;
192   uint_t user_page       : 1;
193   uint_t write_through   : 1;
194   uint_t cache_disable   : 1;
195   uint_t accessed        : 1;
196   uint_t dirty           : 1;
197   uint_t one             : 1;
198   uint_t global_page     : 1;
199   uint_t vmm_info        : 3;
200   uint_t pat             : 1;
201   uint_t rsvd            : 9;
202   uint_t page_base_addr  : 10;
203
204 } __attribute__((packed))  pde32_4MB_t;
205
206 typedef struct pte32 {
207   uint_t present         : 1;
208   uint_t writable        : 1;
209   uint_t user_page       : 1;
210   uint_t write_through   : 1;
211   uint_t cache_disable   : 1;
212   uint_t accessed        : 1;
213   uint_t dirty           : 1;
214   uint_t pte_attr        : 1;
215   uint_t global_page     : 1;
216   uint_t vmm_info        : 3;
217   uint_t page_base_addr  : 20;
218 }  __attribute__((packed)) pte32_t;
219 /* ***** */
220
221 /* 32 bit PAE PAGE STRUCTURES */
222 typedef struct pdpe32pae {
223   uint_t present       : 1;
224   uint_t rsvd          : 2; // MBZ
225   uint_t write_through : 1;
226   uint_t cache_disable : 1;
227   uint_t accessed      : 1; 
228   uint_t avail         : 1;
229   uint_t rsvd2         : 2;  // MBZ
230   uint_t vmm_info      : 3;
231   uint_t pd_base_addr  : 24;
232   uint_t rsvd3         : 28; // MBZ
233 } __attribute__((packed)) pdpe32pae_t;
234
235
236
237 typedef struct pde32pae {
238   uint_t present         : 1;
239   uint_t writable        : 1;
240   uint_t user_page       : 1;
241   uint_t write_through   : 1;
242   uint_t cache_disable   : 1;
243   uint_t accessed        : 1;
244   uint_t avail           : 1;
245   uint_t large_page      : 1;
246   uint_t global_page     : 1;
247   uint_t vmm_info        : 3;
248   uint_t pt_base_addr    : 24;
249   uint_t rsvd            : 28;
250 } __attribute__((packed)) pde32pae_t;
251
252 typedef struct pde32pae_4MB {
253   uint_t present         : 1;
254   uint_t writable        : 1;
255   uint_t user_page       : 1;
256   uint_t write_through   : 1;
257   uint_t cache_disable   : 1;
258   uint_t accessed        : 1;
259   uint_t dirty           : 1;
260   uint_t one             : 1;
261   uint_t global_page     : 1;
262   uint_t vmm_info        : 3;
263   uint_t pat             : 1;
264   uint_t rsvd            : 9;
265   uint_t page_base_addr  : 14;
266   uint_t rsvd2           : 28;
267
268 } __attribute__((packed)) pde32pae_4MB_t;
269
270 typedef struct pte32pae {
271   uint_t present         : 1;
272   uint_t writable        : 1;
273   uint_t user_page       : 1;
274   uint_t write_through   : 1;
275   uint_t cache_disable   : 1;
276   uint_t accessed        : 1;
277   uint_t dirty           : 1;
278   uint_t pte_attr        : 1;
279   uint_t global_page     : 1;
280   uint_t vmm_info        : 3;
281   uint_t page_base_addr  : 24;
282   uint_t rsvd            : 28;
283 } __attribute__((packed)) pte32pae_t;
284
285
286
287
288
289 /* ********** */
290
291
292 /* LONG MODE 64 bit PAGE STRUCTURES */
293 typedef struct pml4e64 {
294   uint_t present        : 1;
295   uint_t writable       : 1;
296   uint_t user_page           : 1;
297   uint_t write_through  : 1;
298   uint_t cache_disable  : 1;
299   uint_t accessed       : 1;
300   uint_t reserved       : 1;
301   uint_t zero           : 2;
302   uint_t vmm_info       : 3;
303   ullong_t pdp_base_addr : 40;
304   uint_t available      : 11;
305   uint_t no_execute     : 1;
306 } __attribute__((packed)) pml4e64_t;
307
308
309 typedef struct pdpe64 {
310   uint_t present        : 1;
311   uint_t writable       : 1;
312   uint_t user_page           : 1;
313   uint_t write_through  : 1;
314   uint_t cache_disable  : 1;
315   uint_t accessed       : 1;
316   uint_t reserved       : 1;
317   uint_t large_page    : 1;
318   uint_t zero           : 1;
319   uint_t vmm_info       : 3;
320   ullong_t pd_base_addr : 40;
321   uint_t available      : 11;
322   uint_t no_execute     : 1;
323 } __attribute__((packed)) pdpe64_t;
324
325
326
327
328 typedef struct pde64 {
329   uint_t present         : 1;
330   uint_t writable        : 1;
331   uint_t user_page       : 1;
332   uint_t write_through   : 1;
333   uint_t cache_disable   : 1;
334   uint_t accessed        : 1;
335   uint_t reserved        : 1;
336   uint_t large_page     : 1;
337   uint_t reserved2       : 1;
338   uint_t vmm_info        : 3;
339   ullong_t pt_base_addr  : 40;
340   uint_t available       : 11;
341   uint_t no_execute      : 1;
342 } __attribute__((packed)) pde64_t;
343
344 typedef struct pte64 {
345   uint_t present         : 1;
346   uint_t writable        : 1;
347   uint_t user_page       : 1;
348   uint_t write_through   : 1;
349   uint_t cache_disable   : 1;
350   uint_t accessed        : 1;
351   uint_t dirty           : 1;
352   uint_t pte_attr        : 1;
353   uint_t global_page     : 1;
354   uint_t vmm_info        : 3;
355   ullong_t page_base_addr : 40;
356   uint_t available       : 11;
357   uint_t no_execute      : 1;
358 } __attribute__((packed)) pte64_t;
359
360 /* *************** */
361
362 typedef struct pf_error_code {
363   uint_t present           : 1; // if 0, fault due to page not present
364   uint_t write             : 1; // if 1, faulting access was a write
365   uint_t user              : 1; // if 1, faulting access was in user mode
366   uint_t rsvd_access       : 1; // if 1, fault from reading a 1 from a reserved field (?)
367   uint_t ifetch            : 1; // if 1, faulting access was an instr fetch (only with NX)
368   uint_t rsvd              : 27;
369 } __attribute__((packed)) pf_error_t;
370
371
372
373
374 void delete_page_tables_pde32(pde32_t * pde);
375
376
377 pde32_entry_type_t pde32_lookup(pde32_t * pd, addr_t addr, addr_t * entry);
378 int pte32_lookup(pte32_t * pte, addr_t addr, addr_t * entry);
379
380 // This assumes that the page table resides in the host address space
381 // IE. IT DOES NO VM ADDR TRANSLATION
382 int pt32_lookup(pde32_t * pd, addr_t vaddr, addr_t * paddr);
383
384
385
386 pt_access_status_t can_access_pde32(pde32_t * pde, addr_t addr, pf_error_t access_type);
387 pt_access_status_t can_access_pte32(pte32_t * pte, addr_t addr, pf_error_t access_type);
388
389
390
391
392
393 struct guest_info;
394
395 pde32_t * create_passthrough_pts_32(struct guest_info * guest_info);
396 pdpe32pae_t * create_passthrough_pts_PAE32(struct guest_info * guest_info);
397 pml4e64_t * create_passthrough_pts_64(struct guest_info * info);
398
399
400
401
402
403 void PrintDebugPageTables(pde32_t * pde);
404
405
406
407
408 void PrintPT32(addr_t starting_address, pte32_t * pte);
409 void PrintPD32(pde32_t * pde);
410 void PrintPTE32(addr_t virtual_address, pte32_t * pte);
411 void PrintPDE32(addr_t virtual_address, pde32_t * pde);
412   
413 void PrintDebugPageTables32PAE(pdpe32pae_t * pde);
414 void PrintPTE32PAE(addr_t virtual_address, pte32pae_t * pte);
415 void PrintPDE32PAE(addr_t virtual_address, pde32pae_t * pde);
416 void PrintPTE64(addr_t virtual_address, pte64_t * pte);
417
418 #endif // !__V3VEE__
419
420
421
422 #endif