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_FULL_HOOK) {
78 PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (reg_type=%s)\n",
79 (void *)guest_pa, v3_shdw_region_type_to_str(shdw_reg->host_type));
83 *host_pa = v3_get_shadow_addr(shdw_reg, guest_pa);
89 /* !! Currently not implemented !! */
90 // This is a scan of the shadow map
91 // For now we ignore it
93 int host_pa_to_guest_pa(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_pa) {
95 PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
102 /**********************************/
104 /**********************************/
107 /* !! Currently not implemented !! */
108 // This will return negative until we implement host_pa_to_guest_pa()
109 int host_va_to_guest_pa(struct guest_info * guest_info, addr_t host_va, addr_t * guest_pa) {
113 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
114 PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
119 if (host_pa_to_guest_pa(guest_info, host_pa, guest_pa) != 0) {
120 PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
131 int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * host_va) {
136 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
137 PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
142 if (host_pa_to_host_va(host_pa, host_va) != 0) {
143 PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
152 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
153 v3_reg_t guest_cr3 = 0;
155 if (guest_info->mem_mode == PHYSICAL_MEM) {
156 // guest virtual address is the same as the physical
157 *guest_pa = guest_va;
161 if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
162 guest_cr3 = guest_info->shdw_pg_state.guest_cr3;
164 guest_cr3 = guest_info->ctrl_regs.cr3;
168 // Guest Is in Paged mode
169 switch (guest_info->cpu_mode) {
171 if (v3_translate_guest_pt_32(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
172 PrintDebug("Could not translate addr (%p) through 32 bit guest PT at %p\n",
173 (void *)guest_va, (void *)(addr_t)guest_cr3);
178 if (v3_translate_guest_pt_32pae(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
179 PrintDebug("Could not translate addr (%p) through 32 bitpae guest PT at %p\n",
180 (void *)guest_va, (void *)(addr_t)guest_cr3);
187 if (v3_translate_guest_pt_64(guest_info, guest_cr3, guest_va, guest_pa) == -1) {
188 PrintDebug("Could not translate addr (%p) through 64 bit guest PT at %p\n",
189 (void *)guest_va, (void *)(addr_t)guest_cr3);
202 /* !! Currently not implemented !! */
203 /* This will be a real pain.... its your standard page table walker in guest memory
205 * For now we ignore it...
207 int guest_pa_to_guest_va(struct guest_info * guest_info, addr_t guest_pa, addr_t * guest_va) {
209 PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
214 /**********************************/
216 /**********************************/
219 int guest_va_to_host_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * host_pa) {
224 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
225 PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
230 if (guest_pa_to_host_pa(guest_info, guest_pa, host_pa) != 0) {
231 PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
239 /* !! Currently not implemented !! */
240 int host_pa_to_guest_va(struct guest_info * guest_info, addr_t host_pa, addr_t * guest_va) {
245 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
246 PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
251 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
252 PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
263 int guest_va_to_host_va(struct guest_info * guest_info, addr_t guest_va, addr_t * host_va) {
269 if (guest_va_to_guest_pa(guest_info, guest_va, &guest_pa) != 0) {
270 PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
275 if (guest_pa_to_host_pa(guest_info, guest_pa, &host_pa) != 0) {
276 PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
281 if (host_pa_to_host_va(host_pa, host_va) != 0) {
282 PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
291 /* !! Currently not implemented !! */
292 int host_va_to_guest_va(struct guest_info * guest_info, addr_t host_va, addr_t * guest_va) {
298 if (host_va_to_host_pa(host_va, &host_pa) != 0) {
299 PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
304 if (host_pa_to_guest_pa(guest_info, host_pa, &guest_pa) != 0) {
305 PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
310 if (guest_pa_to_guest_va(guest_info, guest_pa, guest_va) != 0) {
311 PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
324 /* This is a straight address conversion + copy,
325 * except for the tiny little issue of crossing page boundries.....
327 int read_guest_va_memory(struct guest_info * guest_info, addr_t guest_va, int count, uchar_t * dest) {
328 addr_t cursor = guest_va;
334 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
335 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
336 addr_t host_addr = 0;
339 if (guest_va_to_host_va(guest_info, cursor, &host_addr) != 0) {
340 PrintDebug("Invalid GVA(%p)->HVA lookup\n", (void *)cursor);
346 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
348 bytes_read += bytes_to_copy;
349 count -= bytes_to_copy;
350 cursor += bytes_to_copy;
361 /* This is a straight address conversion + copy,
362 * except for the tiny little issue of crossing page boundries.....
364 int read_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * dest) {
365 addr_t cursor = guest_pa;
369 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
370 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
371 addr_t host_addr = 0;
373 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
378 PrintDebug("Trying to read %d bytes\n", bytes_to_copy);
379 PrintDebug("Dist to page edge=%d\n", dist_to_pg_edge);
380 PrintDebug("PAGE_ADDR=0x%x\n", PAGE_ADDR(cursor));
381 PrintDebug("guest_pa=0x%x\n", guest_pa);
384 memcpy(dest + bytes_read, (void*)host_addr, bytes_to_copy);
386 bytes_read += bytes_to_copy;
387 count -= bytes_to_copy;
388 cursor += bytes_to_copy;
397 /* This is a straight address conversion + copy,
398 * except for the tiny little issue of crossing page boundries.....
400 int write_guest_pa_memory(struct guest_info * guest_info, addr_t guest_pa, int count, uchar_t * src) {
401 addr_t cursor = guest_pa;
402 int bytes_written = 0;
405 int dist_to_pg_edge = (PAGE_ADDR(cursor) + PAGE_SIZE) - cursor;
406 int bytes_to_copy = (dist_to_pg_edge > count) ? count : dist_to_pg_edge;
409 if (guest_pa_to_host_va(guest_info, cursor, &host_addr) != 0) {
410 return bytes_written;
414 memcpy((void*)host_addr, src + bytes_written, bytes_to_copy);
416 bytes_written += bytes_to_copy;
417 count -= bytes_to_copy;
418 cursor += bytes_to_copy;
421 return bytes_written;