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.


b740788be26dc9d182e2d21b51ac21cbba11be7a
[palacios.git] / palacios / src / geekos / vmm_mem.c
1 #include <geekos/vmm_mem.h>
2 #include <geekos/vmm.h>
3 #include <geekos/vmm_util.h>
4
5 extern struct vmm_os_hooks * os_hooks;
6
7
8 void init_shadow_region(shadow_region_t * entry,
9                         addr_t               guest_addr_start,
10                         addr_t               guest_addr_end,
11                         guest_region_type_t  guest_region_type,
12                         host_region_type_t   host_region_type)
13 {
14   entry->guest_type = guest_region_type;
15   entry->guest_start = guest_addr_start;
16   entry->guest_end = guest_addr_end;
17   entry->host_type = host_region_type;
18   entry->next=entry->prev = NULL;
19 }
20
21 void init_shadow_region_physical(shadow_region_t * entry,
22                                  addr_t               guest_addr_start,
23                                  addr_t               guest_addr_end,
24                                  guest_region_type_t  guest_region_type,
25                                  addr_t               host_addr_start,
26                                  host_region_type_t   host_region_type)
27 {
28   init_shadow_region(entry, guest_addr_start, guest_addr_end, guest_region_type, host_region_type);
29   entry->host_addr.phys_addr.host_start = host_addr_start;
30
31 }
32                     
33
34 void init_shadow_map(shadow_map_t * map) {
35   map->num_regions = 0;
36
37   map->head = NULL;
38 }
39
40
41 void free_shadow_map(shadow_map_t * map) {
42   shadow_region_t * cursor = map->head;
43   shadow_region_t * tmp = NULL;
44
45   while(cursor) {
46     tmp = cursor;
47     cursor = cursor->next;
48     VMMFree(tmp);
49   }
50
51   VMMFree(map);
52 }
53
54
55
56 /* This is slightly different semantically from the mem list, in that
57  * we don't allow overlaps we could probably allow overlappig regions
58  * of the same type... but I'll let someone else deal with that
59  */
60 int add_shadow_region(shadow_map_t * map,
61                       shadow_region_t * region) 
62 {
63   shadow_region_t * cursor = map->head;
64
65   if ((!cursor) || (cursor->guest_start >= region->guest_end)) {
66     region->prev = NULL;
67     region->next = cursor;
68     map->num_regions++;
69     map->head = region;
70     return 0;
71   }
72
73   while (cursor) {
74     // Check if it overlaps with the current cursor
75     if ((cursor->guest_end > region->guest_start) && (cursor->guest_start < region->guest_start)) {
76       // overlaps not allowed
77       return -1;
78     }
79     
80     if (!(cursor->next)) {
81       // add to the end of the list
82       cursor->next = region;
83       region->prev = cursor;
84       region->next = NULL;
85       map->num_regions++;
86       return 0;
87     } else if (cursor->next->guest_start >= region->guest_end) {
88       // add here
89       region->next = cursor->next;
90       region->prev = cursor;
91       
92       cursor->next->prev = region;
93       cursor->next = region;
94
95       map->num_regions++;
96       
97       return 0;
98     } else if (cursor->next->guest_end < region->guest_start) {
99       cursor = cursor->next;
100     } else {
101       // This cannot happen!
102       // we should panic here
103       return -1;
104     }
105   }
106   
107   // This cannot happen
108   // We should panic here
109   return -1;
110 }
111
112
113 int delete_shadow_region(shadow_map_t * map,
114                          addr_t guest_start,
115                          addr_t guest_end) {
116   return -1;
117 }
118
119
120
121 shadow_region_t *get_shadow_region_by_index(shadow_map_t *  map,
122                                                uint_t index) {
123   shadow_region_t * reg = map->head;
124   uint_t i = 0;
125
126   while (reg) { 
127     if (i == index) { 
128       return reg;
129     }
130     reg = reg->next;
131     i++;
132   }
133   return NULL;
134 }
135
136
137 shadow_region_t * get_shadow_region_by_addr(shadow_map_t * map,
138                                                addr_t addr) {
139   shadow_region_t * reg = map->head;
140
141   while (reg) {
142     if ((reg->guest_start <= addr) && (reg->guest_end > addr)) {
143       return reg;
144     } else if (reg->guest_start > addr) {
145       return NULL;
146     } else {
147       reg = reg->next;
148     }
149   }
150   return NULL;
151 }
152
153
154
155 host_region_type_t lookup_shadow_map_addr(shadow_map_t * map, addr_t guest_addr, addr_t * host_addr) {
156   shadow_region_t * reg = get_shadow_region_by_addr(map, guest_addr);
157
158   if (!reg) {
159     // No mapping exists
160     return HOST_REGION_INVALID;
161   } else {
162     switch (reg->host_type) {
163     case HOST_REGION_PHYSICAL_MEMORY:
164      *host_addr = (guest_addr - reg->guest_start) + reg->host_addr.phys_addr.host_start;
165      return reg->host_type;
166     case HOST_REGION_MEMORY_MAPPED_DEVICE:
167     case HOST_REGION_UNALLOCATED:
168       // ... 
169     default:
170       *host_addr = 0;
171       return reg->host_type;
172     }
173   }
174 }
175
176 /*
177 int guest_paddr_to_host_paddr(shadow_region_t * entry, 
178                         addr_t guest_addr,
179                         addr_t * host_addr) {
180
181   if (!((guest_addr >= entry->guest_start) && 
182         (guest_addr < entry->guest_end))) { 
183     return -1;
184   }
185
186   switch (entry->host_type) { 
187   case HOST_REGION_PHYSICAL_MEMORY:
188   case HOST_REGION_MEMORY_MAPPED_DEVICE:
189   case HOST_REGION_UNALLOCATED:
190     *host_addr = (guest_addr-entry->guest_start) + entry->host_addr.phys_addr.host_start;
191     return 0;
192     break;
193   default:
194     return -1;
195     break;
196   }
197 }
198
199 */
200
201
202 void print_shadow_map(shadow_map_t * map) {
203   shadow_region_t * cur = map->head;
204   int i = 0;
205
206   PrintDebug("Memory Layout (regions: %d) \n", map->num_regions);
207
208   while (cur) {
209     PrintDebug("%d:  0x%x - 0x%x (%s) -> ", i, cur->guest_start, cur->guest_end - 1,
210                cur->guest_type == GUEST_REGION_PHYSICAL_MEMORY ? "GUEST_REGION_PHYSICAL_MEMORY" :
211                cur->guest_type == GUEST_REGION_NOTHING ? "GUEST_REGION_NOTHING" :
212                cur->guest_type == GUEST_REGION_MEMORY_MAPPED_DEVICE ? "GUEST_REGION_MEMORY_MAPPED_DEVICE" :
213                "UNKNOWN");
214     if (cur->host_type == HOST_REGION_PHYSICAL_MEMORY || 
215         cur->host_type == HOST_REGION_UNALLOCATED ||
216         cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) { 
217       PrintDebug("0x%x", cur->host_addr.phys_addr.host_start);
218     }
219     PrintDebug("(%s)\n",
220                cur->host_type == HOST_REGION_PHYSICAL_MEMORY ? "HOST_REGION_PHYSICAL_MEMORY" :
221                cur->host_type == HOST_REGION_UNALLOCATED ? "HOST_REGION_UNALLOACTED" :
222                cur->host_type == HOST_REGION_NOTHING ? "HOST_REGION_NOTHING" :
223                cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE ? "HOST_REGION_MEMORY_MAPPED_DEVICE" :
224                cur->host_type == HOST_REGION_REMOTE ? "HOST_REGION_REMOTE" : 
225                cur->host_type == HOST_REGION_SWAPPED ? "HOST_REGION_SWAPPED" :
226                "UNKNOWN");
227     cur = cur->next;
228     i++;
229   }
230 }
231
232
233
234
235
236
237
238
239
240
241 #ifdef VMM_MEM_TEST
242
243
244 #include <stdlib.h>
245 #include <stdio.h>
246 #include <stdarg.h>
247
248
249
250
251
252 struct vmm_os_hooks * os_hooks;
253
254 void * TestMalloc(uint_t size) {
255   return malloc(size);
256 }
257
258 void * TestAllocatePages(int size) {
259   return malloc(4096 * size);
260 }
261
262
263 void TestPrint(const char * fmt, ...) {
264   va_list args;
265
266   va_start(args, fmt);
267   vprintf(fmt, args);
268   va_end(args);
269 }
270
271 int mem_list_add_test_1(  vmm_mem_list_t * list) {
272
273   uint_t offset = 0;
274
275   PrintDebug("\n\nTesting Memory List\n");
276
277   init_mem_list(list);
278
279   offset = PAGE_SIZE * 6;
280   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10));
281   add_mem_list_pages(list, offset, 10);
282   print_mem_list(list);
283
284
285   offset = 0;
286   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4);
287   add_mem_list_pages(list, offset, 4);
288   print_mem_list(list);
289
290   offset = PAGE_SIZE * 20;
291   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
292   add_mem_list_pages(list, offset, 1);
293   print_mem_list(list);
294
295   offset = PAGE_SIZE * 21;
296   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 3));
297   add_mem_list_pages(list, offset, 3);
298   print_mem_list(list);
299
300
301   offset = PAGE_SIZE * 10;
302   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30));
303   add_mem_list_pages(list, offset, 30);
304   print_mem_list(list);
305
306
307   offset = PAGE_SIZE * 5;
308   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
309   add_mem_list_pages(list, offset, 1);
310   print_mem_list(list);
311
312  
313
314   return 0;
315 }
316
317
318 int mem_layout_add_test_1(vmm_mem_layout_t * layout) {
319
320   
321   uint_t start = 0;
322   uint_t end = 0;
323
324   PrintDebug("\n\nTesting Memory Layout\n");
325
326   init_mem_layout(layout);
327
328   start = 0x6000;
329   end = 0x10000;;
330   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
331   add_guest_mem_range(layout, start, end);
332   print_mem_layout(layout);
333
334
335   start = 0x1000;
336   end = 0x3000;
337   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
338   add_guest_mem_range(layout, start, end);
339   print_mem_layout(layout);
340
341   start = 0x2000;
342   end = 0x6000;
343   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
344   add_guest_mem_range(layout, start, end);
345   print_mem_layout(layout);
346
347   start = 0x4000;
348   end = 0x5000;
349   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
350   add_guest_mem_range(layout, start, end);
351   print_mem_layout(layout);
352
353
354   start = 0x5000;
355   end = 0x7000;
356   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
357   add_guest_mem_range(layout, start, end);
358   print_mem_layout(layout);
359
360
361
362
363   return 0;
364 }
365
366
367
368 int main(int argc, char ** argv) {
369   struct vmm_os_hooks dummy_hooks;
370   os_hooks = &dummy_hooks;
371
372   vmm_mem_layout_t layout;
373   vmm_mem_list_t list;
374
375   os_hooks->malloc = &TestMalloc;
376   os_hooks->free = &free;
377   os_hooks->print_debug = &TestPrint;
378   os_hooks->allocate_pages = &TestAllocatePages;
379
380
381
382   printf("mem_list_add_test_1: %d\n", mem_list_add_test_1(&list));
383   printf("layout_add_test_1: %d\n", mem_layout_add_test_1(&layout));
384
385   return 0;
386 }
387 #endif
388
389
390
391
392
393