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 shdw_region_type_t reg_type = lookup_shadow_map_addr(&(guest_info->mem_map), guest_pa, host_pa);
72 if ((reg_type == SHDW_REGION_INVALID) ||
73 (reg_type == SHDW_REGION_UNALLOCATED) ||
74 (reg_type == SHDW_REGION_FULL_HOOK)){
75 PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (reg_type=%d)\n",
76 (void *)guest_pa, reg_type);
84 /* !! Currently not implemented !! */
85 // This is a scan of the shadow map
86 // For now we ignore it
88 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
90 PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
97 /**********************************/
99 /**********************************/
102 /* !! Currently not implemented !! */
103 // This will return negative until we implement host_pa_to_guest_pa()
104 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
108 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
109 PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
114 if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
115 PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
126 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
131 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
132 PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
137 if (host_pa_to_host_va(host_pa, host_va) != 0) {
138 PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
147 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
148 v3_reg_t guest_cr3 = 0;
150 if (guest_info->mem_mode == PHYSICAL_MEM) {
151 // guest virtual address is the same as the physical
152 *guest_pa = guest_va;
156 if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
157 guest_cr3 = guest_info->shdw_pg_state.guest_cr3;
159 guest_cr3 = guest_info->ctrl_regs.cr3;
163 // Guest Is in Paged mode
164 switch (guest_info->cpu_mode) {
166 if (v3_translate_guest_pt_32(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
167 PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n",
168 (void *)guest_va, (void *)(addr_t)guest_cr3);
173 if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
174 PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n",
175 (void *)guest_va, (void *)(addr_t)guest_cr3);
182 if (v3_translate_guest_pt_64(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
183 PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n",
184 (void *)guest_va, (void *)(addr_t)guest_cr3);
197 /* !! Currently not implemented !! */
198 /* This will be a real pain.... its your standard page table walker in guest memory
200 * For now we ignore it...
202 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
204 PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
209 /**********************************/
211 /**********************************/
214 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
219 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
220 PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
225 if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
226 PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
234 /* !! Currently not implemented !! */
235 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
240 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
241 PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
246 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
247 PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
258 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
264 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
265 PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
270 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
271 PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
276 if (host_pa_to_host_va(host_pa, host_va) != 0) {
277 PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
286 /* !! Currently not implemented !! */
287 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
293 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
294 PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
299 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
300 PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
305 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
306 PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
319 /* This is a straight address conversion + copy,
320 * except for the tiny little issue of crossing page boundries.....
322 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
323 addr_t cursor = guest_va;
329 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
330 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
331 addr_t host_addr = 0;
334 if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
335 PrintDebug("Invalid GVA(%p)->HVA lookup\n", (void *)cursor);
341 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
343 bytes_read += bytes_to_copy;
344 count -= bytes_to_copy;
345 cursor += bytes_to_copy;
356 /* This is a straight address conversion + copy,
357 * except for the tiny little issue of crossing page boundries.....
359 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
360 addr_t cursor = guest_pa;
364 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
365 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
366 addr_t host_addr = 0;
368 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
373 PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
374 PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
375 PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
376 PrintDebug("guest_pa=0x%x\n", guest_pa);
379 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
381 bytes_read += bytes_to_copy;
382 count -= bytes_to_copy;
383 cursor += bytes_to_copy;
392 /* This is a straight address conversion + copy,
393 * except for the tiny little issue of crossing page boundries.....
395 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
396 addr_t cursor = guest_pa;
397 int bytes_written = 0;
400 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
401 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
404 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
405 return bytes_written;
409 memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
411 bytes_written += bytes_to_copy;
412 count -= bytes_to_copy;
413 cursor += bytes_to_copy;
416 return bytes_written;