1 #include "linux-exts.h"
4 * This is a place holder to ensure that the _lnx_exts section gets created by gcc
7 static struct {} null_ext __attribute__((__used__)) \
8 __attribute__((unused, __section__ ("_lnx_exts"), \
9 aligned(sizeof(void *))));
17 struct rb_root global_ctrls;
19 static inline struct global_ctrl * __insert_global_ctrl(struct global_ctrl * ctrl) {
20 struct rb_node ** p = &(global_ctrls.rb_node);
21 struct rb_node * parent = NULL;
22 struct global_ctrl * tmp_ctrl = NULL;
26 tmp_ctrl = rb_entry(parent, struct global_ctrl, tree_node);
28 if (ctrl->cmd < tmp_ctrl->cmd) {
30 } else if (ctrl->cmd > tmp_ctrl->cmd) {
37 rb_link_node(&(ctrl->tree_node), parent, p);
44 int add_global_ctrl(unsigned int cmd,
45 int (*handler)(unsigned int cmd, unsigned long arg)) {
46 struct global_ctrl * ctrl = palacios_alloc_extended(sizeof(struct global_ctrl), GFP_KERNEL,-1);
49 printk("Error: Could not allocate global ctrl %d\n", cmd);
54 ctrl->handler = handler;
56 if (__insert_global_ctrl(ctrl) != NULL) {
57 printk("Could not insert guest ctrl %d\n", cmd);
62 rb_insert_color(&(ctrl->tree_node), &(global_ctrls));
68 static struct rb_node * find_match(unsigned int cmd) {
69 struct rb_node * n = global_ctrls.rb_node;
70 struct global_ctrl *ctrl;
73 ctrl = rb_entry(n, struct global_ctrl, tree_node);
75 if (cmd < ctrl->cmd) {
77 } else if (cmd > ctrl->cmd) {
88 struct global_ctrl * get_global_ctrl(unsigned int cmd) {
89 struct rb_node *n = find_match(cmd);
92 return rb_entry(n, struct global_ctrl, tree_node);
99 int remove_global_ctrl(unsigned int cmd)
101 struct rb_node *n = find_match(cmd);
102 struct global_ctrl *c;
108 c = rb_entry(n, struct global_ctrl, tree_node);
110 rb_erase(n,&global_ctrls);
128 struct linux_ext * impl;
130 struct list_head node;
134 void * get_vm_ext_data(struct v3_guest * guest, char * ext_name) {
135 struct vm_ext * ext = NULL;
137 list_for_each_entry(ext, &(guest->exts), node) {
138 if (strncmp(ext->impl->name, ext_name, strlen(ext->impl->name)) == 0) {
147 int init_vm_extensions(struct v3_guest * guest) {
148 extern struct linux_ext * __start__lnx_exts[];
149 extern struct linux_ext * __stop__lnx_exts[];
150 struct linux_ext * ext_impl = __start__lnx_exts[0];
153 while (ext_impl != __stop__lnx_exts[0]) {
154 struct vm_ext * ext = NULL;
156 if (ext_impl->guest_init == NULL) {
157 // We can have global extensions without per guest state
158 ext_impl = __start__lnx_exts[++i];
162 INFO("Registering Linux Extension (%s)\n", ext_impl->name);
164 ext = palacios_alloc(sizeof(struct vm_ext));
167 WARNING("Error allocating VM extension (%s)\n", ext_impl->name);
171 ext->impl = ext_impl;
173 ext_impl->guest_init(guest, &(ext->vm_data));
175 list_add(&(ext->node), &(guest->exts));
177 ext_impl = __start__lnx_exts[++i];
185 int deinit_vm_extensions(struct v3_guest * guest) {
186 struct vm_ext * ext = NULL;
187 struct vm_ext * tmp = NULL;
189 list_for_each_entry_safe(ext, tmp, &(guest->exts), node) {
190 if (ext->impl->guest_deinit) {
191 ext->impl->guest_deinit(guest, ext->vm_data);
193 WARNING("WARNING: Extension %s, does not have a guest deinit function\n", ext->impl->name);
196 list_del(&(ext->node));
204 int init_lnx_extensions( void ) {
205 extern struct linux_ext * __start__lnx_exts[];
206 extern struct linux_ext * __stop__lnx_exts[];
207 struct linux_ext * tmp_ext = __start__lnx_exts[0];
210 while (tmp_ext != __stop__lnx_exts[0]) {
212 DEBUG("tmp_ext=%p\n", tmp_ext);
214 if (tmp_ext->init != NULL) {
215 INFO("Registering Linux Extension (%s)\n", tmp_ext->name);
219 tmp_ext = __start__lnx_exts[++i];
226 int deinit_lnx_extensions( void ) {
227 extern struct linux_ext * __start__lnx_exts[];
228 extern struct linux_ext * __stop__lnx_exts[];
229 struct linux_ext * tmp_ext = __start__lnx_exts[0];
232 while (tmp_ext != __stop__lnx_exts[0]) {
233 INFO("Cleaning up Linux Extension (%s)\n", tmp_ext->name);
235 if (tmp_ext->deinit != NULL) {
238 WARNING("WARNING: Extension %s does not have a global deinit function\n", tmp_ext->name);
241 tmp_ext = __start__lnx_exts[++i];