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.


separated virtual cores from physical cores
[palacios.git] / palacios / src / palacios / vmm_extensions.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
22 #include <palacios/vmm_extensions.h>
23 #include <palacios/vm_guest.h>
24 #include <palacios/vmm_hashtable.h>
25
26
27 static struct hashtable * ext_table = NULL;
28
29
30 static uint_t ext_hash_fn(addr_t key) {
31     char * name = (char *)key;
32     return v3_hash_buffer((uint8_t *)name, strlen(name));
33 }
34
35 static int ext_eq_fn(addr_t key1, addr_t key2) {
36     char * name1 = (char *)key1;
37     char * name2 = (char *)key2;
38
39     return (strcmp(name1, name2) == 0);
40 }
41
42
43
44 int V3_init_extensions() {
45     extern struct v3_extension_impl * __start__v3_extensions[];
46     extern struct v3_extension_impl * __stop__v3_extensions[];
47     struct v3_extension_impl ** tmp_ext = __start__v3_extensions;
48     int i = 0;
49
50     ext_table = v3_create_htable(0, ext_hash_fn, ext_eq_fn);
51
52     while (tmp_ext != __stop__v3_extensions) {
53         V3_Print("Registering Extension (%s)\n", (*tmp_ext)->name);
54
55         if (v3_htable_search(ext_table, (addr_t)((*tmp_ext)->name))) {
56             PrintError("Multiple instances of Extension (%s)\n", (*tmp_ext)->name);
57             return -1;
58         }
59
60         if (v3_htable_insert(ext_table, (addr_t)((*tmp_ext)->name), (addr_t)(*tmp_ext)) == 0) {
61             PrintError("Could not register Extension (%s)\n", (*tmp_ext)->name);
62             return -1;
63         }
64
65         tmp_ext = &(__start__v3_extensions[++i]);
66     }
67
68     return 0;
69 }
70
71
72
73
74 int V3_deinit_extensions() {
75     v3_free_htable(ext_table, 0, 0);
76     return 0;
77 }
78
79
80 int v3_init_ext_manager(struct v3_vm_info * vm) {
81     struct v3_extensions * ext_state = &(vm->extensions);
82
83     INIT_LIST_HEAD(&(ext_state->extensions));
84     INIT_LIST_HEAD(&(ext_state->on_exits));
85     INIT_LIST_HEAD(&(ext_state->on_entries));
86     
87     return 0;
88 }
89
90
91 int v3_deinit_ext_manager(struct v3_vm_info * vm)  {
92
93         PrintError("I should really do something here... \n");
94         return -1;
95 }
96
97
98
99 int v3_add_extension(struct v3_vm_info * vm, const char * name, v3_cfg_tree_t * cfg) {
100     struct v3_extension_impl * impl = NULL;
101     struct v3_extension * ext = NULL;
102
103     impl = (void *)v3_htable_search(ext_table, (addr_t)name);
104
105     if (impl == NULL) {
106         PrintError("Could not find requested extension (%s)\n", name);
107         return -1;
108     }
109     
110     V3_ASSERT(impl->init);
111
112     ext = V3_Malloc(sizeof(struct v3_extension));
113     
114     if (!ext) {
115         PrintError("Could not allocate extension\n");
116         return -1;
117     }
118
119     ext->impl = impl;
120
121     if (impl->init(vm, cfg, &(ext->priv_data)) == -1) {
122         PrintError("Error initializing Extension (%s)\n", name);
123         V3_Free(ext);
124         return -1;
125     }
126
127     list_add(&(ext->node), &(vm->extensions.extensions));
128
129     if (impl->on_exit) {
130         list_add(&(ext->exit_node), &(vm->extensions.on_exits));
131     }
132
133     if (impl->on_entry) {
134         list_add(&(ext->entry_node), &(vm->extensions.on_entries));
135     }
136     
137     return 0;
138 }
139
140 int v3_init_core_extensions(struct guest_info * core) {
141     struct v3_extension * ext = NULL;
142
143     list_for_each_entry(ext, &(core->vm_info->extensions.extensions), node) {
144         if ((ext->impl) && (ext->impl->core_init)) {
145             if (ext->impl->core_init(core, ext->priv_data) == -1) {
146                 PrintError("Error configuring per core extension %s on core %d\n", 
147                            ext->impl->name, core->vcpu_id);
148                 return -1;
149             }
150         }
151     }
152
153     return 0;
154 }
155
156
157
158
159 void * v3_get_extension_state(struct v3_vm_info * vm, const char * name) {
160     struct v3_extension * ext = NULL;
161
162     list_for_each_entry(ext, &(vm->extensions.extensions), node) {
163         if (strncmp(ext->impl->name, name, strlen(ext->impl->name)) == 0) {
164             return ext->priv_data;
165         }
166     }
167
168     return NULL;
169 }