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.


eb7687e3bce5b45475ab5cae11a93a3ecbf7b6ea
[palacios.git] / palacios / src / palacios / vm_guest_mem.c
1 #include <palacios/vm_guest_mem.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vmm_paging.h>
4
5 extern struct vmm_os_hooks * os_hooks;
6
7
8 /**********************************/
9 /* GROUP 0                        */
10 /**********************************/
11
12 int host_va_to_host_pa(addr_t host_va, addr_t * host_pa) {
13   if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {
14
15     *host_pa = (addr_t)(os_hooks)->vaddr_to_paddr((void *)host_va);
16   
17     if (*host_pa == 0) {
18       return -1;
19     }
20   } else {
21     return -1;
22   }
23   return 0;
24 }
25
26
27 int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
28   if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {
29
30     *host_va = (addr_t)(os_hooks)->paddr_to_vaddr((void *)host_pa);
31     
32     if (*host_va == 0) {
33       return -1;
34     }
35   } else {
36     return -1;
37   }
38   return 0;
39 }
40
41
42
43 int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_pa) {
44   // we use the shadow map here...
45   if (lookup_shadow_map_addr(&(guest_info->mem_map), guest_pa, host_pa) != HOST_REGION_PHYSICAL_MEMORY) {
46     PrintDebug("Could not find address in shadow map (addr=%x)\n", guest_pa);
47     return -1;
48   }
49
50   return 0;
51 }
52
53
54 /* !! Currently not implemented !! */
55 // This is a scan of the shadow map
56 // For now we ignore it
57 // 
58 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
59   *guest_pa = 0;
60
61   return -1;
62 }
63
64
65
66 /**********************************/
67 /* GROUP 1                        */
68 /**********************************/
69
70
71 /* !! Currently not implemented !! */
72 // This will return negative until we implement host_pa_to_guest_pa()
73 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
74   addr_t host_pa;
75   *guest_pa = 0;
76
77   if (host_va_to_host_pa(host_va, &host_pa) != 0) {
78     return -1;
79   }
80
81   if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
82     return -1;
83   }
84
85   return 0;
86 }
87
88
89
90
91 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
92   addr_t host_pa;
93
94   *host_va = 0;
95
96   if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
97     return -1;
98   }
99   
100   if (host_pa_to_host_va(host_pa, host_va) != 0) {
101     return -1;
102   }
103
104   return 0;
105 }
106
107
108 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
109   if (guest_info->page_mode == SHADOW_PAGING) {
110     switch (guest_info->cpu_mode) {
111     case REAL:
112     case PROTECTED:
113     case LONG:
114     case PROTECTED_PAE:
115       // guest virtual address is the same as the physical
116       *guest_pa = guest_va;
117       return 0;
118     case PROTECTED_PG:
119       {
120         addr_t tmp_pa;
121         pde32_t * pde;
122         addr_t guest_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.guest_cr3.r_reg);
123
124         if (guest_pa_to_host_va(guest_info, guest_pde, (addr_t *)&pde) == -1) {
125           return -1;
126         }
127
128         switch (pde32_lookup(pde, guest_va, &tmp_pa)) {
129         case NOT_PRESENT: 
130           *guest_pa = 0;
131           return -1;
132         case LARGE_PAGE:
133           *guest_pa = tmp_pa;
134           return 0;
135         case PTE32:
136           {
137             pte32_t * pte;
138
139             if (guest_pa_to_host_va(guest_info, tmp_pa, (addr_t*)&pte) == -1) {
140               return -1;
141             }
142             
143             if (pte32_lookup(pte, guest_va, guest_pa) != 0) {
144               return -1;
145             }
146
147             return 0;
148           }
149         default:
150           return -1;
151         }
152       }
153       case PROTECTED_PAE_PG:
154         {
155           // Fill in
156         }
157       case LONG_PG:
158         {
159           // Fill in
160         }
161     default:
162       return -1;
163     }
164   } else if (guest_info->page_mode == NESTED_PAGING) {
165
166     // Fill in
167
168   } else {
169     return -1;
170   }
171
172
173   return 0;
174 }
175
176
177
178 /* !! Currently not implemented !! */
179 /* This will be a real pain.... its your standard page table walker in guest memory
180  * 
181  * For now we ignore it...
182  */
183 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
184   *guest_va = 0;
185   return -1;
186 }
187
188
189 /**********************************/
190 /* GROUP 2                        */
191 /**********************************/
192
193
194 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
195   addr_t guest_pa;
196
197   *host_pa = 0;
198
199   if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
200     return -1;
201   }
202   
203   if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
204     return -1;
205   }
206
207   return 0;
208 }
209
210 /* !! Currently not implemented !! */
211 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
212   addr_t guest_pa;
213
214   *guest_va = 0;
215
216   if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
217     return -1;
218   }
219
220   if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
221     return -1;
222   }
223
224   return 0;
225 }
226
227
228
229
230 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
231   addr_t guest_pa;
232   addr_t host_pa;
233
234   *host_va = 0;
235
236   if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
237     return -1;
238   }
239
240   if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
241     return -1;
242   }
243
244   if (host_pa_to_host_va(host_pa, host_va) != 0) {
245     return -1;
246   }
247
248   return 0;
249 }
250
251
252 /* !! Currently not implemented !! */
253 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
254   addr_t host_pa;
255   addr_t guest_pa;
256
257   *guest_va = 0;
258
259   if (host_va_to_host_pa(host_va, &host_pa) != 0) {
260     return -1;
261   }
262
263   if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
264     return -1;
265   }
266
267   if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
268     return -1;
269   }
270
271   return 0;
272 }
273
274
275
276
277
278
279 /* This is a straight address conversion + copy, 
280  *   except for the tiny little issue of crossing page boundries.....
281  */
282 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * dest) {
283   addr_t cursor = guest_va;
284   int bytes_read = 0;
285
286   while (count > 0) {
287     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
288     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
289     addr_t host_addr;
290
291     if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
292       return bytes_read;
293     }
294
295     memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
296     
297     bytes_read += bytes_to_copy;
298     count -= bytes_to_copy;
299     cursor += bytes_to_copy;    
300   }
301
302   return bytes_read;
303 }
304
305
306
307
308
309
310 /* This is a straight address conversion + copy, 
311  *   except for the tiny little issue of crossing page boundries.....
312  */
313 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * dest) {
314   addr_t cursor = guest_pa;
315   int bytes_read = 0;
316
317   while (count > 0) {
318     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
319     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
320     addr_t host_addr;
321
322     if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
323       return bytes_read;
324     }
325
326     
327     PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
328     PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
329     PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
330     PrintDebug("guest_pa=0x%x\n", guest_pa);
331     
332     
333     memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
334
335     bytes_read += bytes_to_copy;
336     count -= bytes_to_copy;
337     cursor += bytes_to_copy;
338   }
339
340   return bytes_read;
341 }
342
343
344
345
346 /* This is a straight address conversion + copy, 
347  *   except for the tiny little issue of crossing page boundries.....
348  */
349 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * src) {
350   addr_t cursor = guest_pa;
351   int bytes_written = 0;
352
353   while (count > 0) {
354     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
355     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
356     addr_t host_addr;
357
358     if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
359       return bytes_written;
360     }
361
362
363     memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
364
365     bytes_written += bytes_to_copy;
366     count -= bytes_to_copy;
367     cursor += bytes_to_copy;    
368   }
369
370   return bytes_written;
371 }
372