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");
66 int guest_pa_to_host_pa(struct guest_info * info, addr_t guest_pa, addr_t * host_pa) {
67 struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info->vm_info, info->cpu_id, guest_pa);
69 if (shdw_reg == NULL) {
70 PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (NULL REGION)\n",
75 if (shdw_reg->flags.alloced == 0) {
76 PrintError("In GPA->HPA: Tried to translate physical address of non allocated page (addr=%p)\n",
81 *host_pa = v3_get_shadow_addr(shdw_reg, info->cpu_id, guest_pa);
87 /* !! Currently not implemented !! */
88 // This is a scan of the shadow map
89 // For now we ignore it
91 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
93 PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
100 /**********************************/
102 /**********************************/
105 /* !! Currently not implemented !! */
106 // This will return negative until we implement host_pa_to_guest_pa()
107 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
111 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
112 PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
117 if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
118 PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
129 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
134 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
135 PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
140 if (host_pa_to_host_va(host_pa, host_va) != 0) {
141 PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
150 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
151 v3_reg_t guest_cr3 = 0;
153 if (guest_info->mem_mode == PHYSICAL_MEM) {
154 // guest virtual address is the same as the physical
155 *guest_pa = guest_va;
159 if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
160 guest_cr3 = guest_info->shdw_pg_state.guest_cr3;
162 guest_cr3 = guest_info->ctrl_regs.cr3;
166 // Guest Is in Paged mode
167 switch (guest_info->cpu_mode) {
169 if (v3_translate_guest_pt_32(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
170 PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n",
171 (void *)guest_va, (void *)(addr_t)guest_cr3);
176 if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
177 PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n",
178 (void *)guest_va, (void *)(addr_t)guest_cr3);
185 if (v3_translate_guest_pt_64(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
186 PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n",
187 (void *)guest_va, (void *)(addr_t)guest_cr3);
200 /* !! Currently not implemented !! */
201 /* This will be a real pain.... its your standard page table walker in guest memory
203 * For now we ignore it...
205 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
207 PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
212 /**********************************/
214 /**********************************/
217 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
222 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
223 PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
228 if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
229 PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
237 /* !! Currently not implemented !! */
238 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
243 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
244 PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
249 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
250 PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
261 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
267 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
268 PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
273 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
274 PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
279 if (host_pa_to_host_va(host_pa, host_va) != 0) {
280 PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
289 /* !! Currently not implemented !! */
290 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
296 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
297 PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
302 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
303 PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
308 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
309 PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
322 /* This is a straight address conversion + copy,
323 * except for the tiny little issue of crossing page boundries.....
325 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
326 addr_t cursor = guest_va;
332 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
333 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
334 addr_t host_addr = 0;
337 if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
338 PrintDebug("Invalid GVA(%p)->HVA lookup\n", (void *)cursor);
344 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
346 bytes_read += bytes_to_copy;
347 count -= bytes_to_copy;
348 cursor += bytes_to_copy;
359 /* This is a straight address conversion + copy,
360 * except for the tiny little issue of crossing page boundries.....
362 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
363 addr_t cursor = guest_pa;
367 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
368 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
369 addr_t host_addr = 0;
371 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
376 PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
377 PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
378 PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
379 PrintDebug("guest_pa=0x%x\n", guest_pa);
382 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
384 bytes_read += bytes_to_copy;
385 count -= bytes_to_copy;
386 cursor += bytes_to_copy;
395 /* This is a straight address conversion + copy,
396 * except for the tiny little issue of crossing page boundries.....
398 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
399 addr_t cursor = guest_pa;
400 int bytes_written = 0;
403 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
404 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
407 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
408 return bytes_written;
412 memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
414 bytes_written += bytes_to_copy;
415 count -= bytes_to_copy;
416 cursor += bytes_to_copy;
419 return bytes_written;