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 the translation functions to the header file
[palacios.git] / palacios / src / palacios / vmm_paging.c
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 #include <palacios/vmm_paging.h>
21
22 #include <palacios/vmm.h>
23
24 #include <palacios/vm_guest_mem.h>
25
26
27
28 #define USE_VMM_PAGING_DEBUG
29 // All of the debug functions defined in vmm_paging.h are implemented in this file
30 #include "vmm_paging_debug.h"
31 #undef USE_VMM_PAGING_DEBUG
32
33
34 void delete_page_tables_32(pde32_t * pde) {
35   int i;
36
37   if (pde == NULL) { 
38     return;
39   }
40
41   for (i = 0; (i < MAX_PDE32_ENTRIES); i++) {
42     if (pde[i].present) {
43       // We double cast, first to an addr_t to handle 64 bit issues, then to the pointer
44       PrintDebug("PTE base addr %x \n", pde[i].pt_base_addr);
45       pte32_t * pte = (pte32_t *)((addr_t)(uint_t)(pde[i].pt_base_addr << PAGE_POWER));
46
47       PrintDebug("Deleting PTE %d (%p)\n", i, pte);
48       V3_FreePage(pte);
49     }
50   }
51
52   PrintDebug("Deleting PDE (%p)\n", pde);
53   V3_FreePage(V3_PAddr(pde));
54 }
55
56 void delete_page_tables_32PAE(pdpe32pae_t * pdpe) { 
57   PrintError("Unimplemented function\n");
58 }
59
60 void delete_page_tables_64(pml4e64_t * pml4) {
61   PrintError("Unimplemented function\n");
62 }
63
64
65 int v3_translate_guest_pt_32(struct guest_info * info, addr_t guest_cr3, addr_t vaddr, addr_t * paddr) {
66   addr_t guest_pde_pa = CR3_TO_PDE32_PA(guest_cr3);
67   pde32_t * guest_pde = 0;
68   addr_t guest_pte_pa = 0;
69
70   if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t*)&guest_pde) == -1) {
71     PrintError("Could not get virtual address of Guest PDE32 (PA=%p)\n", 
72                (void *)guest_pde_pa);
73     return -1;
74   }
75   
76   switch (pde32_lookup(guest_pde, vaddr, &guest_pte_pa)) {
77   case PT_ENTRY_NOT_PRESENT:
78     *paddr = 0;  
79     return -1;
80   case PT_ENTRY_LARGE_PAGE:
81     *paddr = guest_pte_pa;
82     return 0;
83   case PT_ENTRY_PAGE:
84     {
85       pte32_t * guest_pte = NULL;
86
87       if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t*)&guest_pte) == -1) {
88         PrintError("Could not get virtual address of Guest PTE32 (PA=%p)\n", 
89                    (void *)guest_pte_pa);
90         return -1;
91       }
92
93       if (pte32_lookup(guest_pte, vaddr, paddr) == PT_ENTRY_NOT_PRESENT) {
94         return -1;
95       }
96
97       return 0;
98     }
99   }
100
101   return 0;
102 }
103
104
105 int v3_translate_guest_pt_32pae(struct guest_info * info, addr_t guest_cr3, addr_t vaddr, addr_t * paddr) {
106   addr_t guest_pdpe_pa = CR3_TO_PDPE32PAE_PA(guest_cr3);
107   pdpe32pae_t * guest_pdpe = 0;
108   addr_t guest_pde_pa = 0;
109
110   if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t*)&guest_pdpe) == -1) {
111     PrintError("Could not get virtual address of Guest PDPE32PAE (PA=%p)\n",
112                (void *)guest_pdpe_pa);
113     return -1;
114   }
115
116   switch (pdpe32pae_lookup(guest_pdpe, vaddr, &guest_pde_pa)) 
117     {
118     case PT_ENTRY_NOT_PRESENT:
119       *paddr = 0;
120       return -1;
121     case PT_ENTRY_PAGE:
122       {
123         pde32pae_t * guest_pde = NULL;
124         addr_t guest_pte_pa = 0;
125         
126         if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
127           PrintError("Could not get virtual Address of Guest PDE32PAE (PA=%p)\n", 
128                      (void *)guest_pde_pa);
129           return -1;
130         }
131         
132         switch (pde32pae_lookup(guest_pde, vaddr, &guest_pte_pa)) 
133           {
134           case PT_ENTRY_NOT_PRESENT:
135             *paddr = 0;
136             return -1;
137           case PT_ENTRY_LARGE_PAGE:
138             *paddr = guest_pte_pa;
139             return 0;
140           case PT_ENTRY_PAGE:
141             {
142               pte32pae_t * guest_pte = NULL;
143               
144               if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t *)&guest_pte) == -1) {
145                 PrintError("Could not get virtual Address of Guest PTE32PAE (PA=%p)\n", 
146                            (void *)guest_pte_pa);
147                 return -1;
148               }
149
150               if (pte32pae_lookup(guest_pte, vaddr, paddr) == PT_ENTRY_NOT_PRESENT) {
151                 return -1;
152               }
153
154               return 0;
155             }
156           }
157       }
158     default:
159       return -1;
160     }
161
162   return 0;
163 }
164
165 int v3_translate_guest_pt_64(struct guest_info * info, addr_t guest_cr3, addr_t vaddr, addr_t * paddr) {
166   addr_t guest_pml4_pa = CR3_TO_PML4E64_PA(guest_cr3);
167   pml4e64_t * guest_pml = 0;
168   addr_t guest_pdpe_pa = 0;
169
170   if (guest_pa_to_host_va(info, guest_pml4_pa, (addr_t*)&guest_pml) == -1) {
171     PrintError("Could not get virtual address of Guest PML4E64 (PA=%p)\n", 
172                (void *)guest_pml4_pa);
173     return -1;
174   }
175   
176   switch (pml4e64_lookup(guest_pml, vaddr, &guest_pdpe_pa)) {
177   case PT_ENTRY_NOT_PRESENT:
178     *paddr = 0;
179     return -1;
180   case PT_ENTRY_PAGE:
181     {
182       pdpe64_t * guest_pdp = NULL;
183       addr_t guest_pde_pa = 0;
184
185       if (guest_pa_to_host_va(info, guest_pdpe_pa, (addr_t *)&guest_pdp) == -1) {
186         PrintError("Could not get virtual address of Guest PDPE64 (PA=%p)\n", 
187                    (void *)guest_pdpe_pa);
188         return -1;
189       }
190
191       switch (pdpe64_lookup(guest_pdp, vaddr, &guest_pde_pa)) {
192       case PT_ENTRY_NOT_PRESENT:
193         *paddr = 0;
194         return -1;
195       case PT_ENTRY_LARGE_PAGE:
196         *paddr = 0;
197         PrintError("1 Gigabyte Pages not supported\n");
198         return -1;
199       case PT_ENTRY_PAGE:
200         {
201           pde64_t * guest_pde = NULL;
202           addr_t guest_pte_pa = 0;
203
204           if (guest_pa_to_host_va(info, guest_pde_pa, (addr_t *)&guest_pde) == -1) {
205             PrintError("Could not get virtual address of guest PDE64 (PA=%p)\n", 
206                        (void *)guest_pde_pa);
207             return -1;
208           }
209
210           switch (pde64_lookup(guest_pde, vaddr, &guest_pte_pa)) {
211           case PT_ENTRY_NOT_PRESENT:
212             *paddr = 0;
213             return -1;
214           case PT_ENTRY_LARGE_PAGE:
215             *paddr = guest_pte_pa;
216             return 0;
217           case PT_ENTRY_PAGE:
218             {
219               pte64_t * guest_pte = NULL;
220               
221               if (guest_pa_to_host_va(info, guest_pte_pa, (addr_t *)&guest_pte) == -1) {
222                 PrintError("Could not get virtual address of guest PTE64 (PA=%p)\n", 
223                            (void *)guest_pte_pa);
224                 return -1;
225               }
226                 
227               if (pte64_lookup(guest_pte, vaddr, paddr) == PT_ENTRY_NOT_PRESENT) {
228                 return -1;
229               }
230
231               return 0;
232             }
233           }
234         }
235       }
236     }
237   default:
238     return -1;
239   }
240   return 0;
241 }
242
243
244
245 int v3_translate_host_pt_32(addr_t host_cr3, addr_t vaddr, addr_t * paddr) {
246   pde32_t * host_pde = (pde32_t *)CR3_TO_PDE32_VA(host_cr3);
247   pte32_t * host_pte = 0;
248     
249   switch (pde32_lookup(host_pde, vaddr, (addr_t *)&host_pte)) {
250   case PT_ENTRY_NOT_PRESENT:
251     *paddr = 0;
252     return -1;
253   case PT_ENTRY_LARGE_PAGE:
254     *paddr = (addr_t)host_pte;
255     return 0;
256   case PT_ENTRY_PAGE:
257     if (pte32_lookup(host_pte, vaddr, paddr) == PT_ENTRY_NOT_PRESENT) {
258       return -1;
259     }
260   }
261
262   return 0;
263 }
264
265
266 int v3_translate_host_pt_32pae(addr_t host_cr3, addr_t vaddr, addr_t * paddr) {
267
268
269   return -1;
270 }
271
272
273 int v3_translate_host_pt_64(addr_t host_cr3, addr_t vaddr, addr_t * paddr) {
274
275
276   return -1;
277 }
278
279
280
281
282
283 /*
284  * PAGE TABLE LOOKUP FUNCTIONS
285  *
286  *
287  * The value of entry is a return type:
288  * Page not present: *entry = 0
289  * Large Page: *entry = translated physical address (byte granularity)
290  * PTE entry: *entry is the address of the PTE Page
291  */
292
293 /**
294  * 
295  *  32 bit Page Table lookup functions
296  *
297  **/
298
299 pt_entry_type_t pde32_lookup(pde32_t * pd, addr_t addr, addr_t * entry) {
300   pde32_t * pde_entry = &(pd[PDE32_INDEX(addr)]);
301
302   if (!pde_entry->present) {
303     *entry = 0;
304     return PT_ENTRY_NOT_PRESENT;
305   } else if (pde_entry->large_page) {
306     pde32_4MB_t * large_pde = (pde32_4MB_t *)pde_entry;
307
308     *entry = BASE_TO_PAGE_ADDR_4MB(large_pde->page_base_addr);
309     *entry += PAGE_OFFSET_4MB(addr);
310
311     return PT_ENTRY_LARGE_PAGE;
312   } else {
313     *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
314     return PT_ENTRY_PAGE;
315   }
316 }
317
318
319
320 /* Takes a virtual addr (addr) and returns the physical addr (entry) as defined in the page table
321  */
322 pt_entry_type_t pte32_lookup(pte32_t * pt, addr_t addr, addr_t * entry) {
323   pte32_t * pte_entry = &(pt[PTE32_INDEX(addr)]);
324
325   if (!pte_entry->present) {
326     *entry = 0;
327     //    PrintDebug("Lookup at non present page (index=%d)\n", PTE32_INDEX(addr));
328     return PT_ENTRY_NOT_PRESENT;
329   } else {
330     *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr) + PAGE_OFFSET(addr);
331     return PT_ENTRY_PAGE;
332   }
333
334 }
335
336
337
338 /**
339  * 
340  *  32 bit PAE Page Table lookup functions
341  *
342  **/
343 pt_entry_type_t pdpe32pae_lookup(pdpe32pae_t * pdp, addr_t addr, addr_t * entry) {
344   pdpe32pae_t * pdpe_entry = &(pdp[PDPE32PAE_INDEX(addr)]);
345   
346   if (!pdpe_entry->present) {
347     *entry = 0;
348     return PT_ENTRY_NOT_PRESENT;
349   } else {
350     *entry = BASE_TO_PAGE_ADDR(pdpe_entry->pd_base_addr);
351     return PT_ENTRY_PAGE;
352   }
353 }
354
355 pt_entry_type_t pde32pae_lookup(pde32pae_t * pd, addr_t addr, addr_t * entry) {
356   pde32pae_t * pde_entry = &(pd[PDE32PAE_INDEX(addr)]);
357
358   if (!pde_entry->present) {
359     *entry = 0;
360     return PT_ENTRY_NOT_PRESENT;
361   } else if (pde_entry->large_page) {
362     pde32pae_2MB_t * large_pde = (pde32pae_2MB_t *)pde_entry;
363
364     *entry = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
365     *entry += PAGE_OFFSET_2MB(addr);
366
367     return PT_ENTRY_LARGE_PAGE;
368   } else {
369     *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
370     return PT_ENTRY_PAGE;
371   }
372 }
373
374 pt_entry_type_t pte32pae_lookup(pte32pae_t * pt, addr_t addr, addr_t * entry) {
375   pte32pae_t * pte_entry = &(pt[PTE32PAE_INDEX(addr)]);
376
377   if (!pte_entry->present) {
378     *entry = 0;
379     return PT_ENTRY_NOT_PRESENT;
380   } else {
381     *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr) + PAGE_OFFSET(addr);
382     return PT_ENTRY_PAGE;
383   }
384 }
385
386
387
388 /**
389  * 
390  *  64 bit Page Table lookup functions
391  *
392  **/
393 pt_entry_type_t pml4e64_lookup(pml4e64_t * pml, addr_t addr, addr_t * entry) {
394   pml4e64_t * pml_entry = &(pml[PML4E64_INDEX(addr)]);
395
396   if (!pml_entry->present) {
397     *entry = 0;
398     return PT_ENTRY_NOT_PRESENT;
399   } else {
400     *entry = BASE_TO_PAGE_ADDR(pml_entry->pdp_base_addr);
401     return PT_ENTRY_PAGE;
402   }
403 }
404
405 pt_entry_type_t pdpe64_lookup(pdpe64_t * pdp, addr_t addr, addr_t * entry) {
406   pdpe64_t * pdpe_entry = &(pdp[PDPE64_INDEX(addr)]);
407   
408   if (!pdpe_entry->present) {
409     *entry = 0;
410     return PT_ENTRY_NOT_PRESENT;
411   } else if (pdpe_entry->large_page) {
412     PrintError("1 Gigabyte pages not supported\n");
413     V3_ASSERT(0);
414     return -1;
415   } else {
416     *entry = BASE_TO_PAGE_ADDR(pdpe_entry->pd_base_addr);
417     return PT_ENTRY_PAGE;
418   }
419 }
420
421 pt_entry_type_t pde64_lookup(pde64_t * pd, addr_t addr, addr_t * entry) {
422   pde64_t * pde_entry = &(pd[PDE64_INDEX(addr)]);
423
424   if (!pde_entry->present) {
425     *entry = 0;
426     return PT_ENTRY_NOT_PRESENT;
427   } else if (pde_entry->large_page) {
428     pde64_2MB_t * large_pde = (pde64_2MB_t *)pde_entry;
429
430     *entry = BASE_TO_PAGE_ADDR_2MB(large_pde->page_base_addr);
431     *entry += PAGE_OFFSET_2MB(addr);
432
433     return PT_ENTRY_LARGE_PAGE;
434   } else {
435     *entry = BASE_TO_PAGE_ADDR(pde_entry->pt_base_addr);
436     return PT_ENTRY_PAGE;
437   }
438 }
439
440 pt_entry_type_t pte64_lookup(pte64_t * pt, addr_t addr, addr_t * entry) {
441   pte64_t * pte_entry = &(pt[PTE64_INDEX(addr)]);
442
443   if (!pte_entry->present) {
444     *entry = 0;
445     return PT_ENTRY_NOT_PRESENT;
446   } else {
447     *entry = BASE_TO_PAGE_ADDR(pte_entry->page_base_addr) + PAGE_OFFSET(addr);
448     return PT_ENTRY_PAGE;
449   }
450 }
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468 pt_access_status_t can_access_pde32(pde32_t * pde, addr_t addr, pf_error_t access_type) {
469   pde32_t * entry = &pde[PDE32_INDEX(addr)];
470
471   if (entry->present == 0) {
472     return PT_ACCESS_NOT_PRESENT;
473   } else if ((entry->writable == 0) && (access_type.write == 1)) {
474     return PT_ACCESS_WRITE_ERROR;
475   } else if ((entry->user_page == 0) && (access_type.user == 1)) {
476     // Check CR0.WP?
477     return PT_ACCESS_USER_ERROR;
478   }
479
480   return PT_ACCESS_OK;
481 }
482
483
484 pt_access_status_t can_access_pte32(pte32_t * pte, addr_t addr, pf_error_t access_type) {
485   pte32_t * entry = &pte[PTE32_INDEX(addr)];
486
487   if (entry->present == 0) {
488     return PT_ACCESS_NOT_PRESENT;
489   } else if ((entry->writable == 0) && (access_type.write == 1)) {
490     return PT_ACCESS_WRITE_ERROR;
491   } else if ((entry->user_page == 0) && (access_type.user == 1)) {
492     // Check CR0.WP?
493     return PT_ACCESS_USER_ERROR;
494   }
495
496   return PT_ACCESS_OK;
497 }
498
499
500
501
502 /* We generate a page table to correspond to a given memory layout
503  * pulling pages from the mem_list when necessary
504  * If there are any gaps in the layout, we add them as unmapped pages
505  */
506 pde32_t * create_passthrough_pts_32(struct guest_info * guest_info) {
507   addr_t current_page_addr = 0;
508   int i, j;
509   struct shadow_map * map = &(guest_info->mem_map);
510
511   pde32_t * pde = V3_VAddr(V3_AllocPages(1));
512
513   for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
514     int pte_present = 0;
515     pte32_t * pte = V3_VAddr(V3_AllocPages(1));
516     
517
518     for (j = 0; j < MAX_PTE32_ENTRIES; j++) {
519       struct shadow_region * region = get_shadow_region_by_addr(map, current_page_addr);
520
521       if (!region || 
522           (region->host_type == HOST_REGION_HOOK) || 
523           (region->host_type == HOST_REGION_UNALLOCATED) || 
524           (region->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) || 
525           (region->host_type == HOST_REGION_REMOTE) ||
526           (region->host_type == HOST_REGION_SWAPPED)) {
527         pte[j].present = 0;
528         pte[j].writable = 0;
529         pte[j].user_page = 0;
530         pte[j].write_through = 0;
531         pte[j].cache_disable = 0;
532         pte[j].accessed = 0;
533         pte[j].dirty = 0;
534         pte[j].pte_attr = 0;
535         pte[j].global_page = 0;
536         pte[j].vmm_info = 0;
537         pte[j].page_base_addr = 0;
538       } else {
539         addr_t host_addr;
540         pte[j].present = 1;
541         pte[j].writable = 1;
542         pte[j].user_page = 1;
543         pte[j].write_through = 0;
544         pte[j].cache_disable = 0;
545         pte[j].accessed = 0;
546         pte[j].dirty = 0;
547         pte[j].pte_attr = 0;
548         pte[j].global_page = 0;
549         pte[j].vmm_info = 0;
550
551         if (guest_pa_to_host_pa(guest_info, current_page_addr, &host_addr) == -1) {
552           // BIG ERROR
553           // PANIC
554           return NULL;
555         }
556         
557         pte[j].page_base_addr = host_addr >> 12;
558         
559         pte_present = 1;
560       }
561
562       current_page_addr += PAGE_SIZE;
563     }
564
565     if (pte_present == 0) { 
566       V3_FreePage(V3_PAddr(pte));
567
568       pde[i].present = 0;
569       pde[i].writable = 0;
570       pde[i].user_page = 0;
571       pde[i].write_through = 0;
572       pde[i].cache_disable = 0;
573       pde[i].accessed = 0;
574       pde[i].reserved = 0;
575       pde[i].large_page = 0;
576       pde[i].global_page = 0;
577       pde[i].vmm_info = 0;
578       pde[i].pt_base_addr = 0;
579     } else {
580       pde[i].present = 1;
581       pde[i].writable = 1;
582       pde[i].user_page = 1;
583       pde[i].write_through = 0;
584       pde[i].cache_disable = 0;
585       pde[i].accessed = 0;
586       pde[i].reserved = 0;
587       pde[i].large_page = 0;
588       pde[i].global_page = 0;
589       pde[i].vmm_info = 0;
590       pde[i].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
591     }
592
593   }
594
595   return pde;
596 }
597
598
599 /* We generate a page table to correspond to a given memory layout
600  * pulling pages from the mem_list when necessary
601  * If there are any gaps in the layout, we add them as unmapped pages
602  */
603 pdpe32pae_t * create_passthrough_pts_32PAE(struct guest_info * guest_info) {
604   addr_t current_page_addr = 0;
605   int i, j, k;
606   struct shadow_map * map = &(guest_info->mem_map);
607
608   pdpe32pae_t * pdpe = V3_VAddr(V3_AllocPages(1));
609   memset(pdpe, 0, PAGE_SIZE);
610
611   for (i = 0; i < MAX_PDPE32PAE_ENTRIES; i++) {
612     int pde_present = 0;
613     pde32pae_t * pde = V3_VAddr(V3_AllocPages(1));
614
615     for (j = 0; j < MAX_PDE32PAE_ENTRIES; j++) {
616
617
618       int pte_present = 0;
619       pte32pae_t * pte = V3_VAddr(V3_AllocPages(1));
620       
621       
622       for (k = 0; k < MAX_PTE32PAE_ENTRIES; k++) {
623         struct shadow_region * region = get_shadow_region_by_addr(map, current_page_addr);
624         
625         if (!region || 
626             (region->host_type == HOST_REGION_HOOK) || 
627             (region->host_type == HOST_REGION_UNALLOCATED) || 
628             (region->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) || 
629             (region->host_type == HOST_REGION_REMOTE) ||
630             (region->host_type == HOST_REGION_SWAPPED)) {
631           pte[k].present = 0;
632           pte[k].writable = 0;
633           pte[k].user_page = 0;
634           pte[k].write_through = 0;
635           pte[k].cache_disable = 0;
636           pte[k].accessed = 0;
637           pte[k].dirty = 0;
638           pte[k].pte_attr = 0;
639           pte[k].global_page = 0;
640           pte[k].vmm_info = 0;
641           pte[k].page_base_addr = 0;
642           pte[k].rsvd = 0;
643         } else {
644           addr_t host_addr;
645           pte[k].present = 1;
646           pte[k].writable = 1;
647           pte[k].user_page = 1;
648           pte[k].write_through = 0;
649           pte[k].cache_disable = 0;
650           pte[k].accessed = 0;
651           pte[k].dirty = 0;
652           pte[k].pte_attr = 0;
653           pte[k].global_page = 0;
654           pte[k].vmm_info = 0;
655           
656           if (guest_pa_to_host_pa(guest_info, current_page_addr, &host_addr) == -1) {
657             // BIG ERROR
658             // PANIC
659             return NULL;
660           }
661           
662           pte[k].page_base_addr = host_addr >> 12;
663           pte[k].rsvd = 0;
664
665           pte_present = 1;
666         }
667         
668         current_page_addr += PAGE_SIZE;
669       }
670       
671       if (pte_present == 0) { 
672         V3_FreePage(V3_PAddr(pte));
673         
674         pde[j].present = 0;
675         pde[j].writable = 0;
676         pde[j].user_page = 0;
677         pde[j].write_through = 0;
678         pde[j].cache_disable = 0;
679         pde[j].accessed = 0;
680         pde[j].avail = 0;
681         pde[j].large_page = 0;
682         pde[j].global_page = 0;
683         pde[j].vmm_info = 0;
684         pde[j].pt_base_addr = 0;
685         pde[j].rsvd = 0;
686       } else {
687         pde[j].present = 1;
688         pde[j].writable = 1;
689         pde[j].user_page = 1;
690         pde[j].write_through = 0;
691         pde[j].cache_disable = 0;
692         pde[j].accessed = 0;
693         pde[j].avail = 0;
694         pde[j].large_page = 0;
695         pde[j].global_page = 0;
696         pde[j].vmm_info = 0;
697         pde[j].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
698         pde[j].rsvd = 0;
699
700         pde_present = 1;
701       }
702       
703     }
704     
705     if (pde_present == 0) { 
706       V3_FreePage(V3_PAddr(pde));
707       
708       pdpe[i].present = 0;
709       pdpe[i].rsvd = 0;
710       pdpe[i].write_through = 0;
711       pdpe[i].cache_disable = 0;
712       pdpe[i].accessed = 0;
713       pdpe[i].avail = 0;
714       pdpe[i].rsvd2 = 0;
715       pdpe[i].vmm_info = 0;
716       pdpe[i].pd_base_addr = 0;
717       pdpe[i].rsvd3 = 0;
718     } else {
719       pdpe[i].present = 1;
720       pdpe[i].rsvd = 0;
721       pdpe[i].write_through = 0;
722       pdpe[i].cache_disable = 0;
723       pdpe[i].accessed = 0;
724       pdpe[i].avail = 0;
725       pdpe[i].rsvd2 = 0;
726       pdpe[i].vmm_info = 0;
727       pdpe[i].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));
728       pdpe[i].rsvd3 = 0;
729     }
730     
731   }
732
733
734   return pdpe;
735 }
736
737
738
739
740
741
742 pml4e64_t * create_passthrough_pts_64(struct guest_info * info) {
743   addr_t current_page_addr = 0;
744   int i, j, k, m;
745   struct shadow_map * map = &(info->mem_map);
746   
747   pml4e64_t * pml = V3_VAddr(V3_AllocPages(1));
748
749   for (i = 0; i < 1; i++) {
750     int pdpe_present = 0;
751     pdpe64_t * pdpe = V3_VAddr(V3_AllocPages(1));
752
753     for (j = 0; j < 20; j++) {
754       int pde_present = 0;
755       pde64_t * pde = V3_VAddr(V3_AllocPages(1));
756
757       for (k = 0; k < MAX_PDE64_ENTRIES; k++) {
758         int pte_present = 0;
759         pte64_t * pte = V3_VAddr(V3_AllocPages(1));
760
761
762         for (m = 0; m < MAX_PTE64_ENTRIES; m++) {
763           struct shadow_region * region = get_shadow_region_by_addr(map, current_page_addr);
764           
765
766           
767           if (!region || 
768               (region->host_type == HOST_REGION_HOOK) || 
769               (region->host_type == HOST_REGION_UNALLOCATED) || 
770               (region->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) || 
771               (region->host_type == HOST_REGION_REMOTE) ||
772               (region->host_type == HOST_REGION_SWAPPED)) {
773             pte[m].present = 0;
774             pte[m].writable = 0;
775             pte[m].user_page = 0;
776             pte[m].write_through = 0;
777             pte[m].cache_disable = 0;
778             pte[m].accessed = 0;
779             pte[m].dirty = 0;
780             pte[m].pte_attr = 0;
781             pte[m].global_page = 0;
782             pte[m].vmm_info = 0;
783             pte[m].page_base_addr = 0;
784           } else {
785             addr_t host_addr;
786             pte[m].present = 1;
787             pte[m].writable = 1;
788             pte[m].user_page = 1;
789             pte[m].write_through = 0;
790             pte[m].cache_disable = 0;
791             pte[m].accessed = 0;
792             pte[m].dirty = 0;
793             pte[m].pte_attr = 0;
794             pte[m].global_page = 0;
795             pte[m].vmm_info = 0;
796             
797             if (guest_pa_to_host_pa(info, current_page_addr, &host_addr) == -1) {
798               // BIG ERROR
799               // PANIC
800               return NULL;
801             }
802
803             pte[m].page_base_addr = PAGE_BASE_ADDR(host_addr);
804
805             //PrintPTE64(current_page_addr, &(pte[m]));
806
807             pte_present = 1;      
808           }
809
810
811
812
813           current_page_addr += PAGE_SIZE;
814         }
815         
816         if (pte_present == 0) {
817           V3_FreePage(V3_PAddr(pte));
818
819           pde[k].present = 0;
820           pde[k].writable = 0;
821           pde[k].user_page = 0;
822           pde[k].write_through = 0;
823           pde[k].cache_disable = 0;
824           pde[k].accessed = 0;
825           pde[k].avail = 0;
826           pde[k].large_page = 0;
827           //pde[k].global_page = 0;
828           pde[k].vmm_info = 0;
829           pde[k].pt_base_addr = 0;
830         } else {
831           pde[k].present = 1;
832           pde[k].writable = 1;
833           pde[k].user_page = 1;
834           pde[k].write_through = 0;
835           pde[k].cache_disable = 0;
836           pde[k].accessed = 0;
837           pde[k].avail = 0;
838           pde[k].large_page = 0;
839           //pde[k].global_page = 0;
840           pde[k].vmm_info = 0;
841           pde[k].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
842
843           pde_present = 1;
844         }
845       }
846
847       if (pde_present == 0) {
848         V3_FreePage(V3_PAddr(pde));
849         
850         pdpe[j].present = 0;
851         pdpe[j].writable = 0;
852         pdpe[j].user_page = 0;
853         pdpe[j].write_through = 0;
854         pdpe[j].cache_disable = 0;
855         pdpe[j].accessed = 0;
856         pdpe[j].avail = 0;
857         pdpe[j].large_page = 0;
858         //pdpe[j].global_page = 0;
859         pdpe[j].vmm_info = 0;
860         pdpe[j].pd_base_addr = 0;
861       } else {
862         pdpe[j].present = 1;
863         pdpe[j].writable = 1;
864         pdpe[j].user_page = 1;
865         pdpe[j].write_through = 0;
866         pdpe[j].cache_disable = 0;
867         pdpe[j].accessed = 0;
868         pdpe[j].avail = 0;
869         pdpe[j].large_page = 0;
870         //pdpe[j].global_page = 0;
871         pdpe[j].vmm_info = 0;
872         pdpe[j].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));
873
874
875         pdpe_present = 1;
876       }
877
878     }
879
880     PrintDebug("PML index=%d\n", i);
881
882     if (pdpe_present == 0) {
883       V3_FreePage(V3_PAddr(pdpe));
884       
885       pml[i].present = 0;
886       pml[i].writable = 0;
887       pml[i].user_page = 0;
888       pml[i].write_through = 0;
889       pml[i].cache_disable = 0;
890       pml[i].accessed = 0;
891       pml[i].reserved = 0;
892       //pml[i].large_page = 0;
893       //pml[i].global_page = 0;
894       pml[i].vmm_info = 0;
895       pml[i].pdp_base_addr = 0;
896     } else {
897       pml[i].present = 1;
898       pml[i].writable = 1;
899       pml[i].user_page = 1;
900       pml[i].write_through = 0;
901       pml[i].cache_disable = 0;
902       pml[i].accessed = 0;
903       pml[i].reserved = 0;
904       //pml[i].large_page = 0;
905       //pml[i].global_page = 0;
906       pml[i].vmm_info = 0;
907       pml[i].pdp_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pdpe));
908     }
909   }
910
911   return pml;
912 }
913
914
915
916