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.


Fixed minor compilation problems
[palacios.git] / palacios / src / palacios / mmu / vmm_shdw_pg_kvm_64.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 #ifdef CONFIG_SHADOW_CACHE
21
22 #define PT64_NX_MASK (1ULL << 63)
23 //#define SHOW_ALL 
24
25 static inline int activate_shadow_pt_64(struct guest_info * core) {
26     struct cr3_64 * shadow_cr3 = (struct cr3_64 *)&(core->ctrl_regs.cr3);
27     struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(core->shdw_pg_state.guest_cr3);
28
29     struct shadow_page_cache_data *shadow_pt;
30
31     if(core->n_free_shadow_pages < MIN_FREE_SHADOW_PAGES) {
32         shadow_free_some_pages(core);
33     }
34     shadow_pt = shadow_page_get_page(core, (addr_t)(guest_cr3->pml4t_base_addr), 4, 0, 0, 0, 0);
35     PrintDebug("Activate shadow_pt %p\n", (void *)BASE_TO_PAGE_ADDR(guest_cr3->pml4t_base_addr));
36
37     struct shadow_page_cache_data * shadow_pt = create_new_shadow_pt(core);
38
39     addr_t shadow_pt_addr = shadow_pt->page_pa;
40
41     // Because this is a new CR3 load the allocated page is the new CR3 value
42     shadow_pt->cr3 = shadow_pt->page_pa;
43
44     PrintDebug("Top level Shadow page pa=%p\n", (void *)shadow_pt_addr);
45
46     shadow_cr3->pml4t_base_addr = PAGE_BASE_ADDR_4KB(shadow_pt_addr);
47     PrintDebug("Creating new 64 bit shadow page table %p\n", (void *)BASE_TO_PAGE_ADDR(shadow_cr3->pml4t_base_addr));
48   
49     shadow_cr3->pwt = guest_cr3->pwt;
50     shadow_cr3->pcd = guest_cr3->pcd;
51
52     shadow_topup_caches(core);
53
54     return 0;
55 }
56
57
58
59
60
61
62 /* 
63  * *
64  * * 
65  * * 64 bit Page table fault handlers
66  * *
67  * *
68  */
69
70 static inline void burst_64 (struct guest_info * core) {
71 #ifdef SHOW_ALL
72                 struct shadow_page_cache_data * sp, *node;
73                 pte64_t * pt, *pte;
74                 int idx;
75                 list_for_each_entry_safe(sp, node, &core->active_shadow_pages, link) {
76                         pt = (pte64_t *)V3_VAddr((void *)sp->page_pa);
77                         PrintDebug("burst: pt %p\n",(void *)pt);
78                         for (idx = 0; idx < PT_ENT_PER_PAGE; ++idx) {                           
79                                 pte = (pte64_t *)&(pt[idx]);
80                                 if(*((uint64_t*)pte)) PrintDebug("%d: s %p\n",idx, (void*)*((uint64_t*)pte));
81                         }
82                         
83                 }
84 #endif
85 }
86
87 static inline int fix_read_pf_64(pte64_t *shadow_pte, uint_t vmm_info) {
88
89     PrintDebug("\tReadPf, start vmm_info %d\n", vmm_info);
90
91     if ((vmm_info & PT_USER_MASK) && !(shadow_pte->user_page)) {
92         shadow_pte->user_page = 1;
93         shadow_pte->writable = 0;
94         return 1;
95     }
96     return 0;           
97 }
98
99 static inline int fix_write_pf_64(struct guest_info *core, pte64_t *shadow_pte, pte64_t *guest_pte,
100     int user, int *write_pt, addr_t guest_fn, uint_t vmm_info) {
101
102     int writable_shadow;
103     struct cr0_64 *guest_cr0;
104     struct shadow_page_cache_data *page;
105     *write_pt = 0;
106
107     PrintDebug("\tWritePf, start vmm_info %d\n", vmm_info);
108
109     if (shadow_pte->writable) {
110         return 0;
111     }
112
113     PrintDebug("\tWritePf, pass writable\n");
114     writable_shadow = vmm_info & PT_WRITABLE_MASK;
115     PrintDebug("\tWritePf, writable_shadow %d\n", writable_shadow);
116
117     if (user) {
118         if (!(vmm_info & PT_USER_MASK) || !writable_shadow) {
119             PrintDebug("\tWritePf: 1st User Check\n");
120             return 0;
121         }
122     } else {
123         if (!writable_shadow) {
124            guest_cr0 = (struct cr0_64 *)&(core->shdw_pg_state.guest_cr0);
125            PrintDebug("\tWritePf: WP %d\n", guest_cr0->wp);
126
127            if (guest_cr0->wp) {
128                return 0;
129            }
130            shadow_pte->user_page = 0;
131         }
132     }
133
134     if (guest_pte->present == 0) {
135         memset((void*)shadow_pte, 0, sizeof(struct pte64));
136         PrintDebug("\tWritePf: Guest Not Present\n");
137         return 0;
138     }
139
140     if (user) {
141         while ((page = shadow_page_lookup_page(core, guest_fn, 0)) != NULL) {
142             shadow_zap_page(core, page);
143         }
144         
145         PrintDebug("\tWritePf: Zap Page\n");
146     } else if ((page = shadow_page_lookup_page(core, guest_fn, 0)) != NULL) {
147         if ((page = shadow_page_lookup_page (core, guest_fn, 0)) != NULL) {
148             guest_pte->dirty = 1;
149             *write_pt = 1;
150             PrintDebug("\tWritePf: Write Needed\n");
151             return 0;
152         }
153     }
154
155     shadow_pte->writable = 1;
156     guest_pte->dirty = 1;
157
158     rmap_add(core, (addr_t)shadow_pte);
159
160     PrintDebug("\tWritePf: On Writable\n");
161     return 1;
162
163 }
164
165
166 static int handle_2MB_shadow_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code,
167                                           pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde, uint32_t inherited_ar);
168
169 static int handle_pte_shadow_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code,
170                                           pte64_t * shadow_pt, pte64_t * guest_pt, uint32_t inherited_ar);
171
172 static int handle_pde_shadow_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code,
173                                           pde64_t * shadow_pd, pde64_t * guest_pd, uint32_t inherited_ar);
174
175 static int handle_pdpe_shadow_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code,
176                                            pdpe64_t * shadow_pdp, pdpe64_t * guest_pdp, uint32_t inherited_ar);
177
178
179 static inline int handle_shadow_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code) {
180     pml4e64_t * guest_pml = NULL;
181     pml4e64_t * shadow_pml = CR3_TO_PML4E64_VA(core->ctrl_regs.cr3);
182     addr_t guest_cr3 = CR3_TO_PML4E64_PA(core->shdw_pg_state.guest_cr3);
183     pt_access_status_t guest_pml4e_access;
184     pt_access_status_t shadow_pml4e_access;
185     pml4e64_t * guest_pml4e = NULL;
186     pml4e64_t * shadow_pml4e = (pml4e64_t *)&(shadow_pml[PML4E64_INDEX(fault_addr)]);
187
188     PrintDebug("64 bit Shadow page fault handler: %p\n", (void *)fault_addr);
189     PrintDebug("Handling PML fault\n");
190
191     int metaphysical = 0;
192     unsigned hugepage_access = 0;
193     addr_t pml4e_base_addr = 0;
194     uint32_t inherited_ar = PT_USER_MASK | PT_WRITABLE_MASK;
195
196     if (core->n_free_shadow_pages < MIN_FREE_SHADOW_PAGES) {
197         shadow_free_some_pages(core);
198     }
199     shadow_topup_caches(core);
200
201 #ifdef SHOW_ALL
202     //debug
203     burst_64 (core);
204 #endif
205
206     if (guest_pa_to_host_va(core, guest_cr3, (addr_t*)&guest_pml) == -1) {
207         PrintError("Invalid Guest PML4E Address: 0x%p\n",  (void *)guest_cr3);
208         return -1;
209     } 
210
211     guest_pml4e = (pml4e64_t *)&(guest_pml[PML4E64_INDEX(fault_addr)]);
212
213     pml4e_base_addr = (addr_t)(guest_pml4e->pdp_base_addr);
214
215     PrintDebug("Checking Guest %p\n", (void *)guest_pml);
216     // Check the guest page permissions
217     guest_pml4e_access = v3_can_access_pml4e64(guest_pml, fault_addr, error_code);
218
219     PrintDebug("Checking shadow %p\n", (void *)shadow_pml);
220     // Check the shadow page permissions
221     shadow_pml4e_access = v3_can_access_pml4e64(shadow_pml, fault_addr, error_code);
222
223     if (guest_pml4e_access == PT_ACCESS_NOT_PRESENT) {
224         error_code.present = 0;
225         goto pml4e_error;
226     }
227
228     if (guest_pml4e_access == PT_ACCESS_WRITE_ERROR) {
229         struct cr0_64 *guest_cr0 = (struct cr0_64*)&(core->shdw_pg_state.guest_cr0);
230         if (error_code.user || guest_cr0->wp) {
231             error_code.present = 1;
232             goto pml4e_error;
233         }
234     }
235
236     if (guest_pml4e_access == PT_ACCESS_USER_ERROR) {
237         error_code.present = 1;
238         goto pml4e_error;
239     }
240
241     
242     if (error_code.ifetch == 1 && ((*(uint64_t*)guest_pml4e) & PT64_NX_MASK)) {
243         struct efer_64 *guest_efer = (struct efer_64*)&(core->shdw_pg_state.guest_efer);
244         if (guest_efer->lma == 1) {
245             goto pml4e_error;
246         }
247     }   
248         
249     goto pml4e_noerror;
250
251 pml4e_error:
252
253     PrintDebug("Injecting PML Pf to Guest: (Guest Access Error = %d) (SHDW Access Error = %d) (Pf Error Code = %d)\n",
254         *(uint_t*)&guest_pml4e_access, *(uint_t*)&shadow_pml4e_access, *(uint_t*)&error_code);
255     if (inject_guest_pf(core, fault_addr, error_code) == -1) {
256         PrintError("Could Not Inject Guest Page Fault\n");
257         return -1;
258     }
259     return 0;
260
261 pml4e_noerror:
262
263     if (guest_pml4e->accessed == 0) {
264         guest_pml4e->accessed = 1;              
265     }
266
267     inherited_ar &= *(uint64_t*)guest_pml4e;
268     PrintDebug("PML: inherited %x\n", inherited_ar);
269
270     pdpe64_t * shadow_pdp = NULL;
271     pdpe64_t * guest_pdp = NULL;
272
273     // Get the next shadow page level, allocate if not present
274
275     if (shadow_pml4e_access == PT_ACCESS_NOT_PRESENT) {
276         struct shadow_page_cache_data *shdw_page = shadow_page_get_page(core, pml4e_base_addr, 3, metaphysical, 
277             hugepage_access, (addr_t)shadow_pml4e, 0);
278         shadow_pdp = (pdpe64_t *)V3_VAddr((void *)shdw_page->page_pa);
279
280         shadow_pml4e->present =1;
281         shadow_pml4e->accessed=1;
282         shadow_pml4e->writable=1;
283         shadow_pml4e->user_page=1;      
284     
285         shadow_pml4e->pdp_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
286     } else {
287         shadow_pdp = (pdpe64_t *)V3_VAddr((void *)(addr_t)BASE_TO_PAGE_ADDR(shadow_pml4e->pdp_base_addr));
288     }
289
290     // Continue processing at the next level
291
292     if (guest_pa_to_host_va(core, BASE_TO_PAGE_ADDR(guest_pml4e->pdp_base_addr), (addr_t *)&guest_pdp) == -1) {
293         // Machine check the guest
294         PrintError("Invalid Guest PDP Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pml4e->pdp_base_addr));
295         v3_raise_exception(core, MC_EXCEPTION);
296         return 0;
297     }
298   
299     if (handle_pdpe_shadow_pagefault_64(core, fault_addr, error_code, shadow_pdp, guest_pdp, inherited_ar) == -1) {
300         PrintError("Error handling Page fault caused by PDPE\n");
301         return -1;
302     }
303
304     return 0;
305 }
306
307
308
309 // For now we are not going to handle 1 Gigabyte pages
310 static int handle_pdpe_shadow_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code,
311                                            pdpe64_t * shadow_pdp, pdpe64_t * guest_pdp, uint32_t inherited_ar) {
312     pt_access_status_t guest_pdpe_access;
313     pt_access_status_t shadow_pdpe_access;
314     pdpe64_t * guest_pdpe = (pdpe64_t *)&(guest_pdp[PDPE64_INDEX(fault_addr)]);
315     pdpe64_t * shadow_pdpe = (pdpe64_t *)&(shadow_pdp[PDPE64_INDEX(fault_addr)]);
316  
317     PrintDebug("Handling PDP fault\n");
318
319     if (fault_addr==0) { 
320         PrintDebug("Guest Page Tree for guest virtual address zero fault\n");
321         PrintGuestPageTree(core,fault_addr,(addr_t)(core->shdw_pg_state.guest_cr3));
322         PrintDebug("Host Page Tree for guest virtual address zero fault\n");
323         PrintHostPageTree(core,fault_addr,(addr_t)(core->ctrl_regs.cr3));
324     }
325
326     int metaphysical = 0;
327     unsigned hugepage_access = 0;
328
329     addr_t pdpe_base_addr = (addr_t)(guest_pdpe->pd_base_addr);
330
331     // Check the guest page permissions
332     guest_pdpe_access = v3_can_access_pdpe64(guest_pdp, fault_addr, error_code);
333
334     // Check the shadow page permissions
335     shadow_pdpe_access = v3_can_access_pdpe64(shadow_pdp, fault_addr, error_code);
336
337     if (guest_pdpe_access == PT_ACCESS_NOT_PRESENT) {
338         PrintDebug("Guest Page Tree for guest virtual address zero fault\n");
339         error_code.present = 0;
340         goto pdpe_error;
341     }
342
343     if (guest_pdpe_access == PT_ACCESS_WRITE_ERROR) {
344         struct cr0_64 *guest_cr0 = (struct cr0_64*)&(core->shdw_pg_state.guest_cr0);
345         if (error_code.user || guest_cr0->wp) {
346             error_code.present = 1;
347             goto pdpe_error;
348         }
349     }
350
351     if (guest_pdpe_access == PT_ACCESS_USER_ERROR) {
352         error_code.present = 1;
353         goto pdpe_error;
354     }
355
356     if (error_code.ifetch == 1 && ((*(uint64_t*)guest_pdpe) & PT64_NX_MASK)) {
357         struct efer_64 *guest_efer = (struct efer_64*)&(core->shdw_pg_state.guest_efer);
358         if (guest_efer->lma == 1) {
359             goto pdpe_error;
360         }
361     }   
362         
363     goto pdpe_noerror;
364
365 pdpe_error:
366
367     PrintDebug("Injecting PML Pf to Guest: (Guest Access Error = %d) (SHDW Access Error = %d) (Pf Error Code = %d)\n",
368         *(uint_t*)&guest_pdpe_access, *(uint_t*)&shadow_pdpe_access, *(uint_t*)&error_code);
369     if (inject_guest_pf(core, fault_addr, error_code) == -1) {
370         PrintError("Could Not Inject Guest Page Fault\n");
371         return -1;
372     }
373     return 0;
374
375 pdpe_noerror:
376
377     if (guest_pdpe->accessed == 0) {
378         guest_pdpe->accessed = 1;               
379     }
380
381     inherited_ar &= *(uint64_t*)guest_pdpe;
382     PrintDebug("PDPE: inherited %x\n", inherited_ar);
383   
384     pde64_t * shadow_pd = NULL;
385     pde64_t * guest_pd = NULL;
386
387     // Get the next shadow page level, allocate if not present
388
389     if (shadow_pdpe_access == PT_ACCESS_NOT_PRESENT) {
390         struct shadow_page_cache_data *shdw_page = shadow_page_get_page(core, pdpe_base_addr, 2, metaphysical, 
391             hugepage_access, (addr_t) shadow_pdpe, 0);
392
393         shadow_pd = (pde64_t *)V3_VAddr((void *)shdw_page->page_pa);
394
395         shadow_pdpe->present =1;
396         shadow_pdpe->accessed=1;
397         shadow_pdpe->writable=1;
398         shadow_pdpe->user_page=1;       
399     
400         shadow_pdpe->pd_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
401     } else {
402         shadow_pd = (pde64_t *)V3_VAddr((void *)(addr_t)BASE_TO_PAGE_ADDR(shadow_pdpe->pd_base_addr));
403     }
404
405     // Continue processing at the next level
406
407     if (guest_pa_to_host_va(core, BASE_TO_PAGE_ADDR(guest_pdpe->pd_base_addr), (addr_t *)&guest_pd) == -1) {
408         // Machine check the guest
409         PrintError("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pdpe->pd_base_addr));
410         v3_raise_exception(core, MC_EXCEPTION);
411         return 0;
412     }
413   
414     if (handle_pde_shadow_pagefault_64(core, fault_addr, error_code, shadow_pd, guest_pd, inherited_ar) == -1) {
415         PrintError("Error handling Page fault caused by PDE\n");
416         return -1;
417     }
418
419     return 0;
420 }
421
422
423 static int handle_pde_shadow_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code,
424                                           pde64_t * shadow_pd, pde64_t * guest_pd, uint32_t inherited_ar) {
425     pt_access_status_t guest_pde_access;
426     pt_access_status_t shadow_pde_access;
427     pde64_t * guest_pde = (pde64_t *)&(guest_pd[PDE64_INDEX(fault_addr)]);
428     pde64_t * shadow_pde = (pde64_t *)&(shadow_pd[PDE64_INDEX(fault_addr)]);
429
430     PrintDebug("Handling PDE fault\n");
431
432     int metaphysical = 0;
433     unsigned hugepage_access = 0;
434
435     addr_t pde_base_addr = (addr_t)(guest_pde->pt_base_addr);
436
437     if (guest_pde->large_page == 1) {
438         pde_base_addr = (addr_t)PAGE_BASE_ADDR(BASE_TO_PAGE_ADDR_2MB(((pde64_2MB_t *) guest_pde)->page_base_addr));
439         metaphysical = 1;
440         hugepage_access = (((pde64_2MB_t*) guest_pde)->writable | (((pde64_2MB_t*) guest_pde)->user_page << 1));
441     } 
442  
443     // Check the guest page permissions
444     guest_pde_access = v3_can_access_pde64(guest_pd, fault_addr, error_code);
445
446     // Check the shadow page permissions
447     shadow_pde_access = v3_can_access_pde64(shadow_pd, fault_addr, error_code);
448
449     if (guest_pde_access == PT_ACCESS_NOT_PRESENT) {
450         error_code.present = 0;
451         goto pde_error;
452     }
453
454     if (guest_pde_access == PT_ACCESS_WRITE_ERROR) {
455         struct cr0_64 *guest_cr0 = (struct cr0_64*)&(core->shdw_pg_state.guest_cr0);
456         if (error_code.user || guest_cr0->wp) {
457             error_code.present = 1;
458             goto pde_error;
459         }
460     }
461
462     if (guest_pde_access == PT_ACCESS_USER_ERROR) {
463         error_code.present = 1;
464         goto pde_error;
465     }
466
467     if (error_code.ifetch == 1 && ((*(uint64_t*)guest_pde) & PT64_NX_MASK)) {
468         struct efer_64 *guest_efer = (struct efer_64*)&(core->shdw_pg_state.guest_efer);
469         if (guest_efer->lma == 1) {
470             goto pde_error;
471         }
472     }   
473         
474     goto pde_noerror;
475
476 pde_error:
477
478     PrintDebug("Injecting PML Pf to Guest: (Guest Access Error = %d) (SHDW Access Error = %d) (Pf Error Code = %d)\n",
479         *(uint_t*)&guest_pde_access, *(uint_t*)&shadow_pde_access, *(uint_t*)&error_code);
480     if (inject_guest_pf(core, fault_addr, error_code) == -1) {
481         PrintError("Could Not Inject Guest Page Fault\n");
482         return -1;
483     }
484     return 0;
485
486 pde_noerror:
487
488     if (guest_pde->accessed == 0) {
489         guest_pde->accessed = 1;                
490     }
491
492     inherited_ar &= *(uint64_t*)guest_pde;
493     PrintDebug("PDE: inherited %x\n", inherited_ar);
494   
495     pte64_t * shadow_pt = NULL;
496     pte64_t * guest_pt = NULL;
497
498     // Get the next shadow page level, allocate if not present
499
500     if (shadow_pde_access == PT_ACCESS_NOT_PRESENT) {
501         struct shadow_page_cache_data *shdw_page = shadow_page_get_page(core, pde_base_addr, 1, metaphysical, 
502             hugepage_access, (addr_t) shadow_pde, 0);
503         shadow_pt = (pte64_t *)V3_VAddr((void *)shdw_page->page_pa);
504
505         PrintDebug("Creating new shadow PT: %p\n", shadow_pt);
506
507         shadow_pde->present =1;
508         shadow_pde->accessed=1;
509         shadow_pde->writable=1;
510         shadow_pde->user_page=1;        
511
512         shadow_pde->pt_base_addr = PAGE_BASE_ADDR(shdw_page->page_pa);
513     } else {
514         shadow_pt = (pte64_t *)V3_VAddr((void *)BASE_TO_PAGE_ADDR(shadow_pde->pt_base_addr));
515     }
516
517     // Continue processing at the next level
518     if (guest_pde->large_page == 0) {
519         if (guest_pa_to_host_va(core, BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr), (addr_t *)&guest_pt) == -1) {
520             // Machine check the guest
521             PrintError("Invalid Guest PTE Address: 0x%p\n", (void *)BASE_TO_PAGE_ADDR(guest_pde->pt_base_addr));
522             v3_raise_exception(core, MC_EXCEPTION);
523             return 0;
524         }
525     
526         if (handle_pte_shadow_pagefault_64(core, fault_addr, error_code, shadow_pt, guest_pt, inherited_ar) == -1) {
527             PrintError("Error handling Page fault caused by PDE\n");
528             return -1;
529         }
530
531     } else {
532         if (handle_2MB_shadow_pagefault_64(core, fault_addr, error_code, shadow_pt, 
533                 (pde64_2MB_t *)guest_pde, inherited_ar) == -1) {
534             PrintError("Error handling large pagefault\n");
535             return -1;
536         } 
537     }
538
539     return 0;
540 }
541
542
543 static int handle_pte_shadow_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code,
544                                           pte64_t * shadow_pt, pte64_t * guest_pt, uint32_t inherited_ar)  {
545     pt_access_status_t guest_pte_access;
546     pt_access_status_t shadow_pte_access;
547     pte64_t * guest_pte = (pte64_t *)&(guest_pt[PTE64_INDEX(fault_addr)]);;
548     pte64_t * shadow_pte = (pte64_t *)&(shadow_pt[PTE64_INDEX(fault_addr)]);
549     addr_t guest_pa = BASE_TO_PAGE_ADDR((addr_t)(guest_pte->page_base_addr)) +  PAGE_OFFSET(fault_addr);
550     //  struct shadow_page_state * state = &(core->shdw_pg_state);
551
552     PrintDebug("Handling PTE fault\n");
553
554     struct v3_mem_region * shdw_reg =  v3_get_mem_region(core->vm_info, core->cpu_id, guest_pa);
555
556
557
558     if (shdw_reg == NULL) {
559         // Inject a machine check in the guest
560         PrintError("Invalid Guest Address in page table (0x%p)\n", (void *)guest_pa);
561         v3_raise_exception(core, MC_EXCEPTION);
562         return 0;
563     }
564
565     // Check the guest page permissions
566     guest_pte_access = v3_can_access_pte64(guest_pt, fault_addr, error_code);
567
568     // Check the shadow page permissions
569     shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code);
570
571     if (guest_pte_access == PT_ACCESS_NOT_PRESENT) {
572         error_code.present = 0;
573         goto pte_error;
574     }
575
576     if (guest_pte_access == PT_ACCESS_WRITE_ERROR) {
577         struct cr0_64 *guest_cr0 = (struct cr0_64*)&(core->shdw_pg_state.guest_cr0);
578         if (error_code.user || guest_cr0->wp) {
579             error_code.present = 1;
580             goto pte_error;
581         }
582     }
583
584     if (guest_pte_access == PT_ACCESS_USER_ERROR) {
585         error_code.present = 1;
586         goto pte_error;
587     }
588
589     if (error_code.ifetch == 1 && ((*(uint64_t*)guest_pte) & PT64_NX_MASK)) {
590         struct efer_64 *guest_efer = (struct efer_64*)&(core->shdw_pg_state.guest_efer);
591         if (guest_efer->lma == 1) {
592             goto pte_error;
593         }
594     }   
595         
596     goto pte_noerror;
597
598 pte_error:
599
600     PrintDebug("Injecting PML Pf to Guest: (Guest Access Error = %d) (SHDW Access Error = %d) (Pf Error Code = %d)\n",
601         *(uint_t*)&guest_pte_access, *(uint_t*)&shadow_pte_access, *(uint_t*)&error_code);
602     if (inject_guest_pf(core, fault_addr, error_code) == -1) {
603         PrintError("Could Not Inject Guest Page Fault\n");
604         return -1;
605     }
606     return 0;
607
608 pte_noerror:
609
610     if (guest_pte->accessed == 0) {
611         guest_pte->accessed = 1;                
612     }
613
614     inherited_ar &= *(uint64_t*)guest_pte;
615     PrintDebug("PTE: inherited %x\n", inherited_ar);
616
617     if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
618         // Page Table Entry Not Present
619         PrintDebug("guest_pa =%p\n", (void *)guest_pa);
620
621         if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) ||
622             (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
623
624             int inherited_ar_user = ((inherited_ar & PT_USER_MASK) == PT_USER_MASK) ? 1 : 0;
625             int inherited_ar_writable = ((inherited_ar & PT_WRITABLE_MASK) == PT_WRITABLE_MASK) ? 1 : 0;
626
627             addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->cpu_id, guest_pa);
628       
629             shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
630       
631             shadow_pte->present = guest_pte->present;
632
633             shadow_pte->user_page = inherited_ar_user;
634             PrintDebug("PTE: inheritied shdow_pte_user %d, guest_pte_user %d\n", shadow_pte->user_page, guest_pte->user_page);
635       
636             //set according to VMM policy
637             shadow_pte->global_page = guest_pte->global_page;
638             //
639       
640             shadow_pte->accessed = guest_pte->accessed;
641             shadow_pte->dirty = guest_pte->dirty;
642             shadow_pte->writable = inherited_ar_writable;
643
644             PrintDebug("PTE: inheritied shdow_pte_writable %d, guest_pte_writable %d\n", shadow_pte->writable, guest_pte->writable);
645
646
647             // Write hooks trump all, and are set Read Only
648             if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
649                 shadow_pte->writable = 0;
650             }
651
652             shadow_pte->vmm_info = (inherited_ar_writable << 1) | (inherited_ar_user << 2);
653
654             if (inherited_ar_writable & guest_pte->writable) {
655
656                 struct shadow_page_cache_data *shadow;
657                 shadow = shadow_page_lookup_page(core, PAGE_BASE_ADDR(guest_pa), 0);
658                 if (shadow) {
659                     if (shadow_pte->writable) {
660                         shadow_pte->writable = 0;
661                     }
662                 }
663             }
664
665             PrintDebug("PTE: Updated Shadow Present %d, Write %d, User %d, Dirty %d, Accessed %d, Global %d\n",
666                         shadow_pte->present, shadow_pte->writable, shadow_pte->user_page, shadow_pte->dirty, shadow_pte->accessed, 
667                         shadow_pte->global_page);       
668             PrintDebug("PTE: Shadow %p\n", (void*)*((addr_t*)shadow_pte));
669             rmap_add(core, (addr_t)shadow_pte);
670
671         } else {
672             // Page fault handled by hook functions
673
674             if (v3_handle_mem_full_hook(core, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
675                 PrintError("Special Page fault handler returned error for address: %p\n",  (void *)fault_addr);
676                 return -1;
677             }
678         }
679     } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
680         guest_pte->dirty = 1;
681
682         if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
683             if (v3_handle_mem_wr_hook(core, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
684                 PrintError("Special Page fault handler returned error for address: %p\n",  (void *)fault_addr);
685                 return -1;
686             }
687         } else {
688             PrintDebug("Shadow PTE Write Error\n");
689             shadow_pte->writable = guest_pte->writable;
690         }
691
692         return 0;
693     }
694
695     int fixed = 0;
696     int write_pt = 0;
697     uint_t vmm_info = shadow_pte->vmm_info;
698
699     if (error_code.write == 1) {
700         fixed = fix_write_pf_64(core, shadow_pte, guest_pte, (int)error_code.user, &write_pt, PAGE_BASE_ADDR(guest_pa), vmm_info);
701     } else {
702         fixed = fix_read_pf_64(shadow_pte, vmm_info);
703     }
704
705     PrintDebug("PTE: Fixed %d Write_Pt %d\n", fixed, write_pt);
706     PrintDebug("PTE: Shadow Present %d, Write %d, User %d, Dirty %d, Accessed %d, Global %d\n", 
707                 shadow_pte->present, shadow_pte->writable, shadow_pte->user_page, shadow_pte->dirty, shadow_pte->accessed, 
708                 shadow_pte->global_page);
709     PrintDebug("PTE: Shadow %p\n", (void*)*((addr_t*)shadow_pte));
710
711     if (shdw_reg->host_type == SHDW_REGION_ALLOCATED && write_pt == 1) {
712         PrintDebug("PTE: Emul\n");
713         if (v3_handle_mem_wr_hook(core, fault_addr, guest_pa, shdw_reg, error_code) == -1) {
714             shadow_unprotect_page(core, (addr_t)guest_pte->page_base_addr);
715         }
716     }
717
718     PrintDebug("PTE: PTE end\n");
719     PrintDebug("PTE: Updated Shadow Present %d, Write %d, User %d, Dirty %d, Accessed %d, Global %d\n", 
720                 shadow_pte->present, shadow_pte->writable, shadow_pte->user_page, shadow_pte->dirty, shadow_pte->accessed, 
721                 shadow_pte->global_page);
722     PrintDebug("PTE: Updated Shadow %p\n", (void*)*((addr_t*)shadow_pte));
723     PrintDebug("PTE: Guest PA %p, Host PA %p\n",  (void*)guest_pa, (void*)BASE_TO_PAGE_ADDR(shadow_pte->page_base_addr));
724
725     return 0;
726 }
727
728
729
730 static int handle_2MB_shadow_pagefault_64(struct guest_info * core, 
731                                           addr_t fault_addr, pf_error_t error_code, 
732                                           pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde, uint32_t inherited_ar) 
733 {
734     pt_access_status_t shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code);
735     pte64_t * shadow_pte = (pte64_t *)&(shadow_pt[PTE64_INDEX(fault_addr)]);
736     addr_t guest_fault_pa = BASE_TO_PAGE_ADDR_2MB(large_guest_pde->page_base_addr) + PAGE_OFFSET_2MB(fault_addr);
737     //  struct shadow_page_state * state = &(core->shdw_pg_state);
738
739     PrintDebug("Handling 2MB fault (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code);
740     PrintDebug("ShadowPT=%p, LargeGuestPDE=%p\n", shadow_pt, large_guest_pde);
741
742     struct v3_mem_region * shdw_reg = v3_get_mem_region(core->vm_info, core->cpu_id, guest_fault_pa);
743
744     int fixed = 0;
745     int write_pt = 0;
746     addr_t guest_fn;
747  
748     if (shdw_reg == NULL) {
749         // Inject a machine check in the guest
750         PrintError("Invalid Guest Address in page table (0x%p)\n", (void *)guest_fault_pa);
751         v3_raise_exception(core, MC_EXCEPTION);
752         return 0;
753     }
754
755   
756     if (shadow_pte_access == PT_ACCESS_NOT_PRESENT) {
757         // Get the guest physical address of the fault
758         int inherited_ar_user = ((inherited_ar & PT_USER_MASK) == PT_USER_MASK) ? 1 : 0;
759         int inherited_ar_writable = ((inherited_ar & PT_WRITABLE_MASK) == PT_WRITABLE_MASK) ? 1 : 0;
760
761         if ((shdw_reg->host_type == SHDW_REGION_ALLOCATED) || 
762             (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK)) {
763             addr_t shadow_pa = v3_get_shadow_addr(shdw_reg, core->cpu_id, guest_fault_pa);
764
765             shadow_pte->page_base_addr = PAGE_BASE_ADDR(shadow_pa);
766
767             PrintDebug("LPTE: inherited_ar %d\n", inherited_ar);
768             shadow_pte->user_page = inherited_ar_user;
769             PrintDebug("LPTE: inheritied shdow_pte_user %d\n", shadow_pte->user_page);
770
771             shadow_pte->present = large_guest_pde->present;
772             shadow_pte->dirty = large_guest_pde->dirty;
773
774             shadow_pte->present = 1;
775
776             /* We are assuming that the PDE entry has precedence
777              * so the Shadow PDE will mirror the guest PDE settings, 
778              * and we don't have to worry about them here
779              * Allow everything
780              */
781             shadow_pte->user_page = 1;
782
783             if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
784                 shadow_pte->writable = 0;
785             } else {
786                 shadow_pte->writable = inherited_ar_writable;
787                PrintDebug("LPTE: inheritied shdow_pte_writable %d, PT_WRITABLE_MASK %p, inherited_ar & PT_WRITABLE_MASK %p\n", 
788                                 shadow_pte->writable, (void*)PT_WRITABLE_MASK, (void*)(inherited_ar & PT_WRITABLE_MASK));
789             }
790
791             //set according to VMM policy
792             shadow_pte->global_page = large_guest_pde->global_page;
793             //
794
795             shadow_pte->vmm_info = (inherited_ar_writable <<1) | (inherited_ar_user << 2);
796
797             if (large_guest_pde->writable) {
798                 struct shadow_page_cache_data *shadow;
799                 shadow = shadow_page_lookup_page(core, PAGE_BASE_ADDR(guest_fault_pa), 0);
800
801                 if (shadow) {
802                     if (shadow_pte->writable) {
803                         shadow_pte->writable = 0;
804                     }
805                 }       
806             }
807
808             rmap_add(core, (addr_t)shadow_pte);
809       
810         } else {
811             if (v3_handle_mem_full_hook(core, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
812                 PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
813                 return -1;
814             }
815         }
816     } else if (shadow_pte_access == PT_ACCESS_WRITE_ERROR) {
817
818         if (shdw_reg->host_type == SHDW_REGION_WRITE_HOOK) {
819
820             if (v3_handle_mem_wr_hook(core, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
821                 PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
822                 return -1;
823             }
824         }
825         
826     }
827
828     struct cr3_64 *guest_cr3 = (struct cr3_64 *)&(core->shdw_pg_state.guest_cr3);
829     guest_fn = (addr_t)guest_cr3->pml4t_base_addr;
830     uint_t vmm_info = shadow_pte->vmm_info;
831
832     if (error_code.write == 1) {
833         fixed = fix_write_pf_64(core, shadow_pte, (pte64_t *)large_guest_pde, (int) error_code.user, 
834                 &write_pt, PAGE_BASE_ADDR(guest_fault_pa), vmm_info);
835     } else {
836         fixed = fix_read_pf_64(shadow_pte, vmm_info);
837     }
838
839     PrintDebug("LPTE: Fixed %d, Write_Pt %d\n", fixed, write_pt);
840     PrintDebug("LPTE: Shadow Present %d, Write %d, User %d, Dirty %d, Accessed %d, Global %d\n",
841                 shadow_pte->present, shadow_pte->writable, shadow_pte->user_page, shadow_pte->dirty,
842                 shadow_pte->accessed, shadow_pte->global_page);
843     PrintDebug("LPTE: Shadow %p\n", (void*)*((addr_t*)shadow_pte));
844
845     if (shdw_reg->host_type == SHDW_REGION_ALLOCATED && write_pt == 1){
846         if (v3_handle_mem_wr_hook(core, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
847             shadow_unprotect_page(core, (addr_t)PAGE_BASE_ADDR(guest_fault_pa));
848         }
849     }
850
851     PrintDebug("Updated LPTE: Shadow Present %d, Write %d, User %d, Dirty %d, Accessed %d, Global %d\n",
852                 shadow_pte->present, shadow_pte->writable, shadow_pte->user_page, shadow_pte->dirty, shadow_pte->accessed, 
853                 shadow_pte->global_page);
854     PrintDebug("LPTE: Updated Shadow %p\n", (void*)*((addr_t*)shadow_pte));
855     PrintDebug("LPTE: Guest PA %p Host PA %p\n", 
856                 (void*)BASE_TO_PAGE_ADDR(PAGE_BASE_ADDR(guest_fault_pa)), 
857                 (void*)BASE_TO_PAGE_ADDR(shadow_pte->page_base_addr));
858     PrintDebug("Returning from Large Page Fault Handler\n");
859
860     //  PrintHostPageTree(core, fault_addr, info->ctrl_regs.cr3);
861     PrintDebug("Returning from large page fault handler\n");
862     return 0;
863 }
864
865
866
867
868 static int invalidation_cb_64(struct guest_info * core, page_type_t type, 
869                               addr_t vaddr, addr_t page_ptr, addr_t page_pa, 
870                               void * private_data) {
871
872     switch (type) {
873         case PAGE_PML464:
874             {    
875                 pml4e64_t * pml = (pml4e64_t *)page_ptr;
876
877                 if (pml[PML4E64_INDEX(vaddr)].present == 0) {
878                     return 1;
879                 }
880                 return 0;
881             }
882         case PAGE_PDP64:
883             {
884                 pdpe64_t * pdp = (pdpe64_t *)page_ptr;
885                 pdpe64_t * pdpe = &(pdp[PDPE64_INDEX(vaddr)]);
886
887                 if (pdpe->present == 0) {
888                     return 1;
889                 }
890      
891                 if (pdpe->vmm_info == V3_LARGE_PG) {
892                     PrintError("1 Gigabyte pages not supported\n");
893                     return -1;
894
895                     pdpe->present = 0;
896                     return 1;
897                 }
898
899                 return 0;
900             }
901         case PAGE_PD64:
902             {
903                 pde64_t * pd = (pde64_t *)page_ptr;
904                 pde64_t * pde = &(pd[PDE64_INDEX(vaddr)]);
905
906                 if (pde->present == 0) {
907                     return 1;
908                 }
909       
910                 if (pde->vmm_info == V3_LARGE_PG) {
911                     pde->present = 0;
912                     return 1;
913                 }
914
915                 return 0;
916             }
917         case PAGE_PT64:
918             {
919                 pte64_t * pt = (pte64_t *)page_ptr;
920
921                 pt[PTE64_INDEX(vaddr)].present = 0;
922
923                 return 1;
924             }
925         default:
926             PrintError("Invalid Page Type\n");
927             return -1;
928
929     }
930
931     // should not get here
932     PrintError("Should not get here....\n");
933     return -1;
934 }
935
936
937 static inline int handle_shadow_invlpg_64(struct guest_info * core, addr_t vaddr) {
938     PrintDebug("INVLPG64 - %p\n",(void*)vaddr);
939
940     int ret =  v3_drill_host_pt_64(core, core->ctrl_regs.cr3, vaddr, invalidation_cb_64, NULL);
941     if (ret == -1) {
942         PrintError("Page table drill returned error.... \n");
943         PrintHostPageTree(core, vaddr, core->ctrl_regs.cr3);
944     }
945
946     return (ret == -1) ? -1 : 0; 
947 }
948
949 #endif