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.


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