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.


0fc0e40bacc495d7e90c32facfd75187e0b25788
[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->shdw_pg_mode == SHADOW_PAGING) {
119     if (guest_info->mem_mode == PHYSICAL_MEM) {
120       // guest virtual address is the same as the physical
121       *guest_pa = guest_va;
122       return 0;
123     }
124     
125     
126
127     // Guest Is in Paged mode
128     switch (guest_info->cpu_mode) {
129     case PROTECTED:
130       {
131         addr_t tmp_pa = 0;
132         pde32_t * pde = 0;
133         addr_t guest_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.guest_cr3);
134
135
136         if (guest_pa_to_host_va(guest_info, guest_pde, (addr_t *)&pde) == -1) {
137           PrintDebug("In GVA->GPA: Invalid GPA(%x)->HVA PDE32 lookup\n", guest_pde);
138           return -1;
139         }
140
141
142         switch (pde32_lookup(pde, guest_va, &tmp_pa)) {
143         case PDE32_ENTRY_NOT_PRESENT: 
144           *guest_pa = 0;
145           return -1;
146         case PDE32_ENTRY_LARGE_PAGE:
147           *guest_pa = tmp_pa;
148           return 0;
149         case PDE32_ENTRY_PTE32:
150           {
151             pte32_t * pte = 0;
152
153
154             if (guest_pa_to_host_va(guest_info, tmp_pa, (addr_t*)&pte) == -1) {
155               PrintDebug("In GVA->GPA: Invalid GPA(%x)->HVA PTE32 lookup\n", guest_pa);
156               return -1;
157             }
158             
159             PrintDebug("PTE host addr=%x, GVA=%x, GPA=%x(should be 0)\n", pte, guest_va, *guest_pa);
160
161             if (pte32_lookup(pte, guest_va, guest_pa) != 0) {
162               PrintDebug("In GVA->GPA: PTE32 Lookup failure GVA=%x; PTE=%x\n", guest_va, pte);
163               //              PrintPT32(PDE32_INDEX(guest_va) << 22, pte);
164               return -1;
165             }
166
167             return 0;
168           }
169         default:
170           return -1;
171         }
172       }
173       case PROTECTED_PAE:
174         {
175           // Fill in
176         }
177       case LONG:
178         {
179           // Fill in
180         }
181     default:
182       return -1;
183     }
184   } else if (guest_info->shdw_pg_mode == NESTED_PAGING) {
185
186     // Fill in
187
188   } else {
189     return -1;
190   }
191
192
193   return 0;
194 }
195
196
197
198 /* !! Currently not implemented !! */
199 /* This will be a real pain.... its your standard page table walker in guest memory
200  * 
201  * For now we ignore it...
202  */
203 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
204   *guest_va = 0;
205   PrintDebug("ERROR!!: GPA->GVA Not Implemented!!\n");
206   return -1;
207 }
208
209
210 /**********************************/
211 /* GROUP 2                        */
212 /**********************************/
213
214
215 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
216   addr_t guest_pa = 0;
217
218   *host_pa = 0;
219
220   if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
221     PrintDebug("In GVA->HPA: Invalid GVA(%x)->GPA lookup\n", guest_va);
222     return -1;
223   }
224   
225   if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
226     PrintDebug("In GVA->HPA: Invalid GPA(%x)->HPA lookup\n", guest_pa);
227     return -1;
228   }
229
230   return 0;
231 }
232
233 /* !! Currently not implemented !! */
234 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
235   addr_t guest_pa = 0;
236
237   *guest_va = 0;
238
239   if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
240     PrintDebug("In HPA->GVA: Invalid HPA(%x)->GPA lookup\n", host_pa);
241     return -1;
242   }
243
244   if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
245     PrintDebug("In HPA->GVA: Invalid GPA(%x)->GVA lookup\n", guest_pa);
246     return -1;
247   }
248
249   return 0;
250 }
251
252
253
254
255 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
256   addr_t guest_pa = 0;
257   addr_t host_pa = 0;
258
259   *host_va = 0;
260
261   if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
262     PrintDebug("In GVA->HVA: Invalid GVA(%x)->GPA lookup\n", guest_va);
263     return -1;
264   }
265
266   if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
267     PrintDebug("In GVA->HVA: Invalid GPA(%x)->HPA lookup\n", guest_pa);
268     return -1;
269   }
270
271   if (host_pa_to_host_va(host_pa, host_va) != 0) {
272     PrintDebug("In GVA->HVA: Invalid HPA(%x)->HVA lookup\n", host_pa);
273     return -1;
274   }
275
276   return 0;
277 }
278
279
280 /* !! Currently not implemented !! */
281 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
282   addr_t host_pa = 0;
283   addr_t guest_pa = 0;
284
285   *guest_va = 0;
286
287   if (host_va_to_host_pa(host_va, &host_pa) != 0) {
288     PrintDebug("In HVA->GVA: Invalid HVA(%x)->HPA lookup\n", host_va);
289     return -1;
290   }
291
292   if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
293     PrintDebug("In HVA->GVA: Invalid HPA(%x)->GPA lookup\n", host_va);
294     return -1;
295   }
296
297   if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
298     PrintDebug("In HVA->GVA: Invalid GPA(%x)->GVA lookup\n", guest_pa);
299     return -1;
300   }
301
302   return 0;
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_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, char * dest) {
314   addr_t cursor = guest_va;
315   int bytes_read = 0;
316
317
318
319   while (count > 0) {
320     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
321     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
322     addr_t host_addr = 0;
323
324
325
326     /* JRL FIXME:
327      * This should be somewhere else....
328      */
329     /*  
330   addr_t tmp_addr;
331       
332     addr_t shadow_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.shadow_cr3);
333     
334     // Check the Shadow Page Tables first (Virtual TLB)
335     if (pt32_lookup((pde32_t *)shadow_pde, cursor, &tmp_addr) == 0) {
336       host_addr = tmp_addr;
337
338       if (host_pa_to_host_va(tmp_addr, &host_addr) != 0) {
339         return bytes_read;
340       }
341     } else {
342     
343       // No entry in the VTLB, do a guest page table walk
344    
345       if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
346         PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor);
347         return bytes_read;
348       }
349     }
350 */
351     /* JRL: END GRUESOME HACK */
352
353
354     
355     if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
356       PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor);
357       return bytes_read;
358     }
359     
360     
361
362     memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
363     
364     bytes_read += bytes_to_copy;
365     count -= bytes_to_copy;
366     cursor += bytes_to_copy;    
367   }
368
369   return bytes_read;
370 }
371
372
373
374
375
376
377 /* This is a straight address conversion + copy, 
378  *   except for the tiny little issue of crossing page boundries.....
379  */
380 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * dest) {
381   addr_t cursor = guest_pa;
382   int bytes_read = 0;
383
384   while (count > 0) {
385     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
386     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
387     addr_t host_addr = 0;
388
389     if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
390       return bytes_read;
391     }    
392     
393     /*
394       PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
395       PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
396       PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
397       PrintDebug("guest_pa=0x%x\n", guest_pa);
398     */
399     
400     memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
401
402     bytes_read += bytes_to_copy;
403     count -= bytes_to_copy;
404     cursor += bytes_to_copy;
405   }
406
407   return bytes_read;
408 }
409
410
411
412
413 /* This is a straight address conversion + copy, 
414  *   except for the tiny little issue of crossing page boundries.....
415  */
416 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, char * src) {
417   addr_t cursor = guest_pa;
418   int bytes_written = 0;
419
420   while (count > 0) {
421     int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
422     int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
423     addr_t host_addr;
424
425     if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
426       return bytes_written;
427     }
428
429
430     memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
431
432     bytes_written += bytes_to_copy;
433     count -= bytes_to_copy;
434     cursor += bytes_to_copy;    
435   }
436
437   return bytes_written;
438 }
439