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.


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