From 973870bc9af39ce2df9bb1dd0318891071605fff Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 18 Dec 2011 22:14:22 +0200 Subject: [PATCH] kvm tools: Fixes for serial module Fixes include: - Error handling - Cleanup - Standard init/uninit Signed-off-by: Sasha Levin --- tools/kvm/builtin-run.c | 11 +++++++- tools/kvm/hw/serial.c | 41 ++++++++++++++++++++++++++--- tools/kvm/include/kvm/8250-serial.h | 3 ++- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index 73ca754f1968..4f4843d4acce 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -1115,7 +1115,11 @@ static int kvm_cmd_run_init(int argc, const char **argv) rtc__init(); - serial8250__init(kvm); + r = serial8250__init(kvm); + if (r < 0) { + pr_err("serial__init() failed with error %d\n", r); + goto fail; + } if (active_console == CONSOLE_VIRTIO) virtio_console__init(kvm); @@ -1224,6 +1228,7 @@ static int kvm_cmd_run_work(void) r = 0; kvm_cpu__delete(kvm_cpus[0]); + kvm_cpus[0] = NULL; for (i = 1; i < nrcpus; i++) { if (kvm_cpus[i]->is_running) { @@ -1261,6 +1266,10 @@ static void kvm_cmd_run_exit(int guest_ret) disk_image__close_all(kvm->disks, image_count); free(kvm_cpus); + r = serial8250__exit(kvm); + if (r < 0) + pr_warning("serial8250__exit() failed with error %d\n", r); + r = ioport__exit(kvm); if (r < 0) pr_warning("ioport__exit() failed with error %d\n", r); diff --git a/tools/kvm/hw/serial.c b/tools/kvm/hw/serial.c index d1d67b0d5a2f..852aea423c8a 100644 --- a/tools/kvm/hw/serial.c +++ b/tools/kvm/hw/serial.c @@ -396,19 +396,52 @@ static struct ioport_operations serial8250_ops = { .io_out = serial8250_out, }; -static void serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev) +static int serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev) { - ioport__register(dev->iobase, &serial8250_ops, 8, NULL); + int r; + + r = ioport__register(dev->iobase, &serial8250_ops, 8, NULL); kvm__irq_line(kvm, dev->irq, 0); + + return r; } -void serial8250__init(struct kvm *kvm) +int serial8250__init(struct kvm *kvm) +{ + unsigned int i, j; + int r = 0; + + for (i = 0; i < ARRAY_SIZE(devices); i++) { + struct serial8250_device *dev = &devices[i]; + + r = serial8250__device_init(kvm, dev); + if (r < 0) + goto cleanup; + } + + return r; +cleanup: + for (j = 0; j <= i; j++) { + struct serial8250_device *dev = &devices[j]; + + ioport__unregister(dev->iobase); + } + + return r; +} + +int serial8250__exit(struct kvm *kvm) { unsigned int i; + int r; for (i = 0; i < ARRAY_SIZE(devices); i++) { struct serial8250_device *dev = &devices[i]; - serial8250__device_init(kvm, dev); + r = ioport__unregister(dev->iobase); + if (r < 0) + return r; } + + return 0; } diff --git a/tools/kvm/include/kvm/8250-serial.h b/tools/kvm/include/kvm/8250-serial.h index 8bd8798153b7..df8ef5308385 100644 --- a/tools/kvm/include/kvm/8250-serial.h +++ b/tools/kvm/include/kvm/8250-serial.h @@ -3,7 +3,8 @@ struct kvm; -void serial8250__init(struct kvm *kvm); +int serial8250__init(struct kvm *kvm); +int serial8250__exit(struct kvm *kvm); void serial8250__update_consoles(struct kvm *kvm); void serial8250__inject_sysrq(struct kvm *kvm); -- 2.39.5