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.


code restructuring
[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 /* 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 void print_shadow_map(shadow_map_t * map) {
178   shadow_region_t * cur = map->head;
179   int i = 0;
180
181   PrintDebug("Memory Layout (regions: %d) \n", map->num_regions);
182
183   while (cur) {
184     PrintDebug("%d:  0x%x - 0x%x (%s) -> ", i, cur->guest_start, cur->guest_end - 1,
185                cur->guest_type == GUEST_REGION_PHYSICAL_MEMORY ? "GUEST_REGION_PHYSICAL_MEMORY" :
186                cur->guest_type == GUEST_REGION_NOTHING ? "GUEST_REGION_NOTHING" :
187                cur->guest_type == GUEST_REGION_MEMORY_MAPPED_DEVICE ? "GUEST_REGION_MEMORY_MAPPED_DEVICE" :
188                "UNKNOWN");
189     if (cur->host_type == HOST_REGION_PHYSICAL_MEMORY || 
190         cur->host_type == HOST_REGION_UNALLOCATED ||
191         cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE) { 
192       PrintDebug("0x%x", cur->host_addr.phys_addr.host_start);
193     }
194     PrintDebug("(%s)\n",
195                cur->host_type == HOST_REGION_PHYSICAL_MEMORY ? "HOST_REGION_PHYSICAL_MEMORY" :
196                cur->host_type == HOST_REGION_UNALLOCATED ? "HOST_REGION_UNALLOACTED" :
197                cur->host_type == HOST_REGION_NOTHING ? "HOST_REGION_NOTHING" :
198                cur->host_type == HOST_REGION_MEMORY_MAPPED_DEVICE ? "HOST_REGION_MEMORY_MAPPED_DEVICE" :
199                cur->host_type == HOST_REGION_REMOTE ? "HOST_REGION_REMOTE" : 
200                cur->host_type == HOST_REGION_SWAPPED ? "HOST_REGION_SWAPPED" :
201                "UNKNOWN");
202     cur = cur->next;
203     i++;
204   }
205 }
206
207
208
209
210
211
212
213
214
215
216 #ifdef VMM_MEM_TEST
217
218
219 #include <stdlib.h>
220 #include <stdio.h>
221 #include <stdarg.h>
222
223
224
225
226
227 struct vmm_os_hooks * os_hooks;
228
229 void * TestMalloc(uint_t size) {
230   return malloc(size);
231 }
232
233 void * TestAllocatePages(int size) {
234   return malloc(4096 * size);
235 }
236
237
238 void TestPrint(const char * fmt, ...) {
239   va_list args;
240
241   va_start(args, fmt);
242   vprintf(fmt, args);
243   va_end(args);
244 }
245
246 int mem_list_add_test_1(  vmm_mem_list_t * list) {
247
248   uint_t offset = 0;
249
250   PrintDebug("\n\nTesting Memory List\n");
251
252   init_mem_list(list);
253
254   offset = PAGE_SIZE * 6;
255   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 10));
256   add_mem_list_pages(list, offset, 10);
257   print_mem_list(list);
258
259
260   offset = 0;
261   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + PAGE_SIZE * 4);
262   add_mem_list_pages(list, offset, 4);
263   print_mem_list(list);
264
265   offset = PAGE_SIZE * 20;
266   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
267   add_mem_list_pages(list, offset, 1);
268   print_mem_list(list);
269
270   offset = PAGE_SIZE * 21;
271   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 3));
272   add_mem_list_pages(list, offset, 3);
273   print_mem_list(list);
274
275
276   offset = PAGE_SIZE * 10;
277   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 30));
278   add_mem_list_pages(list, offset, 30);
279   print_mem_list(list);
280
281
282   offset = PAGE_SIZE * 5;
283   PrintDebug("Adding 0x%x - 0x%x\n", offset, offset + (PAGE_SIZE * 1));
284   add_mem_list_pages(list, offset, 1);
285   print_mem_list(list);
286
287  
288
289   return 0;
290 }
291
292
293 int mem_layout_add_test_1(vmm_mem_layout_t * layout) {
294
295   
296   uint_t start = 0;
297   uint_t end = 0;
298
299   PrintDebug("\n\nTesting Memory Layout\n");
300
301   init_mem_layout(layout);
302
303   start = 0x6000;
304   end = 0x10000;;
305   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
306   add_guest_mem_range(layout, start, end);
307   print_mem_layout(layout);
308
309
310   start = 0x1000;
311   end = 0x3000;
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   start = 0x2000;
317   end = 0x6000;
318   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
319   add_guest_mem_range(layout, start, end);
320   print_mem_layout(layout);
321
322   start = 0x4000;
323   end = 0x5000;
324   PrintDebug("Adding 0x%x - 0x%x\n", start, end);
325   add_guest_mem_range(layout, start, end);
326   print_mem_layout(layout);
327
328
329   start = 0x5000;
330   end = 0x7000;
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
337
338   return 0;
339 }
340
341
342
343 int main(int argc, char ** argv) {
344   struct vmm_os_hooks dummy_hooks;
345   os_hooks = &dummy_hooks;
346
347   vmm_mem_layout_t layout;
348   vmm_mem_list_t list;
349
350   os_hooks->malloc = &TestMalloc;
351   os_hooks->free = &free;
352   os_hooks->print_debug = &TestPrint;
353   os_hooks->allocate_pages = &TestAllocatePages;
354
355
356
357   printf("mem_list_add_test_1: %d\n", mem_list_add_test_1(&list));
358   printf("layout_add_test_1: %d\n", mem_layout_add_test_1(&layout));
359
360   return 0;
361 }
362 #endif
363
364
365
366
367
368