Fixes include: - Error handling - Cleanup - Standard init/uninit Signed-off-by: Sasha Levin <levinsasha...@gmail.com> --- tools/kvm/builtin-run.c | 11 ++++++++- tools/kvm/hw/serial.c | 43 ++++++++++++++++++++++++++++++---- tools/kvm/include/kvm/8250-serial.h | 3 +- 3 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index b7e7977..eef3f80 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -1072,7 +1072,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_error("serial__init() failed with error %d\n", r); + goto fail; + } if (active_console == CONSOLE_VIRTIO) virtio_console__init(kvm); @@ -1180,6 +1184,7 @@ static int kvm_cmd_run_work(void) if (pthread_join(kvm_cpus[0]->thread, &ret) != 0) r = 0; + kvm_cpus[0] = NULL; for (i = 1; i < nrcpus; i++) { if (kvm_cpus[i]->is_running) { pthread_kill(kvm_cpus[i]->thread, SIGKVMEXIT); @@ -1214,6 +1219,10 @@ static void kvm_cmd_run_uninit(int guest_ret) disk_image__close_all(kvm->disks, image_count); + r = serial8250__uninit(kvm); + if (r < 0) + pr_warning("serial8250__uninit() failed with error %d\n", r); + r = ioport__uninit(kvm); if (r < 0) pr_warning("ioport__uninit() failed with error %d\n", r); diff --git a/tools/kvm/hw/serial.c b/tools/kvm/hw/serial.c index c0f6970..561fc72 100644 --- a/tools/kvm/hw/serial.c +++ b/tools/kvm/hw/serial.c @@ -339,19 +339,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; + unsigned int i, j; + int r = 0; for (i = 0; i < ARRAY_SIZE(devices); i++) { struct serial8250_device *dev = &devices[i]; - serial8250__device_init(kvm, dev); + 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__uninit(struct kvm *kvm) +{ + unsigned int i; + int r; + + for (i = 0; i < ARRAY_SIZE(devices); i++) { + struct serial8250_device *dev = &devices[i]; + + r = ioport__unregister(dev->iobase); + if (r < 0) + return r; + } + + return 0; +} \ No newline at end of file diff --git a/tools/kvm/include/kvm/8250-serial.h b/tools/kvm/include/kvm/8250-serial.h index 8bd8798..1800cbf 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__uninit(struct kvm *kvm); void serial8250__update_consoles(struct kvm *kvm); void serial8250__inject_sysrq(struct kvm *kvm); -- 1.7.8 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html