Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


refactored memory map
[palacios.git] / palacios / src / palacios / vmm_mem_hook.c
1 /* 
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.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
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.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vm_guest.h>
22 #include <palacios/vmm_mem_hook.h>
23 #include <palacios/vmm_emulator.h>
24
25 struct mem_hook {
26   
27     // Called when data is read from a memory page
28     int (*read)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data);
29     // Called when data is written to a memory page
30     int (*write)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data);
31
32     void * priv_data;
33     addr_t hook_hva;
34     
35
36 };
37
38
39
40 int v3_init_mem_hooks(struct v3_vm_info * vm) {
41     struct v3_mem_hooks * hooks = &(vm->mem_hooks);
42
43     hooks->hook_hvas = V3_VAddr(V3_AllocPages(vm->num_cores));
44
45     INIT_LIST_HEAD(&(hooks->hook_list));
46
47     return 0;
48 }
49
50
51
52
53 static int handle_mem_hook(struct guest_info * info, addr_t guest_va, addr_t guest_pa, 
54                            struct v3_mem_region * reg, pf_error_t access_info) {
55     struct mem_hook * hook = reg->priv_data;
56     addr_t op_addr = 0;
57
58     if (reg->flags.alloced == 0) {
59         op_addr = hook->hook_hva;
60     } else {
61         op_addr = (addr_t)V3_VAddr((void *)v3_get_shadow_addr(reg, info->cpu_id, guest_pa));
62     }
63
64     
65     if (access_info.write == 1) { 
66         // Write Operation 
67
68         if (v3_emulate_write_op(info, guest_va, guest_pa, op_addr, 
69                                 hook->write, hook->priv_data) == -1) {
70             PrintError("Write Full Hook emulation failed\n");
71             return -1;
72         }
73     } else {
74         // Read Operation
75         
76         if (reg->flags.read == 1) {
77             PrintError("Tried to emulate read for a guest Readable page\n");
78             return -1;
79         }
80
81         if (v3_emulate_read_op(info, guest_va, guest_pa, op_addr, 
82                                hook->read, hook->write, 
83                                hook->priv_data) == -1) {
84             PrintError("Read Full Hook emulation failed\n");
85             return -1;
86         }
87
88     }
89
90
91     return 0;
92 }
93
94
95
96
97 int v3_hook_write_mem(struct v3_vm_info * vm, uint16_t core_id,
98                       addr_t guest_addr_start, addr_t guest_addr_end, addr_t host_addr,
99                       int (*write)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
100                       void * priv_data) {
101     struct v3_mem_region * entry = NULL;
102     struct mem_hook * hook = V3_Malloc(sizeof(struct mem_hook));
103     //    struct v3_mem_hooks * hooks = &(vm->mem_hooks);
104
105     memset(hook, 0, sizeof(struct mem_hook));
106
107     hook->write = write;
108     hook->read = NULL;
109     hook->priv_data = priv_data;
110     hook->hook_hva = (addr_t)V3_VAddr((void *)host_addr);
111
112     entry = v3_create_mem_region(vm, core_id, guest_addr_start, guest_addr_end);
113     
114     entry->host_addr = host_addr;
115     entry->unhandled = handle_mem_hook;
116     entry->priv_data = hook;
117
118     entry->flags.read = 1;
119     entry->flags.exec = 1;
120     entry->flags.alloced = 1;
121
122     if (v3_insert_mem_region(vm, entry) == -1) {
123         V3_Free(entry);
124         V3_Free(hook);
125         return -1;
126     }
127
128     return 0;  
129 }
130
131
132
133 int v3_hook_full_mem(struct v3_vm_info * vm, uint16_t core_id, 
134                      addr_t guest_addr_start, addr_t guest_addr_end,
135                      int (*read)(struct guest_info * core, addr_t guest_addr, void * dst, uint_t length, void * priv_data),
136                      int (*write)(struct guest_info * core, addr_t guest_addr, void * src, uint_t length, void * priv_data),
137                      void * priv_data) {
138   
139     struct v3_mem_region * entry = NULL;
140     struct mem_hook * hook = V3_Malloc(sizeof(struct mem_hook));
141     struct v3_mem_hooks * hooks = &(vm->mem_hooks);
142
143     memset(hook, 0, sizeof(struct mem_hook));
144
145     hook->write = write;
146     hook->read = read;
147     hook->priv_data = priv_data;
148     hook->hook_hva = (addr_t)hooks->hook_hvas + (PAGE_SIZE_4KB * core_id);
149
150     entry = v3_create_mem_region(vm, core_id, guest_addr_start, guest_addr_end);
151
152     entry->unhandled = handle_mem_hook;
153     entry->priv_data = hook;
154
155     if (v3_insert_mem_region(vm, entry)) {
156         V3_Free(entry);
157         V3_Free(hook);
158         return -1;
159     }
160
161     return 0;
162 }
163
164
165
166 // This will unhook the memory hook registered at start address
167 // We do not support unhooking subregions
168 int v3_unhook_mem(struct v3_vm_info * vm, uint16_t core_id, addr_t guest_addr_start) {
169     struct v3_mem_region * reg = v3_get_mem_region(vm, core_id, guest_addr_start);
170     struct mem_hook * hook = reg->priv_data;
171
172     V3_Free(hook);
173   
174     v3_delete_mem_region(vm, reg);
175
176     return 0;
177 }
178
179