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 struct v3_shadow_region * shdw_reg = v3_get_shadow_region(guest_info, guest_pa);
71 if (shdw_reg == NULL) {
72 PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (NULL REGION)\n",
77 if ((shdw_reg->host_type == SHDW_REGION_INVALID) ||
78 (shdw_reg->host_type == SHDW_REGION_FULL_HOOK)) {
79 PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (reg_type=%s)\n",
80 (void *)guest_pa, v3_shdw_region_type_to_str(shdw_reg->host_type));
84 *host_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
90 /* !! Currently not implemented !! */
91 // This is a scan of the shadow map
92 // For now we ignore it
94 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
96 PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
103 /**********************************/
105 /**********************************/
108 /* !! Currently not implemented !! */
109 // This will return negative until we implement host_pa_to_guest_pa()
110 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
114 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
115 PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
120 if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
121 PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
132 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
137 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
138 PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
143 if (host_pa_to_host_va(host_pa, host_va) != 0) {
144 PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
153 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
154 v3_reg_t guest_cr3 = 0;
156 if (guest_info->mem_mode == PHYSICAL_MEM) {
157 // guest virtual address is the same as the physical
158 *guest_pa = guest_va;
162 if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
163 guest_cr3 = guest_info->shdw_pg_state.guest_cr3;
165 guest_cr3 = guest_info->ctrl_regs.cr3;
169 // Guest Is in Paged mode
170 switch (guest_info->cpu_mode) {
172 if (v3_translate_guest_pt_32(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
173 PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n",
174 (void *)guest_va, (void *)(addr_t)guest_cr3);
179 if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
180 PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n",
181 (void *)guest_va, (void *)(addr_t)guest_cr3);
188 if (v3_translate_guest_pt_64(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
189 PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n",
190 (void *)guest_va, (void *)(addr_t)guest_cr3);
203 /* !! Currently not implemented !! */
204 /* This will be a real pain.... its your standard page table walker in guest memory
206 * For now we ignore it...
208 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
210 PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
215 /**********************************/
217 /**********************************/
220 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
225 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
226 PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
231 if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
232 PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
240 /* !! Currently not implemented !! */
241 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
246 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
247 PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
252 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
253 PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
264 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
270 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
271 PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
276 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
277 PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
282 if (host_pa_to_host_va(host_pa, host_va) != 0) {
283 PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
292 /* !! Currently not implemented !! */
293 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
299 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
300 PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
305 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
306 PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
311 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
312 PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
325 /* This is a straight address conversion + copy,
326 * except for the tiny little issue of crossing page boundries.....
328 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
329 addr_t cursor = guest_va;
335 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
336 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
337 addr_t host_addr = 0;
340 if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
341 PrintDebug("Invalid GVA(%p)->HVA lookup\n", (void *)cursor);
347 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
349 bytes_read += bytes_to_copy;
350 count -= bytes_to_copy;
351 cursor += bytes_to_copy;
362 /* This is a straight address conversion + copy,
363 * except for the tiny little issue of crossing page boundries.....
365 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
366 addr_t cursor = guest_pa;
370 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
371 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
372 addr_t host_addr = 0;
374 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
379 PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
380 PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
381 PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
382 PrintDebug("guest_pa=0x%x\n", guest_pa);
385 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
387 bytes_read += bytes_to_copy;
388 count -= bytes_to_copy;
389 cursor += bytes_to_copy;
398 /* This is a straight address conversion + copy,
399 * except for the tiny little issue of crossing page boundries.....
401 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
402 addr_t cursor = guest_pa;
403 int bytes_written = 0;
406 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
407 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
410 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
411 return bytes_written;
415 memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
417 bytes_written += bytes_to_copy;
418 count -= bytes_to_copy;
419 cursor += bytes_to_copy;
422 return bytes_written;