Fixes include: - Error handling - Cleanup - Standard init/uninit Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> --- tools/kvm/builtin-run.c | 31 ++++++++++++++------- tools/kvm/include/kvm/symbol.h | 7 +++- tools/kvm/symbol.c | 59 +++++++++++++++++++++++++++++++--------- tools/kvm/x86/kvm-cpu.c | 10 +++++-- 4 files changed, 79 insertions(+), 28 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index 0234879..3d046d7 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -851,7 +851,7 @@ static int kvm_cmd_run_init(int argc, const char **argv) struct framebuffer *fb = NULL; unsigned int nr_online_cpus; int max_cpus, recommended_cpus; - int i; + int i, r; signal(SIGALRM, handle_sigalrm); kvm_ipc__register_handler(KVM_IPC_DEBUG, handle_debug); @@ -946,8 +946,6 @@ static int kvm_cmd_run_init(int argc, const char **argv) if (!script) script = DEFAULT_SCRIPT; - symbol__init(vmlinux_filename); - term_init(); if (!guest_name) { @@ -1047,7 +1045,12 @@ static int kvm_cmd_run_init(int argc, const char **argv) real_cmdline, vidmode)) die("unable to load kernel %s", kernel_filename); - kvm->vmlinux = vmlinux_filename; + kvm->vmlinux = vmlinux_filename; + r = symbol__init(kvm); + if (r < 0) { + pr_error("symbol__init() failed with error %d\n", r); + goto fail; + } ioport__setup_arch(); @@ -1130,7 +1133,8 @@ static int kvm_cmd_run_init(int argc, const char **argv) thread_pool__init(nr_online_cpus); ioeventfd__start(); - return 0; +fail: + return r; } static int kvm_cmd_run_work(void) @@ -1160,10 +1164,16 @@ static int kvm_cmd_run_work(void) return r; } -static int kvm_cmd_run_uninit(int guest_ret) +static void kvm_cmd_run_uninit(int guest_ret) { + int r = 0; + compat__print_all_messages(); + r = symbol__uninit(kvm); + if (r < 0) + pr_warning("symbol__uninit() failed with error %d\n", r); + fb__stop(); virtio_blk__delete_all(kvm); @@ -1174,17 +1184,18 @@ static int kvm_cmd_run_uninit(int guest_ret) if (guest_ret == 0) printf("\n # KVM session ended normally.\n"); - - return 0; } int kvm_cmd_run(int argc, const char **argv, const char *prefix) { - int r, ret; + int r, ret = -EFAULT; r = kvm_cmd_run_init(argc, argv); + if (r < 0) + goto fail; ret = kvm_cmd_run_work(); - r = kvm_cmd_run_uninit(ret); + kvm_cmd_run_uninit(ret); +fail: return ret; } diff --git a/tools/kvm/include/kvm/symbol.h b/tools/kvm/include/kvm/symbol.h index 5bc2221..062f411 100644 --- a/tools/kvm/include/kvm/symbol.h +++ b/tools/kvm/include/kvm/symbol.h @@ -6,14 +6,17 @@ struct kvm; +#define SYMBOL_DEFAULT_UNKNOWN "<unknown>" + #ifdef CONFIG_HAS_BFD -void symbol__init(const char *vmlinux); +int symbol__init(struct kvm *kvm); +int symbol__uninit(struct kvm *kvm); char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size); #else static inline void symbol__init(const char *vmlinux) { } static inline char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size) { - char *s = strncpy(sym, "<unknown>", size); + char *s = strncpy(sym, SYMBOL_DEFAULT_UNKNOWN, size); sym[size - 1] = '\0'; return s; } diff --git a/tools/kvm/symbol.c b/tools/kvm/symbol.c index a2b1e67..54691a4 100644 --- a/tools/kvm/symbol.c +++ b/tools/kvm/symbol.c @@ -2,6 +2,7 @@ #include "kvm/kvm.h" +#include <linux/err.h> #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -9,19 +10,40 @@ static bfd *abfd; -void symbol__init(const char *vmlinux) +int symbol__init(struct kvm *kvm) { - if (!vmlinux) - return; + int r = 0; + + if (!kvm->vmlinux) + return -EINVAL; bfd_init(); - abfd = bfd_openr(vmlinux, NULL); + abfd = bfd_openr(kvm->vmlinux, NULL); + if (abfd == NULL) { + bfd_error_type err = bfd_get_error(); + + switch(err) { + case bfd_error_no_memory: + r = -ENOMEM; + break; + case bfd_error_invalid_target: + r = -EINVAL; + break; + default: + r = -EFAULT; + break; + } + } + + return r; } static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_name) { - int i; + int i, r; + + r = -ENOENT; for (i = 0; i < nr_symbols; i++) { asymbol *symbol = symbols[i]; @@ -30,7 +52,7 @@ static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_nam return symbol; } - return NULL; + return ERR_PTR(r); } char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size) @@ -44,9 +66,9 @@ char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size long symtab_size; asymbol *symbol; asymbol **syms; - int nr_syms; - char *s; + int nr_syms, r; + r = -ENOENT; if (!abfd) goto not_found; @@ -57,13 +79,15 @@ char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size if (!symtab_size) goto not_found; + r = -ENOMEM; syms = malloc(symtab_size); if (!syms) goto not_found; nr_syms = bfd_canonicalize_symtab(abfd, syms); - section = bfd_get_section_by_name(abfd, ".debug_aranges"); + r = -ENOENT; + section= bfd_get_section_by_name(abfd, ".debug_aranges"); if (!section) goto not_found; @@ -74,7 +98,7 @@ char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size goto not_found; symbol = lookup(syms, nr_syms, func); - if (!symbol) + if (IS_ERR(symbol)) goto not_found; sym_start = bfd_asymbol_value(symbol); @@ -90,9 +114,18 @@ char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size return sym; not_found: - s = strncpy(sym, "<unknown>", size); + return ERR_PTR(r); +} - sym[size - 1] = '\0'; +int symbol__uninit(struct kvm *kvm) +{ + bfd_boolean r = TRUE; + + if (abfd) + r = bfd_close(abfd); + + if (r == TRUE) + return 0; - return s; + return -EFAULT; } diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c index 051699f..4aa1b9a 100644 --- a/tools/kvm/x86/kvm-cpu.c +++ b/tools/kvm/x86/kvm-cpu.c @@ -6,7 +6,7 @@ #include <asm/msr-index.h> #include <asm/apicdef.h> - +#include <linux/err.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <signal.h> @@ -324,7 +324,7 @@ void kvm_cpu__show_code(struct kvm_cpu *vcpu) unsigned int code_bytes = 64; unsigned int code_prologue = 43; unsigned int code_len = code_bytes; - char sym[MAX_SYM_LEN]; + char sym[MAX_SYM_LEN] = SYMBOL_DEFAULT_UNKNOWN, *psym; unsigned char c; unsigned int i; u8 *ip; @@ -340,7 +340,11 @@ void kvm_cpu__show_code(struct kvm_cpu *vcpu) dprintf(debug_fd, "\n Code:\n"); dprintf(debug_fd, " -----\n"); - symbol__lookup(vcpu->kvm, vcpu->regs.rip, sym, MAX_SYM_LEN); + psym = symbol__lookup(vcpu->kvm, vcpu->regs.rip, sym, MAX_SYM_LEN); + if (IS_ERR(psym)) + dprintf(debug_fd, + "Warning: symbol__lookup() failed to find symbol " + "with error: %ld\n", PTR_ERR(psym)); dprintf(debug_fd, " rip: [<%016lx>] %s\n\n", (unsigned long) vcpu->regs.rip, sym); -- 1.7.8 -- 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