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.


81719a4484134f5c8306002bc5edbaacb18756b0
[palacios.git] / palacios / src / geekos / vmm_paging.c
1 #include <geekos/vmm_paging.h>
2
3
4
5
6
7 extern struct vmm_os_hooks * os_hooks;
8
9
10
11
12 /* We generate a page table to correspond to a given memory layout
13  * pulling pages from the mem_list when necessary
14  * If there are any gaps in the layout, we add them as unmapped pages
15  */
16 pde_t * generate_guest_page_tables(vmm_mem_layout_t * layout, vmm_mem_list_t * list) {
17   ullong_t current_page_addr = 0;
18   uint_t layout_index = 0;
19   uint_t list_index = 0;
20   ullong_t layout_addr = 0;
21   int i, j;
22   uint_t num_entries = layout->num_pages;  // The number of pages left in the layout
23
24
25   
26
27   pde_t * pde = os_hooks->allocate_pages(1);
28
29   for (i = 0; i < MAX_PAGE_DIR_ENTRIES; i++) {
30     if (num_entries == 0) { 
31       pde[i].present = 0;
32       pde[i].flags = 0;
33       pde[i].accessed = 0;
34       pde[i].reserved = 0;
35       pde[i].large_pages = 0;
36       pde[i].global_page = 0;
37       pde[i].vmm_info = 0;
38       pde[i].pt_base_addr = 0;
39     } else {
40       pte_t * pte = os_hooks->allocate_pages(1);
41
42       pde[i].present = 1;
43       pde[i].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER;
44       pde[i].accessed = 0;
45       pde[i].reserved = 0;
46       pde[i].large_pages = 0;
47       pde[i].global_page = 0;
48       pde[i].vmm_info = 0;
49       pde[i].pt_base_addr = PAGE_ALLIGNED_ADDR(pte);
50
51
52
53       for (j = 0; j < MAX_PAGE_TABLE_ENTRIES; j++) {
54         layout_addr = get_mem_layout_addr(layout, layout_index);
55         
56         if ((current_page_addr < layout_addr) || (num_entries == 0)) {
57           // We have a gap in the layout, fill with unmapped page
58           pte[j].present = 0;
59           pte[j].flags = 0;
60           pte[j].accessed = 0;
61           pte[j].dirty = 0;
62           pte[j].pte_attr = 0;
63           pte[j].global_page = 0;
64           pte[j].vmm_info = 0;
65           pte[j].page_base_addr = 0;
66
67           current_page_addr += PAGE_SIZE;
68         } else if (current_page_addr == layout_addr) {
69           // Set up the Table entry to map correctly to the layout region
70           layout_region_t * page_region = get_layout_cursor(layout, layout_addr);
71
72           if (page_region->type == UNMAPPED) {
73             pte[j].present = 0;
74             pte[j].flags = 0;
75           } else {
76             pte[j].present = 1;
77             pte[j].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER;
78           }         
79
80           pte[j].accessed = 0;
81           pte[j].dirty = 0;
82           pte[j].pte_attr = 0;
83           pte[j].global_page = 0;
84           pte[j].vmm_info = 0;
85
86           if (page_region->type == UNMAPPED) {
87             pte[j].page_base_addr = 0;
88           } else if (page_region->type == SHARED) {
89             pte[j].page_base_addr = page_region->host_addr >> 12;
90           } else if (page_region->type == GUEST) {
91             addr_t list_addr =  get_mem_list_addr(list, list_index++);
92             
93             if (list_addr == -1) {
94               // error
95               // cleanup....
96               return NULL;
97             }
98             PrintDebug("Adding guest page (%x)\n", list_addr);
99             pte[j].page_base_addr = list_addr >> 12;
100           }
101
102           num_entries--;
103           current_page_addr += PAGE_SIZE;
104           layout_index++;
105         } else {
106           // error
107           PrintDebug("Error creating page table...\n");
108           // cleanup
109           return NULL;
110         }
111       }
112     }
113   }
114
115   return pde;
116 }
117
118
119
120
121 void PrintPDE(void * virtual_address, pde_t * pde)
122 {
123   PrintDebug("PDE %p -> %p : present=%x, flags=%x, accessed=%x, reserved=%x, largePages=%x, globalPage=%x, kernelInfo=%x\n",
124               virtual_address,
125               (void *) (pde->pt_base_addr << PAGE_POWER),
126               pde->present,
127               pde->flags,
128               pde->accessed,
129               pde->reserved,
130               pde->large_pages,
131               pde->global_page,
132               pde->vmm_info);
133 }
134   
135 void PrintPTE(void * virtual_address, pte_t * pte)
136 {
137   PrintDebug("PTE %p -> %p : present=%x, flags=%x, accessed=%x, dirty=%x, pteAttribute=%x, globalPage=%x, vmm_info=%x\n",
138               virtual_address,
139               (void*)(pte->page_base_addr << PAGE_POWER),
140               pte->present,
141               pte->flags,
142               pte->accessed,
143               pte->dirty,
144               pte->pte_attr,
145               pte->global_page,
146               pte->vmm_info);
147 }
148
149
150
151 void PrintPD(pde_t * pde)
152 {
153   int i;
154
155   PrintDebug("Page Directory at %p:\n", pde);
156   for (i = 0; (i < MAX_PAGE_DIR_ENTRIES) && pde[i].present; i++) { 
157     PrintPDE((void*)(PAGE_SIZE * MAX_PAGE_TABLE_ENTRIES * i), &(pde[i]));
158   }
159 }
160
161 void PrintPT(void * starting_address, pte_t * pte) 
162 {
163   int i;
164
165   //  PrintDebug("Page Table at %p:\n", pte);
166   for (i = 0; (i < MAX_PAGE_TABLE_ENTRIES) && pte[i].present; i++) { 
167     PrintPTE(starting_address + (PAGE_SIZE * i), &(pte[i]));
168   }
169 }
170
171
172
173
174
175 void PrintDebugPageTables(pde_t * pde)
176 {
177   int i;
178   
179   PrintDebug("Dumping the pages starting with the pde page at %p\n", pde);
180
181   for (i = 0; (i < MAX_PAGE_DIR_ENTRIES) && pde[i].present; i++) { 
182     PrintPDE((void *)(PAGE_SIZE * MAX_PAGE_TABLE_ENTRIES * i), &(pde[i]));
183     PrintPT((void *)(PAGE_SIZE * MAX_PAGE_TABLE_ENTRIES * i), (void *)(pde[i].pt_base_addr << PAGE_POWER));
184   }
185 }
186     
187