#include <palacios/vmm_hypercall.h>
#include <palacios/vmm_cpuid.h>
#include <palacios/vmm_regs.h>
+#include <palacios/vmm_extensions.h>
#ifdef CONFIG_TELEMETRY
#include <palacios/vmm_telemetry.h>
v3_vm_operating_mode_t run_state;
+
+
+
+ struct v3_extensions extensions;
+
#ifdef CONFIG_SYMBIOTIC
/* Symbiotic state */
struct v3_sym_vm_state sym_vm_state;
#endif
-
-
#ifdef CONFIG_TELEMETRY
uint_t enable_telemetry;
struct v3_telemetry_state telemetry;
#include <palacios/vmm.h>
#include <palacios/vmm_list.h>
-#include <palacios/vm_guest.h>
+#include <palacios/vmm_config.h>
+
+
+struct v3_vm_info;
+struct guest_info;
+
+struct v3_extensions {
+ struct list_head extensions;
+ struct list_head on_exits;
+ struct list_head on_entries;
+};
+
struct v3_extension_impl {
char * name;
- int (*init)(struct v3_vm_info * vm, v3_cfg_tree_t * cfg);
+ int (*init)(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data);
int (*deinit)(struct v3_vm_info * vm, void * priv_data);
int (*core_init)(struct guest_info * core);
int (*core_deinit)(struct guest_info * core);
+ int (*on_entry)(struct guest_info * core);
+ int (*on_exit)(struct guest_info * core);
};
-
-
struct v3_extension {
struct v3_extension_impl * impl;
void * priv_data;
struct list_head node;
+ struct list_head exit_node;
+ struct list_head entry_node;
};
int V3_deinit_extensions();
+int v3_init_ext_manager(struct v3_vm_info * vm);
+int v3_add_extension(struct v3_vm_info * vm, const char * name, v3_cfg_tree_t * cfg);
+
#define register_extension(ext) \
static struct v3_extension_impl * _v3_ext \
v3_init_cpuid_map(vm);
v3_init_host_events(vm);
v3_init_intr_routers(vm);
+ v3_init_ext_manager(vm);
// Initialize the memory map
if (v3_init_mem_map(vm) == -1) {
static int setup_memory_map(struct v3_vm_info * vm, v3_cfg_tree_t * cfg);
+static int setup_extensions(struct v3_vm_info * vm, v3_cfg_tree_t * cfg);
static int setup_devices(struct v3_vm_info * vm, v3_cfg_tree_t * cfg);
PrintError("Setting up guest memory map failed...\n");
return -1;
}
-
- //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
-
+
+ /*
+ * Initialize configured extensions
+ */
+ if (setup_extensions(vm, cfg) == -1) {
+ PrintError("Failed to setup extensions\n");
+ return -1;
+ }
+
+ /*
+ * Initialize configured devices
+ */
if (setup_devices(vm, cfg) == -1) {
PrintError("Failed to setup devices\n");
return -1;
}
+static int setup_extensions(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+ v3_cfg_tree_t * extension = v3_cfg_subtree(v3_cfg_subtree(cfg, "extensions"), "extension");
+
+ while (extension) {
+ char * ext_name = v3_cfg_val(extension, "name");
+
+ V3_Print("Configuring extension %s\n", ext_name);
+
+ if (v3_add_extension(vm, ext_name, extension) == -1) {
+ PrintError("Error adding extension %s\n", ext_name);
+ return -1;
+ }
+
+ extension = v3_cfg_next_branch(extension);
+ }
+
+ return 0;
+}
static int setup_devices(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
-
#include <palacios/vmm.h>
#include <palacios/vmm_extensions.h>
-
+#include <palacios/vm_guest.h>
#include <palacios/vmm_hashtable.h>
}
+int v3_init_ext_manager(struct v3_vm_info * vm) {
+ struct v3_extensions * ext_state = &(vm->extensions);
+
+ INIT_LIST_HEAD(&(ext_state->extensions));
+ INIT_LIST_HEAD(&(ext_state->on_exits));
+ INIT_LIST_HEAD(&(ext_state->on_entries));
+
+ return 0;
+}
+
+int v3_add_extension(struct v3_vm_info * vm, const char * name, v3_cfg_tree_t * cfg) {
+ struct v3_extension_impl * impl = NULL;
+ struct v3_extension * ext = NULL;
+
+ impl = (void *)v3_htable_search(ext_table, (addr_t)name);
+
+ if (impl == NULL) {
+ PrintError("Could not find requested extension (%s)\n", name);
+ return -1;
+ }
+
+ V3_ASSERT(impl->init);
+
+ ext = V3_Malloc(sizeof(struct v3_extension));
+
+ if (!ext) {
+ PrintError("Could not allocate extension\n");
+ return -1;
+ }
+
+ ext->impl = impl;
+
+ if (impl->init(vm, cfg, &(ext->priv_data)) == -1) {
+ PrintError("Error initializing Extension (%s)\n", name);
+ V3_Free(ext);
+ return -1;
+ }
+
+ list_add(&(ext->node), &(vm->extensions.extensions));
+
+ if (impl->on_exit) {
+ list_add(&(ext->exit_node), &(vm->extensions.on_exits));
+ }
+
+ if (impl->on_entry) {
+ list_add(&(ext->entry_node), &(vm->extensions.on_entries));
+ }
+
+ return 0;
+}
-static int init_mtrrs(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+static int init_mtrrs(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
+ V3_Print("Intializing MTRR extension\n");
v3_hook_msr(vm, MTRR_CAP_MSR, mtrr_cap_read, mtrr_cap_write, NULL);
}
-struct v3_extension_impl mtrr_ext = {
+static struct v3_extension_impl mtrr_ext = {
.name = "MTRRS",
.init = init_mtrrs,
.deinit = NULL,
return 0;
}
+int v3_offset_time( struct guest_info * info, sint64_t offset )
+{
+ struct vm_time * time_state = &(info->time_state);
+// PrintDebug("Adding additional offset of %lld to guest time.\n", offset);
+ time_state->guest_host_offset += offset;
+ return 0;
+}
+
// Control guest time in relation to host time so that the two stay
// appropriately synchronized to the extent possible.
int v3_adjust_time(struct guest_info * info) {
return 0;
}
-int v3_offset_time( struct guest_info * info, sint64_t offset )
-{
- struct vm_time * time_state = &(info->time_state);
-// PrintDebug("Adding additional offset of %lld to guest time.\n", offset);
- time_state->guest_host_offset += offset;
- return 0;
-}
+
struct v3_timer * v3_add_timer(struct guest_info * info,
struct v3_timer_ops * ops,