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.


*** empty log message ***
[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
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 = (shadow_region_t *)V3_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     V3_Free(tmp);
53   }
54
55   V3_Free(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 host_region_type_t get_shadow_addr_type(struct guest_info * info, addr_t guest_addr) {
159   shadow_region_t * reg = get_shadow_region_by_addr(&(info->mem_map), guest_addr);
160
161   if (!reg) {
162     return HOST_REGION_INVALID;
163   } else {
164     return reg->host_type;
165   }
166 }
167
168 addr_t get_shadow_addr(struct guest_info * info, addr_t guest_addr) {
169   shadow_region_t * reg = get_shadow_region_by_addr(&(info->mem_map), guest_addr);
170
171   if (!reg) {
172     return 0;
173   } else {
174     return (guest_addr - reg->guest_start) + reg->host_addr.phys_addr.host_start;
175   }
176 }
177
178
179 host_region_type_t lookup_shadow_map_addr(struct shadow_map * map, addr_t guest_addr, addr_t * host_addr) {
180   shadow_region_t * reg = get_shadow_region_by_addr(map, guest_addr);
181
182   if (!reg) {
183     // No mapping exists
184     return HOST_REGION_INVALID;
185   } else {
186     switch (reg->host_type) {
187     case HOST_REGION_PHYSICAL_MEMORY:
188      *host_addr = (guest_addr - reg->guest_start) + reg->host_addr.phys_addr.host_start;
189      return reg->host_type;
190     case HOST_REGION_MEMORY_MAPPED_DEVICE:
191     case HOST_REGION_UNALLOCATED:
192       // ... 
193     default:
194       *host_addr = 0;
195       return reg->host_type;
196     }
197   }
198 }
199
200
201 void print_shadow_map(struct shadow_map * map) {
202   shadow_region_t * cur = map->head;
203   int i = 0;
204
205   PrintDebug("Memory Layout (regions: %d) \n", map->num_regions);
206
207   while (cur) {
208     PrintDebug("%d:  0x%x - 0x%x (%s) -> ", i, cur->guest_start, cur->guest_end - 1,
209                cur->guest_type == GUEST_REGION_PHYSICAL_MEMORY ? "GUEST_REGION_PHYSICAL_MEMORY" :
210                cur->guest_type == GUEST_REGION_NOTHING ? "GUEST_REGION_NOTHING" :
211                cur->guest_type == GUEST_REGION_MEMORY_MAPPED_DEVICE ? "GUEST_REGION_MEMORY_MAPPED_DEVICE" :
212                "UNKNOWN");
213     if (cur->host_type == HOST_REGION_PHYSICAL_MEMORY || 
214         cur->host_type == HOST_REGION_UNALLOCATED ||
215         cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) { 
216       PrintDebug("0x%x", cur->host_addr.phys_addr.host_start);
217     }
218     PrintDebug("(%s)\n",
219                cur->host_type == HOST_REGION_PHYSICAL_MEMORY ? "HOST_REGION_PHYSICAL_MEMORY" :
220                cur->host_type == HOST_REGION_UNALLOCATED ? "HOST_REGION_UNALLOACTED" :
221                cur->host_type == HOST_REGION_NOTHING ? "HOST_REGION_NOTHING" :
222                cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE ? "HOST_REGION_MEMORY_MAPPED_DEVICE" :
223                cur->host_type == HOST_REGION_REMOTE ? "HOST_REGION_REMOTE" : 
224                cur->host_type == HOST_REGION_SWAPPED ? "HOST_REGION_SWAPPED" :
225                "UNKNOWN");
226     cur = cur->next;
227     i++;
228   }
229 }
230
231
232
233
234
235
236
237
238
239
240 #ifdef VMM_MEM_TEST
241
242
243 #include <stdlib.h>
244 #include <stdio.h>
245 #include <stdarg.h>
246
247
248
249
250
251 struct vmm_os_hooks * os_hooks;
252
253 void * TestMalloc(uint_t size) {
254   return malloc(size);
255 }
256
257 void * TestAllocatePages(int size) {
258   return malloc(4096 * size);
259 }
260
261
262 void TestPrint(const char * fmt, ...) {
263   va_list args;
264
265   va_start(args, fmt);
266   vprintf(fmt, args);
267   va_end(args);
268 }
269
270 int mem_list_add_test_1(  vmm_mem_list_t * list) {
271
272   uint_t offset = 0;
273
274   PrintDebug("\n\nTesting Memory List\n");
275
276   init_mem_list(list);
277
278   offset = PAGE_SIZE * 6;
279   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10));
280   add_mem_list_pages(list, offset, 10);
281   print_mem_list(list);
282
283
284   offset = 0;
285   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4);
286   add_mem_list_pages(list, offset, 4);
287   print_mem_list(list);
288
289   offset = PAGE_SIZE * 20;
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   offset = PAGE_SIZE * 21;
295   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 3));
296   add_mem_list_pages(list, offset, 3);
297   print_mem_list(list);
298
299
300   offset = PAGE_SIZE * 10;
301   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30));
302   add_mem_list_pages(list, offset, 30);
303   print_mem_list(list);
304
305
306   offset = PAGE_SIZE * 5;
307   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
308   add_mem_list_pages(list, offset, 1);
309   print_mem_list(list);
310
311  
312
313   return 0;
314 }
315
316
317 int mem_layout_add_test_1(vmm_mem_layout_t * layout) {
318
319   
320   uint_t start = 0;
321   uint_t end = 0;
322
323   PrintDebug("\n\nTesting Memory Layout\n");
324
325   init_mem_layout(layout);
326
327   start = 0x6000;
328   end = 0x10000;;
329   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
330   add_guest_mem_range(layout, start, end);
331   print_mem_layout(layout);
332
333
334   start = 0x1000;
335   end = 0x3000;
336   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
337   add_guest_mem_range(layout, start, end);
338   print_mem_layout(layout);
339
340   start = 0x2000;
341   end = 0x6000;
342   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
343   add_guest_mem_range(layout, start, end);
344   print_mem_layout(layout);
345
346   start = 0x4000;
347   end = 0x5000;
348   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
349   add_guest_mem_range(layout, start, end);
350   print_mem_layout(layout);
351
352
353   start = 0x5000;
354   end = 0x7000;
355   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
356   add_guest_mem_range(layout, start, end);
357   print_mem_layout(layout);
358
359
360
361
362   return 0;
363 }
364
365
366
367 int main(int argc, char ** argv) {
368   struct vmm_os_hooks dummy_hooks;
369   os_hooks = &dummy_hooks;
370
371   vmm_mem_layout_t layout;
372   vmm_mem_list_t list;
373
374   os_hooks->malloc = &TestMalloc;
375   os_hooks->free = &free;
376   os_hooks->print_debug = &TestPrint;
377   os_hooks->allocate_pages = &TestAllocatePages;
378
379
380
381   printf("mem_list_add_test_1: %d\n", mem_list_add_test_1(&list));
382   printf("layout_add_test_1: %d\n", mem_layout_add_test_1(&layout));
383
384   return 0;
385 }
386 #endif
387
388
389
390
391
392