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.


symbiotic module changes
[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         list_add(&(capsule->node), &capsule_list);
110
111         tmp_def = &(__start__v3_capsules[++i]);
112     }
113     
114     return 0;
115 }
116
117 /* ***************** */
118 /* Linkage functions */
119 /* ***************** */
120
121
122 /* Data structure containing symbols exported via the symbiotic interface */
123 struct v3_symbol_def32 {
124     uint32_t name_gva;
125     uint32_t value;
126 } __attribute__((packed));
127
128 struct v3_symbol_def64 {
129     uint64_t name_gva;
130     uint64_t value;
131 } __attribute__((packed));
132
133
134
135 struct v3_symbol {
136     char name[256];
137     uint64_t linkage;
138
139     struct list_head sym_node;
140 };
141
142
143
144 #include <palacios/vm_guest_mem.h>
145
146 static int symbol_hcall_handler(struct guest_info * core, hcall_id_t hcall_id, void * priv_data) {
147     struct v3_symmod_state * symmod_state = &(core->vm_info->sym_vm_state.symmod_state);
148     addr_t sym_start_gva = core->vm_regs.rbx;
149     uint32_t sym_size = core->vm_regs.rcx;
150
151     int i = 0;
152
153     PrintError("Received SYMMOD symbol tables addr=%p, size=%d\n", (void *)sym_start_gva, sym_size);
154
155     for (i = 0; i < sym_size; i++) {
156         char * sym_name = NULL;
157         struct v3_symbol_def32 * tmp_symbol = NULL;
158         struct v3_symbol * new_symbol = NULL;
159         addr_t sym_gva = sym_start_gva + (sizeof(struct v3_symbol_def32) * i);
160
161
162         if (guest_va_to_host_va(core, sym_gva, (addr_t *)&(tmp_symbol)) == -1) {
163             PrintError("Could not locate symbiotic symbol definition\n");
164             continue;
165         }
166         
167         if (guest_va_to_host_va(core, tmp_symbol->name_gva, (addr_t *)&(sym_name)) == -1) {
168             PrintError("Could not locate symbiotic symbol name\n");
169             continue;
170         }
171         
172         PrintError("Symbiotic Symbol (%s) at %p\n", sym_name, (void *)(addr_t)tmp_symbol->value);
173         
174         new_symbol = (struct v3_symbol *)V3_Malloc(sizeof(struct v3_symbol));
175
176         strncpy(new_symbol->name, sym_name, 256);
177         new_symbol->linkage = tmp_symbol->value;
178
179         list_add(&(new_symbol->sym_node), &(symmod_state->v3_sym_list));
180     }
181
182     return 0;
183 }
184
185
186 int v3_init_symmod_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
187     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
188     struct v3_symspy_global_page * sym_page = v3_sym_get_symspy_vm(vm);
189     struct v3_sym_capsule * tmp_capsule = NULL;
190
191     symmod_state->capsule_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn);
192
193
194     // Add modules to local hash table, should be keyed to config
195     list_for_each_entry(tmp_capsule, &capsule_list, node) {
196         V3_Print("Adding %s to local module table\n", tmp_capsule->name);
197         if (v3_htable_insert(symmod_state->capsule_table, 
198                              (addr_t)(tmp_capsule->name),
199                              (addr_t)(tmp_capsule)) == 0) {
200             PrintError("Could not insert module %s to vm local list\n", tmp_capsule->name);
201             return -1;
202         }
203         symmod_state->num_avail_capsules++;
204     }
205
206     symmod_state->num_loaded_capsules = 0;
207     sym_page->symmod_enabled = 1;
208
209     v3_register_hypercall(vm, SYMMOD_SYMS_HCALL, symbol_hcall_handler, NULL);
210
211     INIT_LIST_HEAD(&(symmod_state->v3_sym_list));
212
213     V3_Print("Symmod initialized\n");
214
215     return 0;
216 }
217
218
219
220 int v3_set_symmod_loader(struct v3_vm_info * vm, struct v3_symmod_loader_ops * ops, void * priv_data) {
221     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
222    
223     symmod_state->loader_ops = ops;
224     symmod_state->loader_data = priv_data;
225  
226     return 0;
227 }
228
229
230
231
232
233 int v3_load_sym_capsule(struct v3_vm_info * vm, char * name) {
234     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
235     struct v3_sym_capsule * capsule = (struct v3_sym_capsule *)v3_htable_search(capsule_table, (addr_t)name);
236
237     if (!capsule) {
238         PrintError("Could not find capsule %s\n", name);
239         return -1;
240     }
241
242     PrintDebug("Loading Capsule (%s)\n", name);
243
244     return symmod_state->loader_ops->load_capsule(vm, capsule, symmod_state->loader_data);
245 }
246
247
248
249 struct list_head * v3_get_sym_capsule_list() {
250     return &(capsule_list);
251 }
252
253
254 struct v3_sym_capsule * v3_get_sym_capsule(struct v3_vm_info * vm, char * name) {
255     struct v3_sym_capsule * mod = (struct v3_sym_capsule *)v3_htable_search(capsule_table, (addr_t)name);
256
257     if (!mod) {
258         PrintError("Could not find module %s\n", name);
259         return NULL;
260     }
261
262     return mod;
263 }