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);
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 struct global_ctrl * get_global_ctrl(unsigned int cmd) {
69 struct rb_node * n = global_ctrls.rb_node;
70 struct global_ctrl * ctrl = NULL;
73 ctrl = rb_entry(n, struct global_ctrl, tree_node);
75 if (cmd < ctrl->cmd) {
77 } else if (cmd > ctrl->cmd) {
96 struct linux_ext * impl;
98 struct list_head node;
102 void * get_vm_ext_data(struct v3_guest * guest, char * ext_name) {
103 struct vm_ext * ext = NULL;
105 list_for_each_entry(ext, &(guest->exts), node) {
106 if (strncmp(ext->impl->name, ext_name, strlen(ext->impl->name)) == 0) {
115 int init_vm_extensions(struct v3_guest * guest) {
116 extern struct linux_ext * __start__lnx_exts[];
117 extern struct linux_ext * __stop__lnx_exts[];
118 struct linux_ext * ext_impl = __start__lnx_exts[0];
121 while (ext_impl != __stop__lnx_exts[0]) {
122 struct vm_ext * ext = NULL;
124 if (ext_impl->guest_init == NULL) {
125 // We can have global extensions without per guest state
126 ext_impl = __start__lnx_exts[++i];
130 INFO("Registering Linux Extension (%s)\n", ext_impl->name);
132 ext = palacios_alloc(sizeof(struct vm_ext));
135 WARNING("Error allocating VM extension (%s)\n", ext_impl->name);
139 ext->impl = ext_impl;
141 ext_impl->guest_init(guest, &(ext->vm_data));
143 list_add(&(ext->node), &(guest->exts));
145 ext_impl = __start__lnx_exts[++i];
153 int deinit_vm_extensions(struct v3_guest * guest) {
154 struct vm_ext * ext = NULL;
155 struct vm_ext * tmp = NULL;
157 list_for_each_entry_safe(ext, tmp, &(guest->exts), node) {
158 if (ext->impl->guest_deinit) {
159 ext->impl->guest_deinit(guest, ext->vm_data);
161 WARNING("WARNING: Extension %s, does not have a guest deinit function\n", ext->impl->name);
164 list_del(&(ext->node));
172 int init_lnx_extensions( void ) {
173 extern struct linux_ext * __start__lnx_exts[];
174 extern struct linux_ext * __stop__lnx_exts[];
175 struct linux_ext * tmp_ext = __start__lnx_exts[0];
178 while (tmp_ext != __stop__lnx_exts[0]) {
180 DEBUG("tmp_ext=%p\n", tmp_ext);
182 if (tmp_ext->init != NULL) {
183 INFO("Registering Linux Extension (%s)\n", tmp_ext->name);
187 tmp_ext = __start__lnx_exts[++i];
194 int deinit_lnx_extensions( void ) {
195 extern struct linux_ext * __start__lnx_exts[];
196 extern struct linux_ext * __stop__lnx_exts[];
197 struct linux_ext * tmp_ext = __start__lnx_exts[0];
200 while (tmp_ext != __stop__lnx_exts[0]) {
201 INFO("Cleaning up Linux Extension (%s)\n", tmp_ext->name);
203 if (tmp_ext->deinit != NULL) {
206 WARNING("WARNING: Extension %s does not have a global deinit function\n", tmp_ext->name);
209 tmp_ext = __start__lnx_exts[++i];