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.


added new copyright and license
[palacios-OLD.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 #include <palacios/vmm_types.h>
26 #include <palacios/vmm_util.h>
27
28 /*
29
30 In the following, when we say "page table", we mean the whole 2 or 4 layer
31 page table (PDEs, PTEs), etc.
32
33
34 guest-visible paging state
35  This is the state that the guest thinks the machine is using
36  It consists of
37    - guest physical memory
38        The physical memory addresses the guest is allowed to use
39        (see shadow page maps, below)
40    - guest page tables 
41        (we care about when the current one changes)
42    - guest paging registers (these are never written to hardware)
43         CR0
44         CR3
45
46
47 shadow paging state
48  This the state that the machine will actually use when the guest
49  is running.  It consists of:
50    - current shadow page table
51         This is the page table actually useed when the guest is running.
52         It is changed/regenerated when the guest page table changes
53         It mostly reflects the guest page table, except that it restricts 
54         physical addresses to those the VMM allocates to the guest.
55    - shadow page maps
56         This is a mapping from guest physical memory addresses to
57         the current location of the guest physical memory content.   
58         It maps from regions of physical memory addresses to regions 
59         located in physical memory or elsewhere.  
60         (8192,16384) -> MEM(8912,...)
61         (0,8191) -> DISK(65536,..) 
62    - guest paging registers (these are written to guest state)
63         CR0
64         CR3
65
66 host paging state
67   This is the state we expect to be operative when the VMM is running.
68   Typically, this is set up by the host os into which we have embedded
69   the VMM, but we include the description here for clarity.
70     - current page table
71         This is the page table we use when we are executing in 
72         the VMM (or the host os)
73     - paging regisers
74         CR0
75         CR3
76
77
78 The reason why the shadow paging state and the host paging state are
79 distinct is to permit the guest to use any virtual address it wants,
80 irrespective of the addresses the VMM or the host os use.  These guest
81 virtual addresses are reflected in the shadow paging state.  When we
82 exit from the guest, we switch to the host paging state so that any
83 virtual addresses that overlap between the guest and VMM/host now map
84 to the physical addresses epxected by the VMM/host.  On AMD SVM, this
85 switch is done by the hardware.  On Intel VT, the switch is done
86 by the hardware as well, but we are responsible for manually updating
87 the host state in the vmcs before entering the guest.
88 */
89
90
91 #ifdef __V3VEE__
92
93 #define MAX_PTE32_ENTRIES          1024
94 #define MAX_PDE32_ENTRIES          1024
95
96 #define MAX_PTE64_ENTRIES          512
97 #define MAX_PDE64_ENTRIES          512
98 #define MAX_PDPE64_ENTRIES         512
99 #define MAX_PML4E64_ENTRIES        512
100
101
102 /* Converts an address into a page table index */
103 #define PDE32_INDEX(x)  ((((uint_t)x) >> 22) & 0x3ff)
104 #define PTE32_INDEX(x)  ((((uint_t)x) >> 12) & 0x3ff)
105
106 /* Gets the base address needed for a Page Table entry */
107 #define PD32_BASE_ADDR(x) (((uint_t)x) >> 12)
108 #define PT32_BASE_ADDR(x) (((uint_t)x) >> 12)
109 #define PD32_4MB_BASE_ADDR(x) (((uint_t)x) >> 22)
110
111 #define PT32_PAGE_ADDR(x)   (((uint_t)x) & 0xfffff000)
112 #define PT32_PAGE_OFFSET(x) (((uint_t)x) & 0xfff)
113 #define PT32_PAGE_POWER 12
114
115 #define PD32_4MB_PAGE_ADDR(x) (((uint_t)x) & 0xffc00000)
116 #define PD32_4MB_PAGE_OFFSET(x) (((uint_t)x) & 0x003fffff)
117 #define PAGE_SIZE_4MB (4096 * 1024)
118
119 /* The following should be phased out */
120 #define PAGE_OFFSET(x)  ((((uint_t)x) & 0xfff))
121 #define PAGE_ALIGNED_ADDR(x)   (((uint_t) (x)) >> 12)
122 #define PAGE_ADDR(x)   (PAGE_ALIGNED_ADDR(x) << 12)
123 #define PAGE_POWER 12
124 #define PAGE_SIZE 4096
125 /* ** */
126
127
128
129
130 #define CR3_TO_PDE32(cr3) (((ulong_t)cr3) & 0xfffff000)
131 #define CR3_TO_PDPTRE(cr3) (((ulong_t)cr3) & 0xffffffe0)
132 #define CR3_TO_PML4E64(cr3)  (((ullong_t)cr3) & 0x000ffffffffff000LL)
133
134
135
136
137 /* Accessor functions for the page table structures */
138 #define PDE32_T_ADDR(x) (((x).pt_base_addr) << 12)
139 #define PTE32_T_ADDR(x) (((x).page_base_addr) << 12)
140 #define PDE32_4MB_T_ADDR(x) (((x).page_base_addr) << 22)
141
142 /* Page Table Flag Values */
143 #define PT32_HOOK 0x1
144 #define PT32_GUEST_PT 0x2
145
146
147 #endif
148
149 /* PDE 32 bit PAGE STRUCTURES */
150 typedef enum {PDE32_ENTRY_NOT_PRESENT, PDE32_ENTRY_PTE32, PDE32_ENTRY_LARGE_PAGE} pde32_entry_type_t;
151 typedef enum {PT_ACCESS_OK, PT_ENTRY_NOT_PRESENT, PT_WRITE_ERROR, PT_USER_ERROR} pt_access_status_t;
152
153 typedef struct pde32 {
154   uint_t present         : 1;
155   uint_t writable        : 1;
156   uint_t user_page       : 1;
157   uint_t write_through   : 1;
158   uint_t cache_disable   : 1;
159   uint_t accessed        : 1;
160   uint_t reserved        : 1;
161   uint_t large_page     : 1;
162   uint_t global_page     : 1;
163   uint_t vmm_info        : 3;
164   uint_t pt_base_addr    : 20;
165 } pde32_t;
166
167 typedef struct pde32_4MB {
168   uint_t present         : 1;
169   uint_t writable        : 1;
170   uint_t user_page       : 1;
171   uint_t write_through   : 1;
172   uint_t cache_disable   : 1;
173   uint_t accessed        : 1;
174   uint_t dirty           : 1;
175   uint_t one             : 1;
176   uint_t global_page     : 1;
177   uint_t vmm_info        : 3;
178   uint_t pat             : 1;
179   uint_t rsvd            : 9;
180   uint_t page_base_addr  : 10;
181
182 } pde32_4MB_t;
183
184 typedef struct pte32 {
185   uint_t present         : 1;
186   uint_t writable        : 1;
187   uint_t user_page       : 1;
188   uint_t write_through   : 1;
189   uint_t cache_disable   : 1;
190   uint_t accessed        : 1;
191   uint_t dirty           : 1;
192   uint_t pte_attr        : 1;
193   uint_t global_page     : 1;
194   uint_t vmm_info        : 3;
195   uint_t page_base_addr  : 20;
196 } pte32_t;
197 /* ***** */
198
199 /* 32 bit PAE PAGE STRUCTURES */
200
201 //
202 // Fill in
203 //
204
205 /* ********** */
206
207
208 /* LONG MODE 64 bit PAGE STRUCTURES */
209 typedef struct pml4e64 {
210   uint_t present        : 1;
211   uint_t writable       : 1;
212   uint_t user           : 1;
213   uint_t pwt            : 1;
214   uint_t pcd            : 1;
215   uint_t accessed       : 1;
216   uint_t reserved       : 1;
217   uint_t zero           : 2;
218   uint_t vmm_info       : 3;
219   uint_t pdp_base_addr_lo : 20;
220   uint_t pdp_base_addr_hi : 20;
221   uint_t available      : 11;
222   uint_t no_execute     : 1;
223 } pml4e64_t;
224
225
226 typedef struct pdpe64 {
227   uint_t present        : 1;
228   uint_t writable       : 1;
229   uint_t user           : 1;
230   uint_t pwt            : 1;
231   uint_t pcd            : 1;
232   uint_t accessed       : 1;
233   uint_t reserved       : 1;
234   uint_t large_pages    : 1;
235   uint_t zero           : 1;
236   uint_t vmm_info       : 3;
237   uint_t pd_base_addr_lo : 20;
238   uint_t pd_base_addr_hi : 20;
239   uint_t available      : 11;
240   uint_t no_execute     : 1;
241 } pdpe64_t;
242
243
244
245
246 typedef struct pde64 {
247   uint_t present         : 1;
248   uint_t flags           : 4;
249   uint_t accessed        : 1;
250   uint_t reserved        : 1;
251   uint_t large_pages     : 1;
252   uint_t reserved2       : 1;
253   uint_t vmm_info        : 3;
254   uint_t pt_base_addr_lo    : 20;
255   uint_t pt_base_addr_hi : 20;
256   uint_t available       : 11;
257   uint_t no_execute      : 1;
258 } pde64_t;
259
260 typedef struct pte64 {
261   uint_t present         : 1;
262   uint_t flags           : 4;
263   uint_t accessed        : 1;
264   uint_t dirty           : 1;
265   uint_t pte_attr        : 1;
266   uint_t global_page     : 1;
267   uint_t vmm_info        : 3;
268   uint_t page_base_addr_lo  : 20;
269   uint_t page_base_addr_hi : 20;
270   uint_t available       : 11;
271   uint_t no_execute      : 1;
272 } pte64_t;
273
274 /* *************** */
275
276 typedef struct pf_error_code {
277   uint_t present           : 1; // if 0, fault due to page not present
278   uint_t write             : 1; // if 1, faulting access was a write
279   uint_t user              : 1; // if 1, faulting access was in user mode
280   uint_t rsvd_access       : 1; // if 1, fault from reading a 1 from a reserved field (?)
281   uint_t ifetch            : 1; // if 1, faulting access was an instr fetch (only with NX)
282   uint_t rsvd              : 27;
283 } pf_error_t;
284
285 typedef enum { PDE32 } paging_mode_t;
286
287
288
289
290 void delete_page_tables_pde32(pde32_t * pde);
291
292
293 pde32_entry_type_t pde32_lookup(pde32_t * pd, addr_t addr, addr_t * entry);
294 int pte32_lookup(pte32_t * pte, addr_t addr, addr_t * entry);
295
296 // This assumes that the page table resides in the host address space
297 // IE. IT DOES NO VM ADDR TRANSLATION
298 int pt32_lookup(pde32_t * pd, addr_t vaddr, addr_t * paddr);
299
300
301
302 pt_access_status_t can_access_pde32(pde32_t * pde, addr_t addr, pf_error_t access_type);
303 pt_access_status_t can_access_pte32(pte32_t * pte, addr_t addr, pf_error_t access_type);
304
305
306
307
308
309 struct guest_info;
310
311 pde32_t * create_passthrough_pde32_pts(struct guest_info * guest_info);
312
313
314
315
316
317
318 void PrintDebugPageTables(pde32_t * pde);
319
320
321 #ifdef __V3VEE__
322
323
324 void PrintPT32(addr_t starting_address, pte32_t * pte);
325 void PrintPD32(pde32_t * pde);
326 void PrintPTE32(addr_t virtual_address, pte32_t * pte);
327 void PrintPDE32(addr_t virtual_address, pde32_t * pde);
328
329 #endif // !__V3VEE__
330
331
332
333 #endif