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 / 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       PrintDebug("In HVA->HPA: Invalid HVA(%x)->HPA lookup\n", host_va);
19       return -1;
20     }
21   } else {
22     PrintDebug("In HVA->HPA: os_hooks not defined\n");
23     return -1;
24   }
25   return 0;
26 }
27
28
29 int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
30   if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {
31
32     *host_va = (addr_t)(os_hooks)->paddr_to_vaddr((void *)host_pa);
33     
34     if (*host_va == 0) {
35       PrintDebug("In HPA->HVA: Invalid HPA(%x)->HVA lookup\n", host_pa);
36       return -1;
37     }
38   } else {
39     PrintDebug("In HPA->HVA: os_hooks not defined\n");
40     return -1;
41   }
42   return 0;
43 }
44
45
46
47 int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_pa) {
48   // we use the shadow map here...
49   if (lookup_shadow_map_addr(&(guest_info->mem_map), guest_pa, host_pa) != HOST_REGION_PHYSICAL_MEMORY) {
50     PrintDebug("In GPA->HPA: Could not find address in shadow map (addr=%x)\n", guest_pa);
51     return -1;
52   }
53
54   return 0;
55 }
56
57
58 /* !! Currently not implemented !! */
59 // This is a scan of the shadow map
60 // For now we ignore it
61 // 
62 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
63   *guest_pa = 0;
64   PrintDebug("ERROR!!! HPA->GPA currently not implemented!!!\n");
65
66   return -1;
67 }
68
69
70
71 /**********************************/
72 /* GROUP 1                        */
73 /**********************************/
74
75
76 /* !! Currently not implemented !! */
77 // This will return negative until we implement host_pa_to_guest_pa()
78 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
79   addr_t host_pa = 0;
80   *guest_pa = 0;
81
82   if (host_va_to_host_pa(host_va, &host_pa) != 0) {
83     PrintDebug("In HVA->GPA: Invalid HVA(%x)->HPA lookup\n", host_va);
84     return -1;
85   }
86
87   if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
88     PrintDebug("In HVA->GPA: Invalid HPA(%x)->GPA lookup\n", host_pa);
89     return -1;
90   }
91
92   return 0;
93 }
94
95
96
97
98 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
99   addr_t host_pa = 0;
100
101   *host_va = 0;
102
103   if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
104     PrintDebug("In GPA->HVA: Invalid GPA(%x)->HPA lookup\n", guest_pa);
105     return -1;
106   }
107   
108   if (host_pa_to_host_va(host_pa, host_va) != 0) {
109     PrintDebug("In GPA->HVA: Invalid HPA(%x)->HVA lookup\n", host_pa);
110     return -1;
111   }
112
113   return 0;
114 }
115
116
117 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
118   if (guest_info->mem_mode == PHYSICAL_MEM) {
119     // guest virtual address is the same as the physical
120     *guest_pa = guest_va;
121     return 0;
122   }
123
124
125   if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
126     // Guest Is in Paged mode
127     switch (guest_info->cpu_mode) {
128     case PROTECTED:
129       {
130         addr_t tmp_pa = 0;
131         pde32_t * pde = 0;
132         addr_t guest_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.guest_cr3);
133
134
135         if (guest_pa_to_host_va(guest_info, guest_pde, (addr_t *)&pde) == -1) {
136           PrintDebug("In GVA->GPA: Invalid GPA(%x)->HVA PDE32 lookup\n", guest_pde);
137           return -1;
138         }
139
140
141         switch (pde32_lookup(pde, guest_va, &tmp_pa)) {
142         case PDE32_ENTRY_NOT_PRESENT: 
143           *guest_pa = 0;
144           return -1;
145         case PDE32_ENTRY_LARGE_PAGE:
146           *guest_pa = tmp_pa;
147           return 0;
148         case PDE32_ENTRY_PTE32:
149           {
150             pte32_t * pte = 0;
151
152
153             if (guest_pa_to_host_va(guest_info, tmp_pa, (addr_t*)&pte) == -1) {
154               PrintDebug("In GVA->GPA: Invalid GPA(%x)->HVA PTE32 lookup\n", guest_pa);
155               return -1;
156             }
157             
158             PrintDebug("PTE host addr=%x, GVA=%x, GPA=%x(should be 0)\n", pte, guest_va, *guest_pa);
159
160             if (pte32_lookup(pte, guest_va, guest_pa) != 0) {
161               PrintDebug("In GVA->GPA: PTE32 Lookup failure GVA=%x; PTE=%x\n", guest_va, pte);
162               //              PrintPT32(PDE32_INDEX(guest_va) << 22, pte);
163               return -1;
164             }
165
166             return 0;
167           }
168         default:
169           return -1;
170         }
171       }
172       case PROTECTED_PAE:
173         {
174           // Fill in
175         }
176       case LONG:
177         {
178           // Fill in
179         }
180     default:
181       return -1;
182     }
183   } else if (guest_info->shdw_pg_mode == NESTED_PAGING) {
184
185     // Fill in
186     return -1;
187   } else {
188     return -1;
189   }
190
191
192   return 0;
193 }
194
195
196
197 /* !! Currently not implemented !! */
198 /* This will be a real pain.... its your standard page table walker in guest memory
199  * 
200  * For now we ignore it...
201  */
202 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
203   *guest_va = 0;
204   PrintDebug("ERROR!!: GPA->GVA Not Implemented!!\n");
205   return -1;
206 }
207
208
209 /**********************************/
210 /* GROUP 2                        */
211 /**********************************/
212
213
214 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
215   addr_t guest_pa = 0;
216
217   *host_pa = 0;
218
219   if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
220     PrintDebug("In GVA->HPA: Invalid GVA(%x)->GPA lookup\n", guest_va);
221     return -1;
222   }
223   
224   if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
225     PrintDebug("In GVA->HPA: Invalid GPA(%x)->HPA lookup\n", guest_pa);
226     return -1;
227   }
228
229   return 0;
230 }
231
232 /* !! Currently not implemented !! */
233 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
234   addr_t guest_pa = 0;
235
236   *guest_va = 0;
237
238   if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
239     PrintDebug("In HPA->GVA: Invalid HPA(%x)->GPA lookup\n", host_pa);
240     return -1;
241   }
242
243   if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
244     PrintDebug("In HPA->GVA: Invalid GPA(%x)->GVA lookup\n", guest_pa);
245     return -1;
246   }
247
248   return 0;
249 }
250
251
252
253
254 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
255   addr_t guest_pa = 0;
256   addr_t host_pa = 0;
257
258   *host_va = 0;
259
260   if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
261     PrintDebug("In GVA->HVA: Invalid GVA(%x)->GPA lookup\n", guest_va);
262     return -1;
263   }
264
265   if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
266     PrintDebug("In GVA->HVA: Invalid GPA(%x)->HPA lookup\n", guest_pa);
267     return -1;
268   }
269
270   if (host_pa_to_host_va(host_pa, host_va) != 0) {
271     PrintDebug("In GVA->HVA: Invalid HPA(%x)->HVA lookup\n", host_pa);
272     return -1;
273   }
274
275   return 0;
276 }
277
278
279 /* !! Currently not implemented !! */
280 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
281   addr_t host_pa = 0;
282   addr_t guest_pa = 0;
283
284   *guest_va = 0;
285
286   if (host_va_to_host_pa(host_va, &host_pa) != 0) {
287     PrintDebug("In HVA->GVA: Invalid HVA(%x)->HPA lookup\n", host_va);
288     return -1;
289   }
290
291   if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
292     PrintDebug("In HVA->GVA: Invalid HPA(%x)->GPA lookup\n", host_va);
293     return -1;
294   }
295
296   if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
297     PrintDebug("In HVA->GVA: Invalid GPA(%x)->GVA lookup\n", guest_pa);
298     return -1;
299   }
300
301   return 0;
302 }
303
304
305
306
307
308
309 /* This is a straight address conversion + copy, 
310  *   except for the tiny little issue of crossing page boundries.....
311  */
312 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * dest) {
313   addr_t cursor = guest_va;
314   int bytes_read = 0;
315
316
317
318   while (count > 0) {
319     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
320     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
321     addr_t host_addr = 0;
322
323
324
325     /* JRL FIXME:
326      * This should be somewhere else....
327      */
328     /*  
329   addr_t tmp_addr;
330       
331     addr_t shadow_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.shadow_cr3);
332     
333     // Check the Shadow Page Tables first (Virtual TLB)
334     if (pt32_lookup((pde32_t *)shadow_pde, cursor, &tmp_addr) == 0) {
335       host_addr = tmp_addr;
336
337       if (host_pa_to_host_va(tmp_addr, &host_addr) != 0) {
338         return bytes_read;
339       }
340     } else {
341     
342       // No entry in the VTLB, do a guest page table walk
343    
344       if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
345         PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor);
346         return bytes_read;
347       }
348     }
349 */
350     /* JRL: END GRUESOME HACK */
351
352
353     
354     if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
355       PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor);
356       return bytes_read;
357     }
358     
359     
360
361     memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
362     
363     bytes_read += bytes_to_copy;
364     count -= bytes_to_copy;
365     cursor += bytes_to_copy;    
366   }
367
368   return bytes_read;
369 }
370
371
372
373
374
375
376 /* This is a straight address conversion + copy, 
377  *   except for the tiny little issue of crossing page boundries.....
378  */
379 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * dest) {
380   addr_t cursor = guest_pa;
381   int bytes_read = 0;
382
383   while (count > 0) {
384     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
385     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
386     addr_t host_addr = 0;
387
388     if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
389       return bytes_read;
390     }    
391     
392     /*
393       PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
394       PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
395       PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
396       PrintDebug("guest_pa=0x%x\n", guest_pa);
397     */
398     
399     memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
400
401     bytes_read += bytes_to_copy;
402     count -= bytes_to_copy;
403     cursor += bytes_to_copy;
404   }
405
406   return bytes_read;
407 }
408
409
410
411
412 /* This is a straight address conversion + copy, 
413  *   except for the tiny little issue of crossing page boundries.....
414  */
415 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * src) {
416   addr_t cursor = guest_pa;
417   int bytes_written = 0;
418
419   while (count > 0) {
420     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
421     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
422     addr_t host_addr;
423
424     if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
425       return bytes_written;
426     }
427
428
429     memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
430
431     bytes_written += bytes_to_copy;
432     count -= bytes_to_copy;
433     cursor += bytes_to_copy;    
434   }
435
436   return bytes_written;
437 }
438