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.


bug fix to check for illegal memory ranges
[palacios.git] / palacios / src / palacios / vmm_symmod.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 #include <palacios/vmm.h>
20 #include <palacios/vmm_symmod.h>
21 #include <palacios/vmm_symbiotic.h>
22 #include <palacios/vm_guest.h>
23 #include <palacios/vmm_list.h>
24
25 static struct hashtable * capsule_table = NULL;
26 static LIST_HEAD(capsule_list);
27
28
29 /* 
30  * This is a place holder to ensure that the _v3_modules section gets created by gcc
31  */
32 static struct {} null_mod  __attribute__((__used__))                    \
33     __attribute__((unused, __section__ ("_v3_capsules"),                \
34                    aligned(sizeof(addr_t))));
35
36 static uint_t mod_hash_fn(addr_t key) {
37     char * name = (char *)key;
38     return v3_hash_buffer((uchar_t *)name, strlen(name));
39 }
40
41 static int mod_eq_fn(addr_t key1, addr_t key2) {
42     char * name1 = (char *)key1;
43     char * name2 = (char *)key2;
44     
45     return (strcmp(name1, name2) == 0);
46 }
47
48
49 struct capsule_def {
50     char * name;
51     addr_t start_addr;
52     addr_t end_addr;
53     uint32_t flags; // see 'struct v3_symmod_flags'
54 } __attribute__((packed));
55
56
57
58 int V3_init_symmod() {
59     extern struct capsule_def __start__v3_capsules[];
60     extern struct capsule_def __stop__v3_capsules[];
61     struct capsule_def * tmp_def = __start__v3_capsules;
62     int i = 0;
63
64     if (tmp_def == __stop__v3_capsules) {
65         PrintDebug("No Symbiotic capsules found\n");
66         return 0;
67     }
68
69     capsule_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn);
70
71     while (tmp_def != __stop__v3_capsules) {
72         struct v3_sym_capsule * capsule = NULL;
73
74         if (v3_htable_search(capsule_table, (addr_t)(tmp_def->name))) {
75             PrintError("Multiple instances of Module (%s)\n", tmp_def->name);
76             return -1;
77         }
78         
79
80         capsule = V3_Malloc(sizeof(struct v3_sym_capsule));
81         memset(capsule, 0, sizeof(struct v3_sym_capsule));
82
83         capsule->name = tmp_def->name;
84         capsule->start_addr = (void *)(tmp_def->start_addr);
85         capsule->size = tmp_def->end_addr - tmp_def->start_addr;
86         capsule->flags = tmp_def->flags;
87         
88         
89
90         if (capsule->type == V3_SYMMOD_MOD) {
91             // parse module
92             // capsule->capsule_data = v3_sym_module...
93             // capsule->guest_size = size of linked module
94         } else if (capsule->type == V3_SYMMOD_LNX) {
95             capsule->guest_size = capsule->size;
96             capsule->capsule_data = NULL;
97         } else {
98             return -1;
99         }
100
101         PrintDebug("Registering Symbiotic Module (%s)\n", tmp_def->name);
102
103         if (v3_htable_insert(capsule_table, 
104                              (addr_t)(tmp_def->name),
105                              (addr_t)(capsule)) == 0) {
106             PrintError("Could not insert module %s to master list\n", tmp_def->name);
107             return -1;
108         }
109
110         list_add(&(capsule->node), &capsule_list);
111
112         tmp_def = &(__start__v3_capsules[++i]);
113     }
114     
115     return 0;
116 }
117
118 int V3_deinit_symmod() {
119     v3_free_htable(capsule_table, 1, 0);    
120
121     return 0;
122 }
123
124 /* ***************** */
125 /* Linkage functions */
126 /* ***************** */
127
128
129 /* Data structure containing symbols exported via the symbiotic interface */
130 struct v3_symbol_def32 {
131     uint32_t name_gva;
132     uint32_t value;
133 } __attribute__((packed));
134
135 struct v3_symbol_def64 {
136     uint64_t name_gva;
137     uint64_t value;
138 } __attribute__((packed));
139
140
141
142 struct v3_symbol {
143     char name[256];
144     uint64_t linkage;
145
146     struct list_head sym_node;
147 };
148
149
150
151 #include <palacios/vm_guest_mem.h>
152
153 static int symbol_hcall_handler(struct guest_info * core, hcall_id_t hcall_id, void * priv_data) {
154     struct v3_symmod_state * symmod_state = &(core->vm_info->sym_vm_state.symmod_state);
155     addr_t sym_start_gva = core->vm_regs.rbx;
156     uint32_t sym_size = core->vm_regs.rcx;
157
158     int i = 0;
159
160     PrintError("Received SYMMOD symbol tables addr=%p, size=%d\n", (void *)sym_start_gva, sym_size);
161
162     for (i = 0; i < sym_size; i++) {
163         char * sym_name = NULL;
164         struct v3_symbol_def32 * tmp_symbol = NULL;
165         struct v3_symbol * new_symbol = NULL;
166         addr_t sym_gva = sym_start_gva + (sizeof(struct v3_symbol_def32) * i);
167
168
169         if (v3_gva_to_hva(core, sym_gva, (addr_t *)&(tmp_symbol)) == -1) {
170             PrintError("Could not locate symbiotic symbol definition\n");
171             continue;
172         }
173         
174         if (v3_gva_to_hva(core, tmp_symbol->name_gva, (addr_t *)&(sym_name)) == -1) {
175             PrintError("Could not locate symbiotic symbol name\n");
176             continue;
177         }
178         
179         PrintError("Symbiotic Symbol (%s) at %p\n", sym_name, (void *)(addr_t)tmp_symbol->value);
180         
181         new_symbol = (struct v3_symbol *)V3_Malloc(sizeof(struct v3_symbol));
182
183         strncpy(new_symbol->name, sym_name, 256);
184         new_symbol->linkage = tmp_symbol->value;
185
186         list_add(&(new_symbol->sym_node), &(symmod_state->v3_sym_list));
187     }
188
189     return 0;
190 }
191
192
193 int v3_init_symmod_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
194     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
195     struct v3_symspy_global_page * sym_page = v3_sym_get_symspy_vm(vm);
196     struct v3_sym_capsule * tmp_capsule = NULL;
197
198     symmod_state->capsule_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn);
199
200
201     // Add modules to local hash table, should be keyed to config
202     list_for_each_entry(tmp_capsule, &capsule_list, node) {
203         V3_Print("Adding %s to local module table\n", tmp_capsule->name);
204         if (v3_htable_insert(symmod_state->capsule_table, 
205                              (addr_t)(tmp_capsule->name),
206                              (addr_t)(tmp_capsule)) == 0) {
207             PrintError("Could not insert module %s to vm local list\n", tmp_capsule->name);
208             return -1;
209         }
210         symmod_state->num_avail_capsules++;
211     }
212
213     symmod_state->num_loaded_capsules = 0;
214     sym_page->symmod_enabled = 1;
215
216     v3_register_hypercall(vm, SYMMOD_SYMS_HCALL, symbol_hcall_handler, NULL);
217
218     INIT_LIST_HEAD(&(symmod_state->v3_sym_list));
219
220     V3_Print("Symmod initialized\n");
221
222     return 0;
223 }
224
225 int v3_deinit_symmod_vm(struct v3_vm_info * vm) {
226     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
227     struct v3_symbol * sym = NULL;
228     struct v3_symbol * tmp_sym = NULL;
229
230     v3_remove_hypercall(vm, SYMMOD_SYMS_HCALL);
231
232     v3_free_htable(symmod_state->capsule_table, 0, 0);
233
234     list_for_each_entry_safe(sym, tmp_sym, &(symmod_state->v3_sym_list), sym_node) {
235         list_del(&(sym->sym_node));
236         V3_Free(sym);
237     }
238
239     return 0;
240 }
241
242
243 int v3_set_symmod_loader(struct v3_vm_info * vm, struct v3_symmod_loader_ops * ops, void * priv_data) {
244     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
245    
246     symmod_state->loader_ops = ops;
247     symmod_state->loader_data = priv_data;
248  
249     return 0;
250 }
251
252
253
254
255
256 int v3_load_sym_capsule(struct v3_vm_info * vm, char * name) {
257     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
258     struct v3_sym_capsule * capsule = (struct v3_sym_capsule *)v3_htable_search(capsule_table, (addr_t)name);
259
260     if (!capsule) {
261         PrintError("Could not find capsule %s\n", name);
262         return -1;
263     }
264
265     PrintDebug("Loading Capsule (%s)\n", name);
266
267     return symmod_state->loader_ops->load_capsule(vm, capsule, symmod_state->loader_data);
268 }
269
270
271
272 struct list_head * v3_get_sym_capsule_list() {
273     return &(capsule_list);
274 }
275
276
277 struct v3_sym_capsule * v3_get_sym_capsule(struct v3_vm_info * vm, char * name) {
278     struct v3_sym_capsule * mod = (struct v3_sym_capsule *)v3_htable_search(capsule_table, (addr_t)name);
279
280     if (!mod) {
281         PrintError("Could not find module %s\n", name);
282         return NULL;
283     }
284
285     return mod;
286 }