struct guest_info;
void v3_init_cpuid_map(struct v3_vm_info * vm);
-
+int v3_deinit_cpuid_map(struct v3_vm_info * vm);
struct v3_cpuid_hook {
uint32_t cpuid;
void v3_init_hypercall_map(struct v3_vm_info * vm);
-
+int v3_deinit_hypercall_map(struct v3_vm_info * vm);
int v3_register_hypercall(struct v3_vm_info * vm, hcall_id_t hypercall_id,
int (*hypercall)(struct guest_info * info , hcall_id_t hcall_id, void * priv_data),
struct guest_info;
void v3_init_io_map(struct v3_vm_info * vm);
-
+int v3_deinit_io_map(struct v3_vm_info * vm);
void v3_init_msr_map(struct v3_vm_info * vm);
+int v3_deinit_msr_map(struct v3_vm_info * vm);
int v3_unhook_msr(struct v3_vm_info * vm, uint_t msr);
v3_deinit_intr_routers(vm);
v3_deinit_host_events(vm);
+ v3_deinit_cpuid_map(vm);
+ v3_deinit_msr_map(vm);
+ v3_deinit_io_map(vm);
+ v3_deinit_hypercall_map(vm);
+
+#ifdef CONFIG_TELEMETRY
+ v3_deinit_telemetry(vm);
+#endif
+
return 0;
}
// free vm
v3_free_vm_internal(vm);
+ V3_Free(vm);
return 0;
}
vm->cpuid_map.map.rb_node = NULL;
}
+int v3_deinit_cpuid_map(struct v3_vm_info * vm) {
+ struct rb_node * node = v3_rb_first(&(vm->cpuid_map.map));
+ struct v3_cpuid_hook * hook = NULL;
+ struct rb_node * tmp_node = NULL;
+
+
+ while (node) {
+ hook = rb_entry(node, struct v3_cpuid_hook, tree_node);
+ tmp_node = node;
+ node = v3_rb_next(node);
+
+ v3_rb_erase(&(hook->tree_node), &(vm->cpuid_map.map));
+ V3_Free(hook);
+
+ }
+
+ return 0;
+}
+
static inline struct v3_cpuid_hook * __insert_cpuid_hook(struct v3_vm_info * vm, struct v3_cpuid_hook * hook) {
struct rb_node ** p = &(vm->cpuid_map.map.rb_node);
}
-
-void v3_init_hypercall_map(struct v3_vm_info * vm) {
- vm->hcall_map.rb_node = NULL;
-
- v3_register_hypercall(vm, TEST_HCALL, hcall_test, NULL);
-}
-
-
struct hypercall {
uint_t id;
struct rb_node tree_node;
};
+static int free_hypercall(struct v3_vm_info * vm, struct hypercall * hcall);
+
+void v3_init_hypercall_map(struct v3_vm_info * vm) {
+ vm->hcall_map.rb_node = NULL;
+
+ v3_register_hypercall(vm, TEST_HCALL, hcall_test, NULL);
+}
+
+int v3_deinit_hypercall_map(struct v3_vm_info * vm) {
+ struct rb_node * node = NULL;
+ struct hypercall * hcall = NULL;
+ struct rb_node * tmp_node = NULL;
+
+ v3_remove_hypercall(vm, TEST_HCALL);
+
+ node = v3_rb_first(&(vm->hcall_map));
+
+ while (node) {
+ hcall = rb_entry(node, struct hypercall, tree_node);
+ tmp_node = node;
+ node = v3_rb_next(node);
+
+ free_hypercall(vm, hcall);
+ }
+
+ return 0;
+}
+
+
+
static inline struct hypercall * __insert_hypercall(struct v3_vm_info * vm, struct hypercall * hcall) {
}
+
+static int free_hypercall(struct v3_vm_info * vm, struct hypercall * hcall) {
+ v3_rb_erase(&(hcall->tree_node), &(vm->hcall_map));
+ V3_Free(hcall);
+
+ return 0;
+}
+
int v3_remove_hypercall(struct v3_vm_info * vm, hcall_id_t hypercall_id) {
struct hypercall * hcall = get_hypercall(vm, hypercall_id);
return -1;
}
- v3_rb_erase(&(hcall->tree_node), &(vm->hcall_map));
-
- V3_Free(hcall);
+ free_hypercall(vm, hcall);
return 0;
}
#define PrintDebug(fmt, args...)
#endif
+static int free_hook(struct v3_vm_info * vm, struct v3_io_hook * hook);
static int default_write(struct guest_info * core, uint16_t port, void *src, uint_t length, void * priv_data);
static int default_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data);
}
+int v3_deinit_io_map(struct v3_vm_info * vm) {
+ struct rb_node * node = v3_rb_first(&(vm->io_map.map));
+ struct v3_io_hook * hook = NULL;
+ struct rb_node * tmp_node = NULL;
+
+ while (node) {
+ hook = rb_entry(node, struct v3_io_hook, tree_node);
+ tmp_node = node;
+ node = v3_rb_next(node);
+
+ free_hook(vm, hook);
+ }
+
+ return 0;
+}
+
return tmp_hook;
}
}
+
rb_link_node(&(hook->tree_node), parent, p);
return NULL;
return 0;
}
-int v3_unhook_io_port(struct v3_vm_info * vm, uint16_t port) {
- struct v3_io_hook * hook = v3_get_io_hook(vm, port);
-
- if (hook == NULL) {
- PrintError("Could not find port to unhook %u (0x%x)\n", port, port);
- return -1;
- }
+static int free_hook(struct v3_vm_info * vm, struct v3_io_hook * hook) {
v3_rb_erase(&(hook->tree_node), &(vm->io_map.map));
if (vm->io_map.update_map) {
// set the arch map to default (this should be 1, 1)
- vm->io_map.update_map(vm, port, 0, 0);
+ vm->io_map.update_map(vm, hook->port, 0, 0);
}
V3_Free(hook);
return 0;
}
+int v3_unhook_io_port(struct v3_vm_info * vm, uint16_t port) {
+ struct v3_io_hook * hook = v3_get_io_hook(vm, port);
+
+ if (hook == NULL) {
+ PrintError("Could not find port to unhook %u (0x%x)\n", port, port);
+ return -1;
+ }
+
+ free_hook(vm, hook);
+
+ return 0;
+}
+
#include <palacios/vmm.h>
#include <palacios/vm_guest.h>
+static int free_hook(struct v3_vm_info * vm, struct v3_msr_hook * hook);
void v3_init_msr_map(struct v3_vm_info * vm) {
struct v3_msr_map * msr_map = &(vm->msr_map);
msr_map->update_map = NULL;
}
+int v3_deinit_msr_map(struct v3_vm_info * vm) {
+ struct v3_msr_hook * hook = NULL;
+ struct v3_msr_hook * tmp = NULL;
+
+ list_for_each_entry_safe(hook, tmp, &(vm->msr_map.hook_list), link) {
+ free_hook(vm, hook);
+ }
+
+ return 0;
+}
+
int v3_handle_msr_write(struct guest_info * info) {
uint_t msr_num = info->vm_regs.rcx;
struct v3_msr msr_val;
return 0;
}
+static int free_hook(struct v3_vm_info * vm, struct v3_msr_hook * hook) {
+ list_del(&(hook->link));
+
+ if (vm->msr_map.update_map) {
+ vm->msr_map.update_map(vm, hook->msr, 0, 0);
+ }
+
+ V3_Free(hook);
+
+ return 0;
+}
+
int v3_unhook_msr(struct v3_vm_info * vm, uint_t msr) {
struct v3_msr_hook * hook = v3_get_msr_hook(vm, msr);
return -1;
}
- list_del(&(hook->link));
-
- if (vm->msr_map.update_map) {
- vm->msr_map.update_map(vm, msr, 0, 0);
- }
-
- V3_Free(hook);
+ free_hook(vm, hook);
return 0;
}