From: Jack Lange Date: Fri, 8 Apr 2011 18:17:28 +0000 (-0500) Subject: added inspection framework X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=374b2d6d22a0e0dc6ed8d3d628e635ab935072e0;p=palacios.git added inspection framework --- diff --git a/linux_module/palacios-vm.c b/linux_module/palacios-vm.c index b025649..943bbff 100644 --- a/linux_module/palacios-vm.c +++ b/linux_module/palacios-vm.c @@ -17,6 +17,9 @@ #include #include +#ifdef CONFIG_DEBUG_FS +#include +#endif #include @@ -25,6 +28,7 @@ #include "palacios-serial.h" #include "palacios-vm.h" + extern struct class * v3_class; #define STREAM_NAME_LEN 128 @@ -102,6 +106,7 @@ 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; @@ -145,6 +150,37 @@ int start_palacios_vm(void * arg) { printk("palacios: launching vm\n"); + + +#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); + } +#endif + + if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) { printk("palacios: launch of vm failed\n"); return -1; diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index d67fd9f..4b2728f 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -38,6 +38,8 @@ #include #include + + #ifdef CONFIG_TELEMETRY #include #endif @@ -48,6 +50,11 @@ struct v3_sym_core_state; #endif +#ifdef CONFIG_INSPECTOR +#include +#endif + + #include struct v3_intr_state; @@ -180,6 +187,10 @@ struct v3_vm_info { struct v3_telemetry_state telemetry; #endif +#ifdef CONFIG_INSPECTOR + struct v3_inspector_state inspector; +#endif + uint64_t yield_cycle_period; diff --git a/palacios/include/palacios/vmm_inspector.h b/palacios/include/palacios/vmm_inspector.h new file mode 100644 index 0000000..a24ca1c --- /dev/null +++ b/palacios/include/palacios/vmm_inspector.h @@ -0,0 +1,82 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +#ifndef __VMM_INSPECTOR_H__ +#define __VMM_INSPECTOR_H__ + + +typedef void v3_inspect_node_t; + +#ifdef __V3VEE__ + +#include + + + +// Flags +#define SERIALIZABLE 1 +#define READ_ONLY 2 +#define HOOKED 4 + +struct v3_inspector_state { + struct v3_mtree state_tree; + +}; + + + +int v3_init_inspector(struct v3_vm_info * vm); +int v3_init_inspector_core(struct guest_info * core); + + +int v3_inspect_8(v3_inspect_node_t * node, char * name, uint8_t * val); +int v3_inspect_16(v3_inspect_node_t * node, char * name, uint16_t * val); +int v3_inspect_32(v3_inspect_node_t * node, char * name, uint32_t * val); +int v3_inspect_64(v3_inspect_node_t * node, char * name, uint64_t * val); +int v3_inspect_addr(v3_inspect_node_t * node, char * name, addr_t * val); +int v3_inspect_buf(v3_inspect_node_t * node, char * name, uint8_t * buf, uint64_t size); + +v3_inspect_node_t * v3_inspect_add_subtree(v3_inspect_node_t * root, char * name); + + + + + +#endif + + +struct v3_inspection_value { + char * name; + unsigned char * value; + unsigned long long size; + unsigned char flags; +}; + + + + +int v3_get_inspection_value(v3_inspect_node_t * node, char * name, + struct v3_inspection_value * value); + +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); + +#endif diff --git a/palacios/include/palacios/vmm_multitree.h b/palacios/include/palacios/vmm_multitree.h new file mode 100644 index 0000000..14f15e8 --- /dev/null +++ b/palacios/include/palacios/vmm_multitree.h @@ -0,0 +1,75 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +#ifndef __VMM_MULTITREE_H__ +#define __VMM_MULTITREE_H__ + +#ifdef __V3VEE__ + +#include +#include +#include + + + +struct v3_mtree { + char name[50]; + + struct rb_node tree_node; + + union { + uint8_t flags; + struct { + uint8_t subtree : 1; + } __attribute__((packed)); + } __attribute__((packed)); + + uint8_t user_flags; + + uint64_t size; + + union { + struct rb_root child; + void * value; + } __attribute__((packed)); + +} __attribute__((packed)); + + + + + +struct v3_mtree * v3_mtree_create_node(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 * v3_mtree_create_subtree(struct v3_mtree * root, char * name); + +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); + +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/Makefile b/palacios/src/palacios/Makefile index 3af02b7..e06c481 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -36,8 +36,11 @@ obj-y := \ vmm_mptable.o \ vmm_extensions.o \ vmm_mtrr.o \ + vmm_multitree.o \ +obj-$(CONFIG_INSPECTOR) += vmm_inspector.o + obj-$(CONFIG_XED) += vmm_xed.o obj-$(CONFIG_V3_DECODER) += vmm_v3dec.o diff --git a/palacios/src/palacios/vm_guest.c b/palacios/src/palacios/vm_guest.c index 92f49b6..b8cc549 100644 --- a/palacios/src/palacios/vm_guest.c +++ b/palacios/src/palacios/vm_guest.c @@ -530,6 +530,10 @@ int v3_init_vm(struct v3_vm_info * vm) { v3_set_foreground_vm(vm); } +#ifdef CONFIG_INSPECTOR + v3_init_inspector(vm); +#endif + #ifdef CONFIG_TELEMETRY v3_init_telemetry(vm); #endif @@ -657,6 +661,10 @@ int v3_init_core(struct guest_info * core) { v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU()); struct v3_vm_info * vm = core->vm_info; +#ifdef CONFIG_INSPECTOR + v3_init_inspector_core(core); +#endif + /* * Initialize the subsystem data strutures */ diff --git a/palacios/src/palacios/vmm_inspector.c b/palacios/src/palacios/vmm_inspector.c new file mode 100644 index 0000000..c838843 --- /dev/null +++ b/palacios/src/palacios/vmm_inspector.c @@ -0,0 +1,125 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +#include +#include +#include +#include + +// Note that v3_inspect_node_t is actuall a struct v3_mtree +// Its set as void for opaque portability + + +int v3_init_inspector(struct v3_vm_info * vm) { + struct v3_inspector_state * state = (struct v3_inspector_state *)&(vm->inspector); + + strncpy(state->state_tree.name, "vm->name", 50); + state->state_tree.subtree = 1; + + return 0; +} + + +int v3_init_inspector_core(struct guest_info * core) { + struct v3_inspector_state * vm_state = &(core->vm_info->inspector); + char core_name[50]; + + snprintf(core_name, 50, "core.%d", core->cpu_id); + + { + 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(gpr_node, "RAX", (uint64_t *)&(core->vm_regs.rax)); + } + + return 0; +} + + +v3_inspect_node_t * v3_inspect_add_subtree(v3_inspect_node_t * root, char * name) { + return v3_mtree_create_subtree(root, name); +} + +int v3_inspect_8(v3_inspect_node_t * node, char * name, uint8_t * val) { + v3_mtree_create_value(node, name, 1, val); + return 0; +} + + +int v3_inspect_16(v3_inspect_node_t * node, char * name, uint16_t * val) { + v3_mtree_create_value(node, name, 2, val); + + return 0; +} + +int v3_inspect_32(v3_inspect_node_t * node, char * name, uint32_t * val) { + v3_mtree_create_value(node, name, 4, val); + return 0; +} + +int v3_inspect_64(v3_inspect_node_t * node, char * name, uint64_t * val) { + v3_mtree_create_value(node, name, 8, val); + return 0; +} + +int v3_inspect_addr(v3_inspect_node_t * node, char * name, addr_t * val) { + v3_mtree_create_value(node, name, sizeof(addr_t), val); + return 0; +} + +int v3_inspect_buf(v3_inspect_node_t * node, char * name, + uint8_t * buf, uint64_t size) { + v3_mtree_create_value(node, name, size, buf); + + return 0; +} + + + + + +int v3_get_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); + + if (!mt_node) { + return -1; + } + + value->value = mt_node->value; + value->size = mt_node->size; + value->flags = mt_node->user_flags; + value->name = mt_node->name; + + + return 0; +} + + +v3_inspect_node_t * v3_get_inspection_root(struct v3_vm_info * vm) { + return &(vm->inspector.state_tree); +} + +v3_inspect_node_t * v3_get_inspection_subtree(v3_inspect_node_t * root, char * name) { + return v3_mtree_find_subtree(root, name); +} + + diff --git a/palacios/src/palacios/vmm_multitree.c b/palacios/src/palacios/vmm_multitree.c new file mode 100644 index 0000000..5c9adb7 --- /dev/null +++ b/palacios/src/palacios/vmm_multitree.c @@ -0,0 +1,155 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +#include +#include + +#include + +static inline +struct v3_mtree * __insert_mtree_node(struct v3_mtree * root, struct v3_mtree * node) { + struct rb_node ** p = &(root->child.rb_node); + struct rb_node * parent = NULL; + struct v3_mtree * tmp_node; + + while (*p) { + int ret = 0; + parent = *p; + tmp_node = rb_entry(parent, struct v3_mtree, tree_node); + + ret = strcmp(node->name, tmp_node->name); + + if (ret < 0) { + p = &(*p)->rb_left; + } else if (ret > 0) { + p = &(*p)->rb_right; + } else { + return tmp_node; + } + } + + rb_link_node(&(node->tree_node), parent, p); + + return NULL; +} + + + +struct v3_mtree * v3_mtree_create_node(struct v3_mtree * root, char * name) { + struct v3_mtree * node = (struct v3_mtree *)V3_Malloc(sizeof(struct v3_mtree)); + struct v3_mtree * ret = NULL; + + + memset(node, 0, sizeof(struct v3_mtree)); + strncpy(node->name, name, 50); + + if ((ret = __insert_mtree_node(root, node))) { + V3_Free(node); + return NULL; + } + + + v3_rb_insert_color(&(node->tree_node), &(root->child)); + + 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); + + PrintDebug("Creating Subtree %s\n", name); + + if (node == NULL) { + return NULL; + } + + node->subtree = 1; + + return node; +} + + +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); + + + if (node == NULL) { + return NULL; + } + + node->size = size; + node->value = value; + + return node; +} + + + +struct v3_mtree * v3_mtree_find_node(struct v3_mtree * root, char * name) { + struct rb_node * n = root->child.rb_node; + struct v3_mtree * tmp_node = NULL; + + if (root->subtree == 0) { + PrintError("Searching for node on a non-root mtree (search=%s), root=%s\n", name, root->name); + return NULL; + } + + while (n) { + int ret = 0; + tmp_node = rb_entry(n, struct v3_mtree, tree_node); + ret = strcmp(tmp_node->name, name); + + if (ret < 0) { + n = n->rb_left; + } else if (ret > 0) { + n = n->rb_right; + } else { + return tmp_node; + } + } + + return NULL; +} + + +struct v3_mtree * v3_mtree_find_subtree(struct v3_mtree * root, char * name) { + struct v3_mtree * node = v3_mtree_find_node(root, name); + + if (node->subtree == 0) { + return NULL; + } + + return node; +} + + +struct v3_mtree * v3_mtree_find_value(struct v3_mtree * root, char * name) { + struct v3_mtree * node= v3_mtree_find_node(root, name); + + if (node->subtree == 1) { + return NULL; + } + + return node; +}