palacios-mm.o \
palacios-serial.o \
palacios-queue.o \
- palacios-ringbuffer.o
+ palacios-ringbuffer.o \
+ palacios-debugfs.o
ifdef CONFIG_PALACIOS_VNET
v3vee-objs += palacios-vnet.o
#include "palacios-vnet.h"
#include "palacios-packet.h"
+#ifdef CONFIG_DEBUG_FS
+#include "palacios-debugfs.h"
+#endif
+
MODULE_LICENSE("GPL");
int mod_allocs = 0;
palacios_file_init();
palacios_init_console();
+
+#ifdef CONFIG_DEBUG_FS
+ palacios_init_debugfs();
+#endif
+
return 0;
failure1:
class_destroy(v3_class);
+
+#ifdef CONFIG_DEBUG_FS
+ palacios_deinit_debugfs();
+#endif
+
palacios_file_deinit();
palacios_deinit_stream();
#include <linux/spinlock.h>
#ifdef CONFIG_DEBUG_FS
-#include <linux/debugfs.h>
+#include "palacios-debugfs.h"
#endif
#include <palacios/vmm.h>
extern u32 mallocs;
extern u32 frees;
-#include <palacios/vmm_inspector.h>
-
int start_palacios_vm(void * arg) {
struct v3_guest * guest = (struct v3_guest *)arg;
int err;
-#if 0
- // Inspection Test
- {
- struct v3_inspection_value rax;
- v3_inspect_node_t * core = NULL;
- v3_inspect_node_t * gprs = NULL;
- v3_inspect_node_t * root = v3_get_inspection_root(guest->v3_ctx);
-
- if (!root) {
- printk("NULL root inspection tree\n");
- }
-
- core = v3_get_inspection_subtree(root, "core.0");
- if (!core) {
- printk("NULL core inspection tree\n");
- }
-
- gprs = v3_get_inspection_subtree(core, "GPRS");
- if (!gprs) {
- printk("NULL gprs inspection tree\n");
- }
-
- v3_get_inspection_value(gprs, "RAX", &rax);
-
- debugfs_create_u64("RAX", 0644, NULL, (u64 *)rax.value);
- }
+#if CONFIG_DEBUG_FS
+ dfs_register_vm(guest);
#endif
#ifndef __VMM_INSPECTOR_H__
#define __VMM_INSPECTOR_H__
+#include <palacios/vmm.h>
typedef void v3_inspect_node_t;
struct v3_inspection_value {
char * name;
unsigned char * value;
- unsigned long long size;
+ unsigned long long size; // Size of 0 means this is a subtree root
unsigned char flags;
};
-int v3_get_inspection_value(v3_inspect_node_t * node, char * name,
+int v3_find_inspection_value(v3_inspect_node_t * node, char * name,
struct v3_inspection_value * value);
+struct v3_inspection_value v3_inspection_value(v3_inspect_node_t * node);
+
+
+
v3_inspect_node_t * v3_get_inspection_root(struct v3_vm_info * vm);
v3_inspect_node_t * v3_get_inspection_subtree(v3_inspect_node_t * root, char * name);
+
v3_inspect_node_t * v3_inspection_node_next(v3_inspect_node_t * node);
+v3_inspect_node_t * v3_inspection_first_child(v3_inspect_node_t * root);
#endif
struct v3_mtree {
char name[50];
- struct rb_node tree_node;
-
union {
uint8_t flags;
struct {
uint8_t subtree : 1;
+ uint8_t rsvd : 7;
} __attribute__((packed));
} __attribute__((packed));
void * value;
} __attribute__((packed));
-} __attribute__((packed));
+ struct rb_node tree_node;
+};
struct v3_mtree * v3_mtree_find_subtree(struct v3_mtree * root, char * name);
struct v3_mtree * v3_mtree_find_value(struct v3_mtree * root, char * name);
+
+struct v3_mtree * v3_mtree_first_child(struct v3_mtree * root);
+struct v3_mtree * v3_mtree_next_node(struct v3_mtree * node);
+
void v3_mtree_free_tree(struct v3_mtree * root);
void v3_mtree_free_node(struct v3_mtree * root, char * name);
+
#endif
#endif
int v3_init_inspector(struct v3_vm_info * vm) {
struct v3_inspector_state * state = (struct v3_inspector_state *)&(vm->inspector);
+ memset(state, 0, sizeof(struct v3_inspector_state));
+
strncpy(state->state_tree.name, "vm->name", 50);
state->state_tree.subtree = 1;
{
struct v3_mtree * core_node = v3_mtree_create_subtree(&(vm_state->state_tree), core_name);
- struct v3_mtree * gpr_node = v3_mtree_create_subtree(core_node, "GPRS");
+ v3_inspect_64(core_node, "RIP", (uint64_t *)&(core->rip));
+ v3_inspect_64(core_node, "NUM_EXITS", (uint64_t *)&(core->num_exits));
+ // v3_inspect_buf(core_node, "EXEC_NAME", core->exec_name, sizeof(core->exec_name));
+
+ struct v3_mtree * gpr_node = v3_mtree_create_subtree(core_node, "GPRS");
v3_inspect_64(gpr_node, "RAX", (uint64_t *)&(core->vm_regs.rax));
+ v3_inspect_64(gpr_node, "RBX", (uint64_t *)&(core->vm_regs.rbx));
+ v3_inspect_64(gpr_node, "RCX", (uint64_t *)&(core->vm_regs.rcx));
+ v3_inspect_64(gpr_node, "RDX", (uint64_t *)&(core->vm_regs.rdx));
+ v3_inspect_64(gpr_node, "RSP", (uint64_t *)&(core->vm_regs.rsp));
+ v3_inspect_64(gpr_node, "RBP", (uint64_t *)&(core->vm_regs.rbp));
+ v3_inspect_64(gpr_node, "RSI", (uint64_t *)&(core->vm_regs.rsi));
+ v3_inspect_64(gpr_node, "RDI", (uint64_t *)&(core->vm_regs.rdi));
+
+
+ struct v3_mtree * cr_node = v3_mtree_create_subtree(core_node, "CTRL_REGS");
+ v3_inspect_64(cr_node, "CR0", (uint64_t *)&(core->ctrl_regs.cr0));
+ v3_inspect_64(cr_node, "CR2", (uint64_t *)&(core->ctrl_regs.cr2));
+ v3_inspect_64(cr_node, "CR3", (uint64_t *)&(core->ctrl_regs.cr3));
+ v3_inspect_64(cr_node, "CR4", (uint64_t *)&(core->ctrl_regs.cr4));
+ v3_inspect_64(cr_node, "RFLAGS", (uint64_t *)&(core->ctrl_regs.rflags));
+ v3_inspect_64(cr_node, "EFER", (uint64_t *)&(core->ctrl_regs.efer));
+
+
+ // struct v3_mtree * seg_node = v3_mtree_create_subtree(core_node, "SEGMENTS");
+
+
+
}
return 0;
-int v3_get_inspection_value(v3_inspect_node_t * node, char * name,
+int v3_find_inspection_value(v3_inspect_node_t * node, char * name,
struct v3_inspection_value * value) {
struct v3_mtree * mt_node = v3_mtree_find_node(node, name);
return -1;
}
- value->value = mt_node->value;
- value->size = mt_node->size;
- value->flags = mt_node->user_flags;
- value->name = mt_node->name;
-
+ *value = v3_inspection_value(mt_node);
return 0;
}
+struct v3_inspection_value v3_inspection_value(v3_inspect_node_t * node) {
+ struct v3_mtree * mt_node = node;
+ struct v3_inspection_value value;
+
+ value.value = mt_node->value;
+ value.size = mt_node->size;
+ value.flags = mt_node->user_flags;
+ value.name = mt_node->name;
+
+ return value;
+}
+
+
v3_inspect_node_t * v3_get_inspection_root(struct v3_vm_info * vm) {
return &(vm->inspector.state_tree);
}
+v3_inspect_node_t * v3_inspection_node_next(v3_inspect_node_t * node) {
+ return v3_mtree_next_node(node);
+}
+
+v3_inspect_node_t * v3_inspection_first_child(v3_inspect_node_t * root) {
+ return v3_mtree_first_child(root);
+}
struct v3_mtree * ret = NULL;
+ PrintDebug("Creating Node %s\n", name);
+
memset(node, 0, sizeof(struct v3_mtree));
strncpy(node->name, name, 50);
if ((ret = __insert_mtree_node(root, node))) {
+ PrintError("Insertion failure\n");
V3_Free(node);
return NULL;
}
+ PrintDebug("Node (%s)=%p, root=%p, root->child=%p\n", node->name, node, root, root->child.rb_node);
v3_rb_insert_color(&(node->tree_node), &(root->child));
+ PrintDebug("balanced\n");
+
return node;
}
struct v3_mtree * v3_mtree_create_subtree(struct v3_mtree * root, char * name) {
- struct v3_mtree * node = v3_mtree_create_node(root, name);
+ struct v3_mtree * node = NULL;
PrintDebug("Creating Subtree %s\n", name);
+ node = v3_mtree_create_node(root, name);
if (node == NULL) {
return NULL;
struct v3_mtree * v3_mtree_create_value(struct v3_mtree * root, char * name,
uint64_t size, void * value) {
- struct v3_mtree * node = v3_mtree_create_node(root, name);
-
- PrintDebug("Creating value %s\n", name);
+ struct v3_mtree * node = NULL;
+ PrintDebug("Creating value %s\n", name);
+ node = v3_mtree_create_node(root, name);
if (node == NULL) {
return NULL;
return node;
}
+
+
+struct v3_mtree * v3_mtree_first_child(struct v3_mtree * root) {
+ struct rb_node * node = v3_rb_first(&(root->child));
+
+ if (node == NULL) {
+ return NULL;
+ }
+
+ return rb_entry(node, struct v3_mtree, tree_node);
+}
+
+
+struct v3_mtree * v3_mtree_next_node(struct v3_mtree * node) {
+ struct rb_node * next_node = v3_rb_next(&(node->tree_node));
+
+ if (next_node == NULL) {
+ return NULL;
+ }
+ return rb_entry(next_node, struct v3_mtree, tree_node);
+}