This patch makes debug output go to a 'debug_fd' instead of stdout. Doing so allows us to send the output to a different console when required. This patch also changes the behaviour of 'kvm debug' to show the debug output in the console that executed the debug command instead of in the console of the guest. Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> --- tools/kvm/builtin-debug.c | 9 ++++ tools/kvm/builtin-run.c | 8 +++- tools/kvm/include/kvm/kvm-cpu.h | 2 + tools/kvm/kvm-cpu.c | 78 ++++++++++++++++++++++---------------- 4 files changed, 63 insertions(+), 34 deletions(-) diff --git a/tools/kvm/builtin-debug.c b/tools/kvm/builtin-debug.c index f744a7e..63804fd 100644 --- a/tools/kvm/builtin-debug.c +++ b/tools/kvm/builtin-debug.c @@ -47,6 +47,7 @@ void kvm_debug_help(void) static int do_debug(const char *name, int sock) { + char buff[100]; struct debug_cmd cmd = {KVM_IPC_DEBUG, 0}; int r; @@ -54,6 +55,14 @@ static int do_debug(const char *name, int sock) if (r < 0) return r; + do { + r = read(sock, buff, 100); + if (r < 0) + return 0; + printf("%s", buff); + memset(buff, 0, 100); + } while (r > 0); + return 0; } diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index bc4f07b..bfade41 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -456,11 +456,12 @@ static int printout_done; static void handle_sigusr1(int sig) { struct kvm_cpu *cpu = current_kvm_cpu; + int fd = kvm_cpu__get_debug_fd(); if (!cpu) return; - printf("\n #\n # vCPU #%ld's dump:\n #\n", cpu->cpu_id); + dprintf(fd, "\n #\n # vCPU #%ld's dump:\n #\n", cpu->cpu_id); kvm_cpu__show_registers(cpu); kvm_cpu__show_code(cpu); kvm_cpu__show_page_tables(cpu); @@ -496,6 +497,8 @@ static void handle_debug(int fd, u32 type, u32 len, u8 *msg) continue; printout_done = 0; + + kvm_cpu__set_debug_fd(fd); pthread_kill(cpu->thread, SIGUSR1); /* * Wait for the vCPU to dump state before signalling @@ -506,6 +509,8 @@ static void handle_debug(int fd, u32 type, u32 len, u8 *msg) mb(); } + close(fd); + serial8250__inject_sysrq(kvm); } @@ -539,6 +544,7 @@ panic_kvm: fprintf(stderr, "KVM exit code: 0x%Lu\n", current_kvm_cpu->kvm_run->hw.hardware_exit_reason); + kvm_cpu__set_debug_fd(STDOUT_FILENO); kvm_cpu__show_registers(current_kvm_cpu); kvm_cpu__show_code(current_kvm_cpu); kvm_cpu__show_page_tables(current_kvm_cpu); diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h index 95f3f9d..01540ac 100644 --- a/tools/kvm/include/kvm/kvm-cpu.h +++ b/tools/kvm/include/kvm/kvm-cpu.h @@ -37,6 +37,8 @@ void kvm_cpu__run(struct kvm_cpu *vcpu); void kvm_cpu__reboot(void); int kvm_cpu__start(struct kvm_cpu *cpu); +int kvm_cpu__get_debug_fd(void); +void kvm_cpu__set_debug_fd(int fd); void kvm_cpu__show_code(struct kvm_cpu *vcpu); void kvm_cpu__show_registers(struct kvm_cpu *vcpu); void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu); diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c index d7ae5ce..0ad6f3b 100644 --- a/tools/kvm/kvm-cpu.c +++ b/tools/kvm/kvm-cpu.c @@ -19,6 +19,18 @@ extern struct kvm_cpu *kvm_cpus[KVM_NR_CPUS]; extern __thread struct kvm_cpu *current_kvm_cpu; +static int debug_fd; + +void kvm_cpu__set_debug_fd(int fd) +{ + debug_fd = fd; +} + +int kvm_cpu__get_debug_fd(void) +{ + return debug_fd; +} + static inline bool is_in_protected_mode(struct kvm_cpu *vcpu) { return vcpu->sregs.cr0 & 0x01; @@ -216,13 +228,13 @@ void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu) static void print_dtable(const char *name, struct kvm_dtable *dtable) { - printf(" %s %016llx %08hx\n", + dprintf(debug_fd, " %s %016llx %08hx\n", name, (u64) dtable->base, (u16) dtable->limit); } static void print_segment(const char *name, struct kvm_segment *seg) { - printf(" %s %04hx %016llx %08x %02hhx %x %x %x %x %x %x %x\n", + dprintf(debug_fd, " %s %04hx %016llx %08x %02hhx %x %x %x %x %x %x %x\n", name, (u16) seg->selector, (u64) seg->base, (u32) seg->limit, (u8) seg->type, seg->present, seg->dpl, seg->db, seg->s, seg->l, seg->g, seg->avl); } @@ -254,14 +266,14 @@ void kvm_cpu__show_registers(struct kvm_cpu *vcpu) r10 = regs.r10; r11 = regs.r11; r12 = regs.r12; r13 = regs.r13; r14 = regs.r14; r15 = regs.r15; - printf("\n Registers:\n"); - printf( " ----------\n"); - printf(" rip: %016lx rsp: %016lx flags: %016lx\n", rip, rsp, rflags); - printf(" rax: %016lx rbx: %016lx rcx: %016lx\n", rax, rbx, rcx); - printf(" rdx: %016lx rsi: %016lx rdi: %016lx\n", rdx, rsi, rdi); - printf(" rbp: %016lx r8: %016lx r9: %016lx\n", rbp, r8, r9); - printf(" r10: %016lx r11: %016lx r12: %016lx\n", r10, r11, r12); - printf(" r13: %016lx r14: %016lx r15: %016lx\n", r13, r14, r15); + dprintf(debug_fd, "\n Registers:\n"); + dprintf(debug_fd, " ----------\n"); + dprintf(debug_fd, " rip: %016lx rsp: %016lx flags: %016lx\n", rip, rsp, rflags); + dprintf(debug_fd, " rax: %016lx rbx: %016lx rcx: %016lx\n", rax, rbx, rcx); + dprintf(debug_fd, " rdx: %016lx rsi: %016lx rdi: %016lx\n", rdx, rsi, rdi); + dprintf(debug_fd, " rbp: %016lx r8: %016lx r9: %016lx\n", rbp, r8, r9); + dprintf(debug_fd, " r10: %016lx r11: %016lx r12: %016lx\n", r10, r11, r12); + dprintf(debug_fd, " r13: %016lx r14: %016lx r15: %016lx\n", r13, r14, r15); if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0) die("KVM_GET_REGS failed"); @@ -269,11 +281,11 @@ void kvm_cpu__show_registers(struct kvm_cpu *vcpu) cr0 = sregs.cr0; cr2 = sregs.cr2; cr3 = sregs.cr3; cr4 = sregs.cr4; cr8 = sregs.cr8; - printf(" cr0: %016lx cr2: %016lx cr3: %016lx\n", cr0, cr2, cr3); - printf(" cr4: %016lx cr8: %016lx\n", cr4, cr8); - printf("\n Segment registers:\n"); - printf( " ------------------\n"); - printf(" register selector base limit type p dpl db s l g avl\n"); + dprintf(debug_fd, " cr0: %016lx cr2: %016lx cr3: %016lx\n", cr0, cr2, cr3); + dprintf(debug_fd, " cr4: %016lx cr8: %016lx\n", cr4, cr8); + dprintf(debug_fd, "\n Segment registers:\n"); + dprintf(debug_fd, " ------------------\n"); + dprintf(debug_fd, " register selector base limit type p dpl db s l g avl\n"); print_segment("cs ", &sregs.cs); print_segment("ss ", &sregs.ss); print_segment("ds ", &sregs.ds); @@ -285,17 +297,17 @@ void kvm_cpu__show_registers(struct kvm_cpu *vcpu) print_dtable("gdt", &sregs.gdt); print_dtable("idt", &sregs.idt); - printf("\n APIC:\n"); - printf( " -----\n"); - printf(" efer: %016llx apic base: %016llx nmi: %s\n", + dprintf(debug_fd, "\n APIC:\n"); + dprintf(debug_fd, " -----\n"); + dprintf(debug_fd, " efer: %016llx apic base: %016llx nmi: %s\n", (u64) sregs.efer, (u64) sregs.apic_base, (vcpu->kvm->nmi_disabled ? "disabled" : "enabled")); - printf("\n Interrupt bitmap:\n"); - printf( " -----------------\n"); + dprintf(debug_fd, "\n Interrupt bitmap:\n"); + dprintf(debug_fd, " -----------------\n"); for (i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++) - printf(" %016llx", (u64) sregs.interrupt_bitmap[i]); - printf("\n"); + dprintf(debug_fd, " %016llx", (u64) sregs.interrupt_bitmap[i]); + dprintf(debug_fd, "\n"); } #define MAX_SYM_LEN 128 @@ -318,12 +330,12 @@ void kvm_cpu__show_code(struct kvm_cpu *vcpu) ip = guest_flat_to_host(vcpu->kvm, ip_to_flat(vcpu, vcpu->regs.rip) - code_prologue); - printf("\n Code:\n"); - printf( " -----\n"); + dprintf(debug_fd, "\n Code:\n"); + dprintf(debug_fd, " -----\n"); symbol__lookup(vcpu->kvm, vcpu->regs.rip, sym, MAX_SYM_LEN); - printf(" rip: [<%016lx>] %s\n\n", (unsigned long) vcpu->regs.rip, sym); + dprintf(debug_fd, " rip: [<%016lx>] %s\n\n", (unsigned long) vcpu->regs.rip, sym); for (i = 0; i < code_len; i++, ip++) { if (!host_ptr_in_ram(vcpu->kvm, ip)) @@ -332,15 +344,15 @@ void kvm_cpu__show_code(struct kvm_cpu *vcpu) c = *ip; if (ip == guest_flat_to_host(vcpu->kvm, ip_to_flat(vcpu, vcpu->regs.rip))) - printf(" <%02x>", c); + dprintf(debug_fd, " <%02x>", c); else - printf(" %02x", c); + dprintf(debug_fd, " %02x", c); } - printf("\n"); + dprintf(debug_fd, "\n"); - printf("\n Stack:\n"); - printf( " ------\n"); + dprintf(debug_fd, "\n Stack:\n"); + dprintf(debug_fd, " ------\n"); kvm__dump_mem(vcpu->kvm, vcpu->regs.rsp, 32); } @@ -373,13 +385,13 @@ void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) if (!host_ptr_in_ram(vcpu->kvm, pte1)) return; - printf("Page Tables:\n"); + dprintf(debug_fd, "Page Tables:\n"); if (*pte2 & (1 << 7)) - printf(" pte4: %016llx pte3: %016llx" + dprintf(debug_fd, " pte4: %016llx pte3: %016llx" " pte2: %016llx\n", *pte4, *pte3, *pte2); else - printf(" pte4: %016llx pte3: %016llx pte2: %016" + dprintf(debug_fd, " pte4: %016llx pte3: %016llx pte2: %016" "llx pte1: %016llx\n", *pte4, *pte3, *pte2, *pte1); } -- 1.7.7 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html