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 (shdw_reg->host_type == SHDW_REGION_INVALID) ||
73 (shdw_reg->host_type == SHDW_REGION_FULL_HOOK)){
74 PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (reg_type=%s)\n",
75 (void *)guest_pa, v3_shdw_region_type_to_str(shdw_reg->host_type));
79 *host_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
85 /* !! Currently not implemented !! */
86 // This is a scan of the shadow map
87 // For now we ignore it
89 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
91 PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
98 /**********************************/
100 /**********************************/
103 /* !! Currently not implemented !! */
104 // This will return negative until we implement host_pa_to_guest_pa()
105 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
109 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
110 PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
115 if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
116 PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
127 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
132 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
133 PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
138 if (host_pa_to_host_va(host_pa, host_va) != 0) {
139 PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
148 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
149 v3_reg_t guest_cr3 = 0;
151 if (guest_info->mem_mode == PHYSICAL_MEM) {
152 // guest virtual address is the same as the physical
153 *guest_pa = guest_va;
157 if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
158 guest_cr3 = guest_info->shdw_pg_state.guest_cr3;
160 guest_cr3 = guest_info->ctrl_regs.cr3;
164 // Guest Is in Paged mode
165 switch (guest_info->cpu_mode) {
167 if (v3_translate_guest_pt_32(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
168 PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n",
169 (void *)guest_va, (void *)(addr_t)guest_cr3);
174 if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
175 PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n",
176 (void *)guest_va, (void *)(addr_t)guest_cr3);
183 if (v3_translate_guest_pt_64(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
184 PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n",
185 (void *)guest_va, (void *)(addr_t)guest_cr3);
198 /* !! Currently not implemented !! */
199 /* This will be a real pain.... its your standard page table walker in guest memory
201 * For now we ignore it...
203 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
205 PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
210 /**********************************/
212 /**********************************/
215 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
220 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
221 PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
226 if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
227 PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
235 /* !! Currently not implemented !! */
236 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
241 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
242 PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
247 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
248 PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
259 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
265 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
266 PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
271 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
272 PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
277 if (host_pa_to_host_va(host_pa, host_va) != 0) {
278 PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
287 /* !! Currently not implemented !! */
288 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
294 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
295 PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
300 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
301 PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
306 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
307 PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
320 /* This is a straight address conversion + copy,
321 * except for the tiny little issue of crossing page boundries.....
323 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
324 addr_t cursor = guest_va;
330 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
331 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
332 addr_t host_addr = 0;
335 if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
336 PrintDebug("Invalid GVA(%p)->HVA lookup\n", (void *)cursor);
342 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
344 bytes_read += bytes_to_copy;
345 count -= bytes_to_copy;
346 cursor += bytes_to_copy;
357 /* This is a straight address conversion + copy,
358 * except for the tiny little issue of crossing page boundries.....
360 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
361 addr_t cursor = guest_pa;
365 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
366 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
367 addr_t host_addr = 0;
369 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
374 PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
375 PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
376 PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
377 PrintDebug("guest_pa=0x%x\n", guest_pa);
380 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
382 bytes_read += bytes_to_copy;
383 count -= bytes_to_copy;
384 cursor += bytes_to_copy;
393 /* This is a straight address conversion + copy,
394 * except for the tiny little issue of crossing page boundries.....
396 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
397 addr_t cursor = guest_pa;
398 int bytes_written = 0;
401 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
402 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
405 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
406 return bytes_written;
410 memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
412 bytes_written += bytes_to_copy;
413 count -= bytes_to_copy;
414 cursor += bytes_to_copy;
417 return bytes_written;