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.


BIOS now runs, but dies because it has no devices....
[palacios.git] / palacios / src / palacios / vmm_mem.c
1 #include <palacios/vmm_mem.h>
2 #include <palacios/vmm.h>
3 #include <palacios/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 int add_shadow_region_passthrough( struct guest_info *  guest_info,
22                                    addr_t               guest_addr_start,
23                                    addr_t               guest_addr_end,
24                                    addr_t               host_addr_start)
25 {
26   shadow_region_t * entry = os_hooks->malloc(sizeof(shadow_region_t));
27
28   init_shadow_region(entry, guest_addr_start, guest_addr_end, 
29                      GUEST_REGION_PHYSICAL_MEMORY, HOST_REGION_PHYSICAL_MEMORY);
30   entry->host_addr.phys_addr.host_start = host_addr_start;
31
32   return add_shadow_region(&(guest_info->mem_map), entry);
33 }
34
35
36
37
38 void init_shadow_map(struct shadow_map * map) {
39   map->num_regions = 0;
40
41   map->head = NULL;
42 }
43
44
45 void free_shadow_map(struct shadow_map * map) {
46   shadow_region_t * cursor = map->head;
47   shadow_region_t * tmp = NULL;
48
49   while(cursor) {
50     tmp = cursor;
51     cursor = cursor->next;
52     VMMFree(tmp);
53   }
54
55   VMMFree(map);
56 }
57
58
59
60
61 int add_shadow_region(struct shadow_map * map,
62                       shadow_region_t * region) 
63 {
64   shadow_region_t * cursor = map->head;
65
66   PrintDebug("Adding Shadow Region: (0x%x-0x%x)\n", region->guest_start, region->guest_end);
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       PrintDebug("WTF?\n");
105       // This cannot happen!
106       // we should panic here
107       return -1;
108     }
109   }
110   
111   // This cannot happen
112   // We should panic here
113   return -1;
114 }
115
116
117 int delete_shadow_region(struct shadow_map * map,
118                          addr_t guest_start,
119                          addr_t guest_end) {
120   return -1;
121 }
122
123
124
125 shadow_region_t *get_shadow_region_by_index(struct shadow_map *  map,
126                                                uint_t index) {
127   shadow_region_t * reg = map->head;
128   uint_t i = 0;
129
130   while (reg) { 
131     if (i == index) { 
132       return reg;
133     }
134     reg = reg->next;
135     i++;
136   }
137   return NULL;
138 }
139
140
141 shadow_region_t * get_shadow_region_by_addr(struct shadow_map * map,
142                                                addr_t addr) {
143   shadow_region_t * reg = map->head;
144
145   while (reg) {
146     if ((reg->guest_start <= addr) && (reg->guest_end > addr)) {
147       return reg;
148     } else if (reg->guest_start > addr) {
149       return NULL;
150     } else {
151       reg = reg->next;
152     }
153   }
154   return NULL;
155 }
156
157
158
159 host_region_type_t lookup_shadow_map_addr(struct shadow_map * map, addr_t guest_addr, addr_t * host_addr) {
160   shadow_region_t * reg = get_shadow_region_by_addr(map, guest_addr);
161
162   if (!reg) {
163     // No mapping exists
164     return HOST_REGION_INVALID;
165   } else {
166     switch (reg->host_type) {
167     case HOST_REGION_PHYSICAL_MEMORY:
168      *host_addr = (guest_addr - reg->guest_start) + reg->host_addr.phys_addr.host_start;
169      return reg->host_type;
170     case HOST_REGION_MEMORY_MAPPED_DEVICE:
171     case HOST_REGION_UNALLOCATED:
172       // ... 
173     default:
174       *host_addr = 0;
175       return reg->host_type;
176     }
177   }
178 }
179
180
181 void print_shadow_map(struct shadow_map * map) {
182   shadow_region_t * cur = map->head;
183   int i = 0;
184
185   PrintDebug("Memory Layout (regions: %d) \n", map->num_regions);
186
187   while (cur) {
188     PrintDebug("%d:  0x%x - 0x%x (%s) -> ", i, cur->guest_start, cur->guest_end - 1,
189                cur->guest_type == GUEST_REGION_PHYSICAL_MEMORY ? "GUEST_REGION_PHYSICAL_MEMORY" :
190                cur->guest_type == GUEST_REGION_NOTHING ? "GUEST_REGION_NOTHING" :
191                cur->guest_type == GUEST_REGION_MEMORY_MAPPED_DEVICE ? "GUEST_REGION_MEMORY_MAPPED_DEVICE" :
192                "UNKNOWN");
193     if (cur->host_type == HOST_REGION_PHYSICAL_MEMORY || 
194         cur->host_type == HOST_REGION_UNALLOCATED ||
195         cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) { 
196       PrintDebug("0x%x", cur->host_addr.phys_addr.host_start);
197     }
198     PrintDebug("(%s)\n",
199                cur->host_type == HOST_REGION_PHYSICAL_MEMORY ? "HOST_REGION_PHYSICAL_MEMORY" :
200                cur->host_type == HOST_REGION_UNALLOCATED ? "HOST_REGION_UNALLOACTED" :
201                cur->host_type == HOST_REGION_NOTHING ? "HOST_REGION_NOTHING" :
202                cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE ? "HOST_REGION_MEMORY_MAPPED_DEVICE" :
203                cur->host_type == HOST_REGION_REMOTE ? "HOST_REGION_REMOTE" : 
204                cur->host_type == HOST_REGION_SWAPPED ? "HOST_REGION_SWAPPED" :
205                "UNKNOWN");
206     cur = cur->next;
207     i++;
208   }
209 }
210
211
212
213
214
215
216
217
218
219
220 #ifdef VMM_MEM_TEST
221
222
223 #include <stdlib.h>
224 #include <stdio.h>
225 #include <stdarg.h>
226
227
228
229
230
231 struct vmm_os_hooks * os_hooks;
232
233 void * TestMalloc(uint_t size) {
234   return malloc(size);
235 }
236
237 void * TestAllocatePages(int size) {
238   return malloc(4096 * size);
239 }
240
241
242 void TestPrint(const char * fmt, ...) {
243   va_list args;
244
245   va_start(args, fmt);
246   vprintf(fmt, args);
247   va_end(args);
248 }
249
250 int mem_list_add_test_1(  vmm_mem_list_t * list) {
251
252   uint_t offset = 0;
253
254   PrintDebug("\n\nTesting Memory List\n");
255
256   init_mem_list(list);
257
258   offset = PAGE_SIZE * 6;
259   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10));
260   add_mem_list_pages(list, offset, 10);
261   print_mem_list(list);
262
263
264   offset = 0;
265   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4);
266   add_mem_list_pages(list, offset, 4);
267   print_mem_list(list);
268
269   offset = PAGE_SIZE * 20;
270   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
271   add_mem_list_pages(list, offset, 1);
272   print_mem_list(list);
273
274   offset = PAGE_SIZE * 21;
275   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 3));
276   add_mem_list_pages(list, offset, 3);
277   print_mem_list(list);
278
279
280   offset = PAGE_SIZE * 10;
281   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30));
282   add_mem_list_pages(list, offset, 30);
283   print_mem_list(list);
284
285
286   offset = PAGE_SIZE * 5;
287   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
288   add_mem_list_pages(list, offset, 1);
289   print_mem_list(list);
290
291  
292
293   return 0;
294 }
295
296
297 int mem_layout_add_test_1(vmm_mem_layout_t * layout) {
298
299   
300   uint_t start = 0;
301   uint_t end = 0;
302
303   PrintDebug("\n\nTesting Memory Layout\n");
304
305   init_mem_layout(layout);
306
307   start = 0x6000;
308   end = 0x10000;;
309   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
310   add_guest_mem_range(layout, start, end);
311   print_mem_layout(layout);
312
313
314   start = 0x1000;
315   end = 0x3000;
316   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
317   add_guest_mem_range(layout, start, end);
318   print_mem_layout(layout);
319
320   start = 0x2000;
321   end = 0x6000;
322   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
323   add_guest_mem_range(layout, start, end);
324   print_mem_layout(layout);
325
326   start = 0x4000;
327   end = 0x5000;
328   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
329   add_guest_mem_range(layout, start, end);
330   print_mem_layout(layout);
331
332
333   start = 0x5000;
334   end = 0x7000;
335   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
336   add_guest_mem_range(layout, start, end);
337   print_mem_layout(layout);
338
339
340
341
342   return 0;
343 }
344
345
346
347 int main(int argc, char ** argv) {
348   struct vmm_os_hooks dummy_hooks;
349   os_hooks = &dummy_hooks;
350
351   vmm_mem_layout_t layout;
352   vmm_mem_list_t list;
353
354   os_hooks->malloc = &TestMalloc;
355   os_hooks->free = &free;
356   os_hooks->print_debug = &TestPrint;
357   os_hooks->allocate_pages = &TestAllocatePages;
358
359
360
361   printf("mem_list_add_test_1: %d\n", mem_list_add_test_1(&list));
362   printf("layout_add_test_1: %d\n", mem_layout_add_test_1(&layout));
363
364   return 0;
365 }
366 #endif
367
368
369
370
371
372