2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vm_guest_mem.h>
21 #include <palacios/vmm.h>
22 #include <palacios/vmm_paging.h>
24 extern struct v3_os_hooks * os_hooks;
27 /**********************************/
29 /**********************************/
31 int host_va_to_host_pa(addr_t host_va, addr_t * host_pa) {
32 if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {
34 *host_pa = (addr_t)(os_hooks)->vaddr_to_paddr((void *)host_va);
37 PrintError("In HVA->HPA: Invalid HVA(%x)->HPA lookup\n", host_va);
41 PrintError("In HVA->HPA: os_hooks not defined\n");
48 int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
49 if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {
51 *host_va = (addr_t)(os_hooks)->paddr_to_vaddr((void *)host_pa);
54 PrintError("In HPA->HVA: Invalid HPA(%x)->HVA lookup\n", host_pa);
58 PrintError("In HPA->HVA: os_hooks not defined\n");
66 int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_pa) {
67 // we use the shadow map here...
68 if (lookup_shadow_map_addr(&(guest_info->mem_map), guest_pa, host_pa) != HOST_REGION_PHYSICAL_MEMORY) {
69 PrintError("In GPA->HPA: Could not find address in shadow map (addr=%x)\n", guest_pa);
77 /* !! Currently not implemented !! */
78 // This is a scan of the shadow map
79 // For now we ignore it
81 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
83 PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
90 /**********************************/
92 /**********************************/
95 /* !! Currently not implemented !! */
96 // This will return negative until we implement host_pa_to_guest_pa()
97 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
101 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
102 PrintError("In HVA->GPA: Invalid HVA(%x)->HPA lookup\n", host_va);
106 if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
107 PrintError("In HVA->GPA: Invalid HPA(%x)->GPA lookup\n", host_pa);
117 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
122 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
123 PrintError("In GPA->HVA: Invalid GPA(%x)->HPA lookup\n", guest_pa);
127 if (host_pa_to_host_va(host_pa, host_va) != 0) {
128 PrintError("In GPA->HVA: Invalid HPA(%x)->HVA lookup\n", host_pa);
136 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
137 if (guest_info->mem_mode == PHYSICAL_MEM) {
138 // guest virtual address is the same as the physical
139 *guest_pa = guest_va;
145 // Guest Is in Paged mode
146 switch (guest_info->cpu_mode) {
151 addr_t guest_pde = 0;
153 if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
154 guest_pde = CR3_TO_PDE32(guest_info->shdw_pg_state.guest_cr3);
155 } else if (guest_info->shdw_pg_mode == NESTED_PAGING) {
156 guest_pde = CR3_TO_PDE32(guest_info->ctrl_regs.cr3);
159 if (guest_pa_to_host_va(guest_info, guest_pde, (addr_t *)&pde) == -1) {
160 PrintError("In GVA->GPA: Invalid GPA(%x)->HVA PDE32 lookup\n", guest_pde);
165 switch (pde32_lookup(pde, guest_va, &tmp_pa)) {
166 case PDE32_ENTRY_NOT_PRESENT:
169 case PDE32_ENTRY_LARGE_PAGE:
172 case PDE32_ENTRY_PTE32:
177 if (guest_pa_to_host_va(guest_info, tmp_pa, (addr_t*)&pte) == -1) {
178 PrintError("In GVA->GPA: Invalid GPA(%x)->HVA PTE32 lookup\n", guest_pa);
182 //PrintDebug("PTE host addr=%x, GVA=%x, GPA=%x(should be 0)\n", pte, guest_va, *guest_pa);
184 if (pte32_lookup(pte, guest_va, guest_pa) != 0) {
185 PrintError("In GVA->GPA: PTE32 Lookup failure GVA=%x; PTE=%x\n", guest_va, pte);
186 // PrintPT32(PDE32_INDEX(guest_va) << 22, pte);
215 /* !! Currently not implemented !! */
216 /* This will be a real pain.... its your standard page table walker in guest memory
218 * For now we ignore it...
220 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
222 PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
227 /**********************************/
229 /**********************************/
232 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
237 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
238 PrintError("In GVA->HPA: Invalid GVA(%x)->GPA lookup\n", guest_va);
242 if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
243 PrintError("In GVA->HPA: Invalid GPA(%x)->HPA lookup\n", guest_pa);
250 /* !! Currently not implemented !! */
251 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
256 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
257 PrintError("In HPA->GVA: Invalid HPA(%x)->GPA lookup\n", host_pa);
261 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
262 PrintError("In HPA->GVA: Invalid GPA(%x)->GVA lookup\n", guest_pa);
272 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
278 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
279 PrintError("In GVA->HVA: Invalid GVA(%x)->GPA lookup\n", guest_va);
283 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
284 PrintError("In GVA->HVA: Invalid GPA(%x)->HPA lookup\n", guest_pa);
288 if (host_pa_to_host_va(host_pa, host_va) != 0) {
289 PrintError("In GVA->HVA: Invalid HPA(%x)->HVA lookup\n", host_pa);
297 /* !! Currently not implemented !! */
298 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
304 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
305 PrintError("In HVA->GVA: Invalid HVA(%x)->HPA lookup\n", host_va);
309 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
310 PrintError("In HVA->GVA: Invalid HPA(%x)->GPA lookup\n", host_va);
314 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
315 PrintError("In HVA->GVA: Invalid GPA(%x)->GVA lookup\n", guest_pa);
327 /* This is a straight address conversion + copy,
328 * except for the tiny little issue of crossing page boundries.....
330 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
331 addr_t cursor = guest_va;
337 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
338 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
339 addr_t host_addr = 0;
342 if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
343 PrintDebug("Invalid GVA(%x)->HVA lookup\n", cursor);
349 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
351 bytes_read += bytes_to_copy;
352 count -= bytes_to_copy;
353 cursor += bytes_to_copy;
364 /* This is a straight address conversion + copy,
365 * except for the tiny little issue of crossing page boundries.....
367 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
368 addr_t cursor = guest_pa;
372 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
373 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
374 addr_t host_addr = 0;
376 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
381 PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
382 PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
383 PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
384 PrintDebug("guest_pa=0x%x\n", guest_pa);
387 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
389 bytes_read += bytes_to_copy;
390 count -= bytes_to_copy;
391 cursor += bytes_to_copy;
400 /* This is a straight address conversion + copy,
401 * except for the tiny little issue of crossing page boundries.....
403 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
404 addr_t cursor = guest_pa;
405 int bytes_written = 0;
408 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
409 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
412 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
413 return bytes_written;
417 memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
419 bytes_written += bytes_to_copy;
420 count -= bytes_to_copy;
421 cursor += bytes_to_copy;
424 return bytes_written;