Fixes include:
- Error handling
- Cleanup
- Standard init/uninit
Signed-off-by: Sasha Levin <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html