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.


8638f90ced429ba0e06af72ae00d5844e3f9283e
[palacios.git] / palacios / src / palacios / vmm_debug.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_debug.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vmm_host_events.h>
24 #include <palacios/vm_guest.h>
25 #include <palacios/vmm_decoder.h>
26 #include <palacios/vm_guest_mem.h>
27 #include <palacios/vmm_config.h>
28
29 #define PRINT_TELEMETRY  1
30 #define PRINT_CORE_STATE 2
31 #define PRINT_ARCH_STATE 3
32 #define PRINT_STACK      4
33 #define PRINT_BACKTRACE  5
34
35
36 #define PRINT_ALL        100 // Absolutely everything
37 #define PRINT_STATE      101 // telemetry, core state, arch state
38
39
40
41
42 static int core_handler(struct guest_info * core, uint32_t cmd) {
43
44
45     switch (cmd) {
46 #ifdef V3_CONFIG_TELEMETRY
47         case PRINT_TELEMETRY: 
48             v3_print_core_telemetry(core);
49             break;
50 #endif
51         
52         case PRINT_CORE_STATE:
53             v3_raise_barrier(core->vm_info, NULL);
54
55             v3_print_guest_state(core);
56
57             v3_lower_barrier(core->vm_info);
58             break;
59         case PRINT_ARCH_STATE:
60             v3_raise_barrier(core->vm_info, NULL);
61
62             v3_print_arch_state(core);
63
64             v3_lower_barrier(core->vm_info);
65             break;
66         case PRINT_STACK:
67             v3_raise_barrier(core->vm_info, NULL);
68
69             v3_print_stack(core);
70
71             v3_lower_barrier(core->vm_info);
72             break;
73         case PRINT_BACKTRACE:
74             v3_raise_barrier(core->vm_info, NULL);
75
76             v3_print_backtrace(core);
77             
78             v3_lower_barrier(core->vm_info);
79             break;
80
81         case PRINT_STATE:
82             v3_raise_barrier(core->vm_info, NULL);
83
84 #ifdef V3_CONFIG_TELEMETRY
85             v3_print_core_telemetry(core);
86 #endif
87             v3_print_guest_state(core);
88             v3_print_arch_state(core);
89
90             v3_lower_barrier(core->vm_info);
91             break;
92
93         case PRINT_ALL:
94             v3_raise_barrier(core->vm_info, NULL);
95
96 #ifdef V3_CONFIG_TELEMETRY
97             v3_print_core_telemetry(core);
98 #endif
99             v3_print_guest_state(core);
100             v3_print_arch_state(core);
101         v3_print_stack(core);
102         v3_print_backtrace(core);
103
104             v3_lower_barrier(core->vm_info);
105             break;
106
107     }
108
109     return 0;
110 }
111
112
113 static int evt_handler(struct v3_vm_info * vm, struct v3_debug_event * evt, void * priv_data) {
114
115     V3_Print(vm, VCORE_NONE,"Debug Event Handler for core %d cmd=%x\n", evt->core_id, evt->cmd);
116
117     if (evt->core_id == -1) {
118         int i = 0;
119         for (i = 0; i < vm->num_cores; i++) {
120             core_handler(&(vm->cores[i]), evt->cmd);
121         }
122     } else {
123         return core_handler(&vm->cores[evt->core_id], evt->cmd);
124     }
125
126     
127     return 0;
128 }
129
130
131 int v3_init_vm_debugging(struct v3_vm_info * vm) {
132     v3_hook_host_event(vm, HOST_DEBUG_EVT, 
133                        V3_HOST_EVENT_HANDLER(evt_handler), 
134                        NULL);
135
136
137     return 0;
138 }
139
140
141
142
143
144 void v3_print_segments(struct v3_segments * segs) {
145     int i = 0;
146     struct v3_segment * seg_ptr;
147
148     seg_ptr=(struct v3_segment *)segs;
149   
150     char *seg_names[] = {"CS", "DS" , "ES", "FS", "GS", "SS" , "LDTR", "GDTR", "IDTR", "TR", NULL};
151     V3_Print(VM_NONE, VCORE_NONE, "Segments\n");
152
153     for (i = 0; seg_names[i] != NULL; i++) {
154
155         V3_Print(VM_NONE, VCORE_NONE, "\t%s: Sel=%x, base=%p, limit=%x (long_mode=%d, db=%d)\n", seg_names[i], seg_ptr[i].selector, 
156                    (void *)(addr_t)seg_ptr[i].base, seg_ptr[i].limit,
157                    seg_ptr[i].long_mode, seg_ptr[i].db);
158
159     }
160 }
161
162
163
164 void v3_print_ctrl_regs(struct guest_info * core) {
165     struct v3_ctrl_regs * regs = &(core->ctrl_regs);
166     int i = 0;
167     v3_reg_t * reg_ptr;
168     char * reg_names[] = {"CR0", "CR2", "CR3", "CR4", "CR8", "FLAGS", "EFER", NULL};
169    
170
171     reg_ptr = (v3_reg_t *)regs;
172
173     V3_Print(core->vm_info, core,"Ctrl Regs:\n");
174
175     for (i = 0; reg_names[i] != NULL; i++) {
176         V3_Print(core->vm_info, core, "\t%s=0x%p (at %p)\n", reg_names[i], (void *)(addr_t)reg_ptr[i], &(reg_ptr[i]));  
177     }
178
179
180 }
181
182 #if 0
183 static int safe_gva_to_hva(struct guest_info * core, addr_t linear_addr, addr_t * host_addr) {
184     /* select the proper translation based on guest mode */
185     if (core->mem_mode == PHYSICAL_MEM) {
186         if (v3_gpa_to_hva(core, linear_addr, host_addr) == -1) return -1;
187     } else if (core->mem_mode == VIRTUAL_MEM) {
188         if (v3_gva_to_hva(core, linear_addr, host_addr) == -1) return -1;
189     }
190     return 0;
191 }
192
193 static int v3_print_disassembly(struct guest_info * core) {
194     int passed_rip = 0;
195     addr_t rip, rip_linear, rip_host;
196
197     /* we don't know where the instructions preceding RIP start, so we just take
198      * a guess and hope the instruction stream synced up with our disassembly
199      * some time before RIP; if it has not we correct RIP at that point
200      */
201
202     /* start disassembly 64 bytes before current RIP, continue 32 bytes after */
203     rip = (addr_t) core->rip - 64;
204     while ((int) (rip - core->rip) < 32) {
205         V3_Print(info->vm_info, info, "disassembly step\n");
206
207         /* always print RIP, even if the instructions before were bad */
208         if (!passed_rip && rip >= core->rip) {
209             if (rip != core->rip) {
210                 V3_Print(info->vm_info, info, "***** bad disassembly up to this point *****\n");
211                 rip = core->rip;
212             }
213             passed_rip = 1;
214         }
215
216         /* look up host virtual address for this instruction */
217         rip_linear = get_addr_linear(core, rip, &(core->segments.cs));
218         if (safe_gva_to_hva(core, rip_linear, &rip_host) < 0) {
219             rip++;
220             continue;
221         }
222
223         /* print disassembled instrcution (updates rip) */
224         if (v3_disasm(core, (void *) rip_host, &rip, rip == core->rip) < 0) {
225             rip++;
226             continue;
227         }
228
229     }
230
231     return 0;
232 }
233
234 #endif
235
236 void v3_print_guest_state(struct guest_info * core) {
237     addr_t linear_addr = 0; 
238
239     V3_Print(core->vm_info, core, "RIP: %p\n", (void *)(addr_t)(core->rip));
240     linear_addr = get_addr_linear(core, core->rip, &(core->segments.cs));
241     V3_Print(core->vm_info, core, "RIP Linear: %p\n", (void *)linear_addr);
242
243     V3_Print(core->vm_info, core, "NumExits: %u\n", (uint32_t)core->num_exits);
244
245     V3_Print(core->vm_info, core, "IRQ STATE: started=%d, pending=%d\n", 
246              core->intr_core_state.irq_started, 
247              core->intr_core_state.irq_pending);
248     V3_Print(core->vm_info, core, "EXCP STATE: err_code_valid=%d, err_code=%x\n", 
249              core->excp_state.excp_error_code_valid, 
250              core->excp_state.excp_error_code);
251
252
253     v3_print_segments(&(core->segments));
254     v3_print_ctrl_regs(core);
255
256     if (core->shdw_pg_mode == SHADOW_PAGING) {
257         V3_Print(core->vm_info, core, "Shadow Paging Guest Registers:\n");
258         V3_Print(core->vm_info, core, "\tGuest CR0=%p\n", (void *)(addr_t)(core->shdw_pg_state.guest_cr0));
259         V3_Print(core->vm_info, core, "\tGuest CR3=%p\n", (void *)(addr_t)(core->shdw_pg_state.guest_cr3));
260         V3_Print(core->vm_info, core, "\tGuest EFER=%p\n", (void *)(addr_t)(core->shdw_pg_state.guest_efer.value));
261         // CR4
262     }
263     v3_print_GPRs(core);
264
265     v3_print_mem_map(core->vm_info);
266
267     v3_print_stack(core);
268
269     //  v3_print_disassembly(core);
270 }
271
272
273 void v3_print_arch_state(struct guest_info * core) {
274
275
276 }
277
278
279 void v3_print_guest_state_all(struct v3_vm_info * vm) {
280     int i = 0;
281
282     V3_Print(vm, VCORE_NONE,"VM Core states for %s\n", vm->name);
283
284     for (i = 0; i < 80; i++) {
285       V3_Print(vm, VCORE_NONE, "-");
286     }
287
288     for (i = 0; i < vm->num_cores; i++) {
289         v3_print_guest_state(&vm->cores[i]);  
290     }
291     
292     for (i = 0; i < 80; i++) {
293         V3_Print(vm, VCORE_NONE, "-");
294     }
295
296     V3_Print(vm, VCORE_NONE, "\n");    
297 }
298
299
300
301 void v3_print_stack(struct guest_info * core) {
302     addr_t linear_addr = 0;
303     addr_t host_addr = 0;
304     int i = 0;
305     v3_cpu_mode_t cpu_mode = v3_get_vm_cpu_mode(core);
306
307     linear_addr = get_addr_linear(core, core->vm_regs.rsp, &(core->segments.ss));
308  
309     V3_Print(core->vm_info, core, "Stack at %p:\n", (void *)linear_addr);
310    
311     if (core->mem_mode == PHYSICAL_MEM) {
312         if (v3_gpa_to_hva(core, linear_addr, &host_addr) == -1) {
313             PrintError(core->vm_info, core, "Could not translate Stack address\n");
314             return;
315         }
316     } else if (core->mem_mode == VIRTUAL_MEM) {
317         if (v3_gva_to_hva(core, linear_addr, &host_addr) == -1) {
318             PrintError(core->vm_info, core, "Could not translate Virtual Stack address\n");
319             return;
320         }
321     }
322     
323     V3_Print(core->vm_info, core, "Host Address of rsp = 0x%p\n", (void *)host_addr);
324  
325     // We start i at one because the current stack pointer points to an unused stack element
326     for (i = 0; i <= 24; i++) {
327
328         if (cpu_mode == REAL) {
329             V3_Print(core->vm_info, core, "\t0x%.4x\n", *((uint16_t *)host_addr + (i * 2)));
330         } else if (cpu_mode == LONG) {
331             V3_Print(core->vm_info, core, "\t%p\n", (void *)*(addr_t *)(host_addr + (i * 8)));
332         } else {
333             // 32 bit stacks...
334             V3_Print(core->vm_info, core, "\t0x%.8x\n", *(uint32_t *)(host_addr + (i * 4)));
335         }
336     }
337
338 }    
339
340
341 void v3_print_backtrace(struct guest_info * core) {
342     addr_t gla_rbp = 0;
343     int i = 0;
344     v3_cpu_mode_t cpu_mode = v3_get_vm_cpu_mode(core);
345     struct v3_cfg_file * system_map = v3_cfg_get_file(core->vm_info, "System.map");
346
347     V3_Print(core->vm_info, core, "Performing Backtrace for Core %d\n", core->vcpu_id);
348     V3_Print(core->vm_info, core, "\tRSP=%p, RBP=%p\n", (void *)core->vm_regs.rsp, (void *)core->vm_regs.rbp);
349
350     gla_rbp = get_addr_linear(core, core->vm_regs.rbp, &(core->segments.ss));
351
352
353     for (i = 0; i < 30; i++) {
354         addr_t hva_rbp = 0; 
355         addr_t hva_rip = 0; 
356         char * sym_name = NULL;
357         addr_t rip_val = 0;
358
359         if (core->mem_mode == PHYSICAL_MEM) {
360             if (v3_gpa_to_hva(core, gla_rbp, &hva_rbp) == -1) {
361                 PrintError(core->vm_info, core, "Could not translate Stack address\n");
362                 return;
363             }
364         } else if (core->mem_mode == VIRTUAL_MEM) {
365             if (v3_gva_to_hva(core, gla_rbp, &hva_rbp) == -1) {
366                 PrintError(core->vm_info, core, "Could not translate Virtual Stack address\n");
367                 return;
368             }
369         }
370
371
372         hva_rip = hva_rbp + v3_get_addr_width(core);
373         
374         if (cpu_mode == REAL) {
375             rip_val = (addr_t)*(uint16_t *)hva_rip;
376         } else if (cpu_mode == LONG) {
377             rip_val = (addr_t)*(uint64_t *)hva_rip;
378         } else {
379             rip_val = (addr_t)*(uint32_t *)hva_rip;
380         }
381
382         if (system_map) {
383             char * tmp_ptr = system_map->data;
384             char * sym_ptr = NULL;
385             uint64_t file_offset = 0; 
386             uint64_t sym_offset = 0;
387
388             while (file_offset < system_map->size) {
389                 sym_offset = strtox(tmp_ptr, &tmp_ptr);
390
391                 tmp_ptr += 3; // pass over symbol type
392
393                 if (sym_offset > rip_val) {
394                     char * end_ptr = strchr(sym_ptr, '\n');
395
396                     if (end_ptr) {
397                         *end_ptr = 0; // null terminate symbol...
398                     }
399
400                     sym_name = sym_ptr;
401                     break;
402                 }
403
404                 sym_ptr = tmp_ptr;
405                 { 
406                     char * end_ptr2 = strchr(tmp_ptr, '\n');
407
408                     if (!end_ptr2) {
409                         tmp_ptr += strlen(tmp_ptr) + 1;
410                     } else {
411                         tmp_ptr = end_ptr2 + 1;
412                     }
413                 }
414             }
415         }
416
417         if (!sym_name) {
418             sym_name = "?";
419         }
420
421         if (cpu_mode == REAL) {
422             V3_Print(core->vm_info, core, "Next RBP=0x%.4x, RIP=0x%.4x (%s)\n", 
423                      *(uint16_t *)hva_rbp,*(uint16_t *)hva_rip, 
424                      sym_name);
425             
426             gla_rbp = *(uint16_t *)hva_rbp;
427         } else if (cpu_mode == LONG) {
428             V3_Print(core->vm_info, core, "Next RBP=%p, RIP=%p (%s)\n", 
429                      (void *)*(uint64_t *)hva_rbp, (void *)*(uint64_t *)hva_rip,
430                      sym_name);
431             gla_rbp = *(uint64_t *)hva_rbp;
432         } else {
433             V3_Print(core->vm_info, core, "Next RBP=0x%.8x, RIP=0x%.8x (%s)\n", 
434                      *(uint32_t *)hva_rbp, *(uint32_t *)hva_rip,
435                      sym_name);
436             gla_rbp = *(uint32_t *)hva_rbp;
437         }
438
439     }
440 }
441
442
443 #ifdef __V3_32BIT__
444
445 void v3_print_GPRs(struct guest_info * core) {
446     struct v3_gprs * regs = &(core->vm_regs);
447     int i = 0;
448     v3_reg_t * reg_ptr;
449     char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", NULL};
450
451     reg_ptr = (v3_reg_t *)regs;
452
453     V3_Print(info->vm_info, info, "32 bit GPRs:\n");
454
455     for (i = 0; reg_names[i] != NULL; i++) {
456         V3_Print(info->vm_info, info, "\t%s=0x%p (at %p)\n", reg_names[i], (void *)(addr_t)reg_ptr[i], &(reg_ptr[i]));  
457     }
458 }
459
460 #elif __V3_64BIT__
461
462 void v3_print_GPRs(struct guest_info * core) {
463     struct v3_gprs * regs = &(core->vm_regs);
464     int i = 0;
465     v3_reg_t * reg_ptr;
466     char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", \
467                            "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", NULL};
468
469     reg_ptr = (v3_reg_t *)regs;
470
471     V3_Print(core->vm_info, core, "64 bit GPRs:\n");
472
473     for (i = 0; reg_names[i] != NULL; i++) {
474         V3_Print(core->vm_info, core, "\t%s=0x%p (at %p)\n", reg_names[i], (void *)(addr_t)reg_ptr[i], &(reg_ptr[i]));  
475     }
476 }
477
478 #endif