From: Jack Lange Date: Fri, 8 Apr 2011 20:01:54 +0000 (-0500) Subject: user space VM inspection works for GPRs, RIP, CTRL REGS X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=467878dcf7ccb6248c83483e01360b0ffdc83dc0;p=palacios-OLD.git user space VM inspection works for GPRs, RIP, CTRL REGS --- diff --git a/linux_module/Makefile b/linux_module/Makefile index 4163b1a..f20fb08 100644 --- a/linux_module/Makefile +++ b/linux_module/Makefile @@ -13,7 +13,8 @@ v3vee-objs:= palacios.o \ 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 diff --git a/linux_module/palacios-dev.c b/linux_module/palacios-dev.c index 1dfafc2..e3f83b6 100644 --- a/linux_module/palacios-dev.c +++ b/linux_module/palacios-dev.c @@ -28,6 +28,10 @@ #include "palacios-vnet.h" #include "palacios-packet.h" +#ifdef CONFIG_DEBUG_FS +#include "palacios-debugfs.h" +#endif + MODULE_LICENSE("GPL"); int mod_allocs = 0; @@ -271,6 +275,11 @@ static int __init v3_init(void) { palacios_file_init(); palacios_init_console(); + +#ifdef CONFIG_DEBUG_FS + palacios_init_debugfs(); +#endif + return 0; failure1: @@ -311,6 +320,11 @@ static void __exit v3_exit(void) { class_destroy(v3_class); + +#ifdef CONFIG_DEBUG_FS + palacios_deinit_debugfs(); +#endif + palacios_file_deinit(); palacios_deinit_stream(); diff --git a/linux_module/palacios-vm.c b/linux_module/palacios-vm.c index 943bbff..0e1f51e 100644 --- a/linux_module/palacios-vm.c +++ b/linux_module/palacios-vm.c @@ -18,7 +18,7 @@ #include #ifdef CONFIG_DEBUG_FS -#include +#include "palacios-debugfs.h" #endif #include @@ -106,8 +106,6 @@ extern u32 pg_frees; extern u32 mallocs; extern u32 frees; -#include - int start_palacios_vm(void * arg) { struct v3_guest * guest = (struct v3_guest *)arg; int err; @@ -152,32 +150,8 @@ int start_palacios_vm(void * arg) { -#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 diff --git a/palacios/include/palacios/vmm_inspector.h b/palacios/include/palacios/vmm_inspector.h index a24ca1c..ee0f70d 100644 --- a/palacios/include/palacios/vmm_inspector.h +++ b/palacios/include/palacios/vmm_inspector.h @@ -21,6 +21,7 @@ #ifndef __VMM_INSPECTOR_H__ #define __VMM_INSPECTOR_H__ +#include typedef void v3_inspect_node_t; @@ -65,18 +66,24 @@ v3_inspect_node_t * v3_inspect_add_subtree(v3_inspect_node_t * root, char * name 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 diff --git a/palacios/include/palacios/vmm_multitree.h b/palacios/include/palacios/vmm_multitree.h index 14f15e8..1fab8a2 100644 --- a/palacios/include/palacios/vmm_multitree.h +++ b/palacios/include/palacios/vmm_multitree.h @@ -32,12 +32,11 @@ 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)); @@ -50,7 +49,8 @@ struct v3_mtree { void * value; } __attribute__((packed)); -} __attribute__((packed)); + struct rb_node tree_node; +}; @@ -65,11 +65,16 @@ struct v3_mtree * v3_mtree_find_node(struct v3_mtree * root, char * name); 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 diff --git a/palacios/src/palacios/vmm_inspector.c b/palacios/src/palacios/vmm_inspector.c index c838843..2ff611b 100644 --- a/palacios/src/palacios/vmm_inspector.c +++ b/palacios/src/palacios/vmm_inspector.c @@ -30,6 +30,8 @@ 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; @@ -45,9 +47,35 @@ int v3_init_inspector_core(struct guest_info * core) { { 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; @@ -96,7 +124,7 @@ int v3_inspect_buf(v3_inspect_node_t * node, char * name, -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); @@ -104,15 +132,24 @@ int v3_get_inspection_value(v3_inspect_node_t * node, char * 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); @@ -123,3 +160,10 @@ v3_inspect_node_t * v3_get_inspection_subtree(v3_inspect_node_t * root, char * n } +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); +} diff --git a/palacios/src/palacios/vmm_multitree.c b/palacios/src/palacios/vmm_multitree.c index 5c9adb7..309d1a0 100644 --- a/palacios/src/palacios/vmm_multitree.c +++ b/palacios/src/palacios/vmm_multitree.c @@ -57,25 +57,32 @@ struct v3_mtree * v3_mtree_create_node(struct v3_mtree * root, char * name) { 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; @@ -89,10 +96,10 @@ struct v3_mtree * v3_mtree_create_subtree(struct v3_mtree * root, char * name) { 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; @@ -153,3 +160,24 @@ struct v3_mtree * v3_mtree_find_value(struct v3_mtree * root, char * name) { 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); +}