Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Context-based output infrastructure (V3_Print, etc) and modifications to use it
[palacios.git] / palacios / src / extensions / ext_inspector.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20
21 //#include <palacios/vmm_inspector.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vm_guest.h>
24 #include <palacios/vmm_sprintf.h>
25 #include <palacios/vmm_extensions.h>
26
27 #include <palacios/vmm_multitree.h>
28 #include <interfaces/inspector.h>
29
30 // Note that v3_inspect_node_t is actuall a struct v3_mtree
31 // Its set as void for opaque portability
32
33 struct v3_inspector_state {
34     struct v3_mtree state_tree;
35
36 };
37
38
39 static int init_inspector(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
40     struct v3_inspector_state * state = V3_Malloc(sizeof(struct v3_inspector_state));
41
42     if (!state) {
43         PrintError(vm, VCORE_NONE, "Cannot allocate state in inspector\n");
44         return -1;
45     }
46
47     memset(state, 0, sizeof(struct v3_inspector_state));
48
49     strncpy(state->state_tree.name, "vm->name", 50);
50     state->state_tree.subtree = 1;
51
52     *priv_data = state;
53
54     return 0;
55 }
56
57
58 static int init_inspector_core(struct guest_info * core, void * priv_data, void ** core_data) {
59     struct v3_inspector_state * vm_state = priv_data;
60     char core_name[50];
61
62     snprintf(core_name, 50, "core.%d", core->vcpu_id);
63
64     {
65         struct v3_mtree * core_node = v3_mtree_create_subtree(&(vm_state->state_tree), core_name);
66         v3_inspect_64(core_node, "RIP", (uint64_t *)&(core->rip));
67         v3_inspect_64(core_node, "NUM_EXITS", (uint64_t *)&(core->num_exits));
68         //      v3_inspect_buf(core_node, "EXEC_NAME", core->exec_name, sizeof(core->exec_name));
69
70
71         struct v3_mtree * gpr_node = v3_mtree_create_subtree(core_node, "GPRS");
72         v3_inspect_64(gpr_node, "RAX", (uint64_t *)&(core->vm_regs.rax));    
73         v3_inspect_64(gpr_node, "RBX", (uint64_t *)&(core->vm_regs.rbx));    
74         v3_inspect_64(gpr_node, "RCX", (uint64_t *)&(core->vm_regs.rcx));    
75         v3_inspect_64(gpr_node, "RDX", (uint64_t *)&(core->vm_regs.rdx));    
76         v3_inspect_64(gpr_node, "RSP", (uint64_t *)&(core->vm_regs.rsp));    
77         v3_inspect_64(gpr_node, "RBP", (uint64_t *)&(core->vm_regs.rbp));    
78         v3_inspect_64(gpr_node, "RSI", (uint64_t *)&(core->vm_regs.rsi));    
79         v3_inspect_64(gpr_node, "RDI", (uint64_t *)&(core->vm_regs.rdi));    
80
81
82         struct v3_mtree * cr_node = v3_mtree_create_subtree(core_node, "CTRL_REGS");
83         v3_inspect_64(cr_node, "CR0", (uint64_t *)&(core->ctrl_regs.cr0));    
84         v3_inspect_64(cr_node, "CR2", (uint64_t *)&(core->ctrl_regs.cr2));    
85         v3_inspect_64(cr_node, "CR3", (uint64_t *)&(core->ctrl_regs.cr3));    
86         v3_inspect_64(cr_node, "CR4", (uint64_t *)&(core->ctrl_regs.cr4));    
87         v3_inspect_64(cr_node, "RFLAGS", (uint64_t *)&(core->ctrl_regs.rflags));    
88         v3_inspect_64(cr_node, "EFER", (uint64_t *)&(core->ctrl_regs.efer));    
89
90
91         //struct v3_mtree * seg_node = v3_mtree_create_subtree(core_node, "SEGMENTS");
92         
93
94
95     }
96
97     return 0;
98 }
99
100
101
102
103
104 static struct v3_extension_impl inspector_impl = {
105     .name = "inspector",
106     .init = init_inspector,
107     .deinit = NULL,
108     .core_init = init_inspector_core,
109     .core_deinit = NULL,
110     .on_entry = NULL,
111     .on_exit = NULL
112 };
113
114
115 register_extension(&inspector_impl);
116
117
118 v3_inspect_node_t * v3_inspect_add_subtree(v3_inspect_node_t * root, char * name) {
119     return v3_mtree_create_subtree(root, name);
120 }
121
122 int v3_inspect_8(v3_inspect_node_t * node, char * name, uint8_t * val) {
123     v3_mtree_create_value(node, name, 1, val);
124     return 0;
125 }
126
127
128 int v3_inspect_16(v3_inspect_node_t * node, char * name, uint16_t * val) {
129     v3_mtree_create_value(node, name, 2, val);
130
131     return 0;
132 }
133
134 int v3_inspect_32(v3_inspect_node_t * node, char * name, uint32_t * val) {
135     v3_mtree_create_value(node, name, 4, val); 
136     return 0;
137 }
138
139 int v3_inspect_64(v3_inspect_node_t * node, char * name, uint64_t * val) {
140     v3_mtree_create_value(node, name, 8, val);
141     return 0;
142 }
143
144 int v3_inspect_addr(v3_inspect_node_t * node, char * name, addr_t * val) {
145     v3_mtree_create_value(node, name, sizeof(addr_t), val);
146     return 0;
147 }
148
149 int v3_inspect_buf(v3_inspect_node_t * node, char * name, 
150                    uint8_t * buf, uint64_t size) {
151     v3_mtree_create_value(node, name, size, buf);
152
153     return 0;
154 }
155
156
157
158 int v3_find_inspection_value(v3_inspect_node_t * node, char * name, 
159                            struct v3_inspection_value * value) {
160     struct v3_mtree * mt_node = v3_mtree_find_node(node, name);
161     
162     if (!mt_node) {
163         return -1;
164     }
165     
166     *value = v3_inspection_value(mt_node);
167
168     return 0;
169 }
170
171 struct v3_inspection_value v3_inspection_value(v3_inspect_node_t * node) {
172     struct v3_mtree * mt_node = node;
173     struct v3_inspection_value value;
174
175     value.value = mt_node->value;
176     value.size = mt_node->size;
177     value.flags = mt_node->user_flags;
178     value.name = mt_node->name;
179
180     return value;
181 }
182
183
184
185 v3_inspect_node_t * v3_get_inspection_root(struct v3_vm_info * vm) {
186     struct v3_inspector_state * inspector = v3_get_extension_state(vm, inspector_impl.name);
187
188     if (inspector == NULL) {
189         return NULL;
190     }
191
192     return &(inspector->state_tree);
193 }
194
195 v3_inspect_node_t * v3_get_inspection_subtree(v3_inspect_node_t * root, char * name) {
196     return v3_mtree_find_subtree(root, name);
197 }
198
199
200 v3_inspect_node_t * v3_inspection_node_next(v3_inspect_node_t * node) {
201     return v3_mtree_next_node(node);
202 }
203
204 v3_inspect_node_t * v3_inspection_first_child(v3_inspect_node_t * root) {
205     return v3_mtree_first_child(root);
206 }
207
208
209
210