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.


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