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.


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