1 #include <palacios/vm_guest_mem.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vmm_paging.h>
5 extern struct vmm_os_hooks * os_hooks;
8 /**********************************/
10 /**********************************/
12 int host_va_to_host_pa(addr_t host_va, addr_t * host_pa) {
13 if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {
15 *host_pa = (addr_t)(os_hooks)->vaddr_to_paddr((void *)host_va);
27 int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
28 if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {
30 *host_va = (addr_t)(os_hooks)->paddr_to_vaddr((void *)host_pa);
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);
54 /* !! Currently not implemented !! */
55 // This is a scan of the shadow map
56 // For now we ignore it
58 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
66 /**********************************/
68 /**********************************/
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) {
77 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
81 if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
91 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
96 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
100 if (host_pa_to_host_va(host_pa, host_va) != 0) {
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) {
115 // guest virtual address is the same as the physical
116 *guest_pa = guest_va;
122 addr_t guest_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.guest_cr3.r_reg);
124 if (guest_pa_to_host_va(guest_info, guest_pde, (addr_t *)&pde) == -1) {
128 switch (pde32_lookup(pde, guest_va, &tmp_pa)) {
139 if (guest_pa_to_host_va(guest_info, tmp_pa, (addr_t*)&pte) == -1) {
143 if (pte32_lookup(pte, guest_va, guest_pa) != 0) {
153 case PROTECTED_PAE_PG:
164 } else if (guest_info->page_mode == NESTED_PAGING) {
178 /* !! Currently not implemented !! */
179 /* This will be a real pain.... its your standard page table walker in guest memory
181 * For now we ignore it...
183 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
189 /**********************************/
191 /**********************************/
194 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
199 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
203 if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
210 /* !! Currently not implemented !! */
211 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
216 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
220 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
230 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
236 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
240 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
244 if (host_pa_to_host_va(host_pa, host_va) != 0) {
252 /* !! Currently not implemented !! */
253 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
259 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
263 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
267 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
279 /* This is a straight address conversion + copy,
280 * except for the tiny little issue of crossing page boundries.....
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;
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;
291 if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
295 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
297 bytes_read += bytes_to_copy;
298 count -= bytes_to_copy;
299 cursor += bytes_to_copy;
310 /* This is a straight address conversion + copy,
311 * except for the tiny little issue of crossing page boundries.....
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;
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;
322 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
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);
333 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
335 bytes_read += bytes_to_copy;
336 count -= bytes_to_copy;
337 cursor += bytes_to_copy;
346 /* This is a straight address conversion + copy,
347 * except for the tiny little issue of crossing page boundries.....
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;
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;
358 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
359 return bytes_written;
363 memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
365 bytes_written += bytes_to_copy;
366 count -= bytes_to_copy;
367 cursor += bytes_to_copy;
370 return bytes_written;