void v3_init_telemetry(struct v3_vm_info * vm);
void v3_init_core_telemetry(struct guest_info * info);
+void v3_deinit_telemetry(struct v3_vm_info * vm);
+void v3_deinit_core_telemetry(struct guest_info * core);
void v3_telemetry_start_exit(struct guest_info * info);
void v3_telemetry_end_exit(struct guest_info * info, uint_t exit_code);
static int virtio_free(struct virtio_dev_state * virtio) {
+ struct virtio_blk_state * blk_state = NULL;
+ struct virtio_blk_state * tmp = NULL;
+
+ list_for_each_entry_safe(blk_state, tmp, &(virtio->dev_list), dev_link) {
+
+ // unregister from PCI
+
+ list_del(&(blk_state->dev_link));
+ V3_Free(blk_state);
+ }
+
V3_Free(virtio);
return 0;
blk_state->pci_dev = pci_dev;
+
+
+ /* Add backend to list of devices */
+ list_add(&(blk_state->dev_link), &(virtio->dev_list));
/* Block configuration */
blk_state->virtio_cfg.host_features = VIRTIO_SEG_MAX;
return ret_val;
}
-static int virtio_free(struct virtio_net_state * virtio) {
-
- // unregister from PCI
+static int virtio_free(struct virtio_dev_state * virtio) {
+ struct virtio_net_state * backend = NULL;
+ struct virtio_net_state * tmp = NULL;
+
+
+ list_for_each_entry_safe(backend, tmp, &(virtio->dev_list), dev_link) {
+
+ // unregister from PCI
+
+ list_del(&(backend->dev_link));
+ V3_Free(backend);
+ }
V3_Free(virtio);
return 0;
virtio_init_state(net_state);
+
+ /* Add backend to list of devices */
+ list_add(&(net_state->dev_link), &(virtio->dev_list));
+
return 0;
}
};
+static int free_callback(struct v3_vm_info * vm, struct telemetry_cb * cb);
+static int free_exit(struct guest_info * core, struct exit_event * event);
+
+
void v3_init_telemetry(struct v3_vm_info * vm) {
struct v3_telemetry_state * telemetry = &(vm->telemetry);
INIT_LIST_HEAD(&(telemetry->cb_list));
}
+void v3_deinit_telemetry(struct v3_vm_info * vm) {
+ struct telemetry_cb * cb = NULL;
+ struct telemetry_cb * tmp = NULL;
+
+ list_for_each_entry_safe(cb, tmp, &(vm->telemetry.cb_list), cb_node) {
+ free_callback(vm, cb);
+ }
+}
+
+
void v3_init_core_telemetry(struct guest_info * core) {
struct v3_core_telemetry * telemetry = &(core->core_telem);
telemetry->exit_root.rb_node = NULL;
}
+void v3_deinit_core_telemetry(struct guest_info * core) {
+ struct rb_node * node = v3_rb_first(&(core->core_telem.exit_root));
+ struct exit_event * evt = NULL;
+
+ while (node) {
+ evt = rb_entry(node, struct exit_event, tree_node);
+ node = v3_rb_next(node);
+
+ free_exit(core, evt);
+ }
+}
+
static inline struct exit_event * __insert_event(struct guest_info * info,
return evt;
}
+
+
+static int free_exit(struct guest_info * core, struct exit_event * evt) {
+ v3_rb_erase(&(evt->tree_node), &(core->core_telem.exit_root));
+ V3_Free(evt);
+ return 0;
+}
+
+
void v3_telemetry_start_exit(struct guest_info * info) {
rdtscll(info->core_telem.vmm_start_tsc);
}
+static int free_callback(struct v3_vm_info * vm, struct telemetry_cb * cb) {
+ list_del(&(cb->cb_node));
+ V3_Free(cb);
+
+ return 0;
+}
+
+
void v3_print_telemetry(struct v3_vm_info * vm) {
struct v3_telemetry_state * telemetry = &(vm->telemetry);
uint64_t invoke_tsc = 0;