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(%p)->HPA lookup\n",
42 PrintError("In HVA->HPA: os_hooks not defined\n");
49 int host_pa_to_host_va(addr_t host_pa, addr_t * host_va) {
50 if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {
52 *host_va = (addr_t)(os_hooks)->paddr_to_vaddr((void *)host_pa);
55 PrintError("In HPA->HVA: Invalid HPA(%p)->HVA lookup\n",
60 PrintError("In HPA->HVA: os_hooks not defined\n");
68 int guest_pa_to_host_pa(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_pa) {
69 // we use the shadow map here...
70 host_region_type_t reg_type = lookup_shadow_map_addr(&(guest_info->mem_map), guest_pa, host_pa);
72 if (reg_type != HOST_REGION_PHYSICAL_MEMORY) {
73 PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (reg_type=%d)\n",
74 (void *)guest_pa, reg_type);
82 /* !! Currently not implemented !! */
83 // This is a scan of the shadow map
84 // For now we ignore it
86 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
88 PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
95 /**********************************/
97 /**********************************/
100 /* !! Currently not implemented !! */
101 // This will return negative until we implement host_pa_to_guest_pa()
102 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
106 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
107 PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
112 if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
113 PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
124 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
129 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
130 PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
135 if (host_pa_to_host_va(host_pa, host_va) != 0) {
136 PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
145 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
146 v3_reg_t guest_cr3 = 0;
148 if (guest_info->mem_mode == PHYSICAL_MEM) {
149 // guest virtual address is the same as the physical
150 *guest_pa = guest_va;
154 if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
155 guest_cr3 = guest_info->shdw_pg_state.guest_cr3;
157 guest_cr3 = guest_info->ctrl_regs.cr3;
161 // Guest Is in Paged mode
162 switch (guest_info->cpu_mode) {
164 if (v3_translate_guest_pt_32(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
165 PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n",
166 (void *)guest_va, (void *)(addr_t)guest_cr3);
171 if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
172 PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n",
173 (void *)guest_va, (void *)(addr_t)guest_cr3);
180 if (v3_translate_guest_pt_64(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
181 PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n",
182 (void *)guest_va, (void *)(addr_t)guest_cr3);
195 /* !! Currently not implemented !! */
196 /* This will be a real pain.... its your standard page table walker in guest memory
198 * For now we ignore it...
200 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
202 PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
207 /**********************************/
209 /**********************************/
212 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
217 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
218 PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
223 if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
224 PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
232 /* !! Currently not implemented !! */
233 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
238 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
239 PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
244 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
245 PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
256 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
262 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
263 PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
268 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
269 PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
274 if (host_pa_to_host_va(host_pa, host_va) != 0) {
275 PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
284 /* !! Currently not implemented !! */
285 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
291 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
292 PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
297 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
298 PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
303 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
304 PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
317 /* This is a straight address conversion + copy,
318 * except for the tiny little issue of crossing page boundries.....
320 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
321 addr_t cursor = guest_va;
327 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
328 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
329 addr_t host_addr = 0;
332 if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
333 PrintDebug("Invalid GVA(%p)->HVA lookup\n", (void *)cursor);
339 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
341 bytes_read += bytes_to_copy;
342 count -= bytes_to_copy;
343 cursor += bytes_to_copy;
354 /* This is a straight address conversion + copy,
355 * except for the tiny little issue of crossing page boundries.....
357 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
358 addr_t cursor = guest_pa;
362 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
363 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
364 addr_t host_addr = 0;
366 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
371 PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
372 PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
373 PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
374 PrintDebug("guest_pa=0x%x\n", guest_pa);
377 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
379 bytes_read += bytes_to_copy;
380 count -= bytes_to_copy;
381 cursor += bytes_to_copy;
390 /* This is a straight address conversion + copy,
391 * except for the tiny little issue of crossing page boundries.....
393 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
394 addr_t cursor = guest_pa;
395 int bytes_written = 0;
398 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
399 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
402 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
403 return bytes_written;
407 memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
409 bytes_written += bytes_to_copy;
410 count -= bytes_to_copy;
411 cursor += bytes_to_copy;
414 return bytes_written;