1 #include <palacios/vmm_shadow_paging.h>
4 #include <palacios/vmm.h>
5 #include <palacios/vm_guest_mem.h>
7 extern struct vmm_os_hooks * os_hooks;
10 int init_shadow_page_state(struct shadow_page_state * state) {
11 state->guest_mode = PDE32;
12 state->shadow_mode = PDE32;
15 state->shadow_cr3 = 0;
20 int handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
21 if (info->cpu_mode == PROTECTED_PG) {
22 return handle_shadow_pagefault32(info, fault_addr, error_code);
29 int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
30 pde32_t * guest_pde = NULL;
31 pde32_t * shadow_pde = (pde32_t *)CR3_TO_PDE32(info->shdw_pg_state.shadow_cr3);
32 addr_t guest_cr3 = CR3_TO_PDE32(info->shdw_pg_state.guest_cr3);
34 if (guest_pa_to_host_va(info, guest_cr3, (addr_t*)&guest_pde) == -1) {
38 if (error_code.present == 0) {
39 // Faulted because page was not present...
40 if (shadow_pde[PDE32_INDEX(fault_addr)].present) {
59 addr_t create_new_shadow_pt32(struct guest_info * info) {
62 V3_AllocPages(host_pde, 1);
63 memset(host_pde, 0, PAGE_SIZE);
65 return (addr_t)host_pde;
71 addr_t setup_shadow_pt32(struct guest_info * info, addr_t virt_cr3) {
72 addr_t cr3_guest_addr = CR3_TO_PDE32(virt_cr3);
74 pde32_t * host_pde = NULL;
77 // Setup up guest_pde to point to the PageDir in host addr
78 if (guest_pa_to_host_va(info, cr3_guest_addr, (addr_t*)&guest_pde) == -1) {
82 V3_AllocPages(host_pde, 1);
83 memset(host_pde, 0, PAGE_SIZE);
85 for (i = 0; i < MAX_PDE32_ENTRIES; i++) {
86 if (guest_pde[i].present == 1) {
90 if (guest_pa_to_host_va(info, PDE32_T_ADDR(guest_pde[i]), &pt_host_addr) == -1) {
94 if ((host_pte = setup_shadow_pte32(info, pt_host_addr)) == 0) {
98 host_pde[i].present = 1;
99 host_pde[i].pt_base_addr = PD32_BASE_ADDR(host_pte);
102 // Set Page DIR flags
107 PrintDebugPageTables(host_pde);
109 return (addr_t)host_pde;
114 addr_t setup_shadow_pte32(struct guest_info * info, addr_t pt_host_addr) {
115 pte32_t * guest_pte = (pte32_t *)pt_host_addr;
116 pte32_t * host_pte = NULL;
119 V3_AllocPages(host_pte, 1);
120 memset(host_pte, 0, PAGE_SIZE);
122 for (i = 0; i < MAX_PTE32_ENTRIES; i++) {
123 if (guest_pte[i].present == 1) {
124 addr_t guest_pa = PTE32_T_ADDR(guest_pte[i]);
125 shadow_mem_type_t page_type;
128 page_type = get_shadow_addr_type(info, guest_pa);
130 if (page_type == HOST_REGION_PHYSICAL_MEMORY) {
131 host_pa = get_shadow_addr(info, guest_pa);
135 // Setup various memory types
139 host_pte[i].page_base_addr = PT32_BASE_ADDR(host_pa);
140 host_pte[i].present = 1;
144 return (addr_t)host_pte;