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.


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