Commit-ID: 3dfcb6ec85d5430622c8b99ca05451c1afd08bf5 Gitweb: http://git.kernel.org/tip/3dfcb6ec85d5430622c8b99ca05451c1afd08bf5 Author: Cyrill Gorcunov <gorcunov@xxxxxxxxxx> AuthorDate: Mon, 6 Feb 2012 00:19:02 +0400 Committer: Pekka Enberg <penberg@xxxxxxxxxx> CommitDate: Mon, 6 Feb 2012 12:17:37 +0200 kvm tool: Don't close not yet opened files and SIGSEV fix In case if there error happened in kvm__init and we have no files opened -- we should not try to close them. Also once kvm failed to init the caller should not try to dereference a pointer obtained, otherwise we might get SIGSEV | [cyrill@moon kvm]$ ./lkvm run ... | Error: '/dev/kvm' not found. Please make sure your kernel has CONFIG_KVM | enabled and that the KVM modules are loaded. | Segmentation fault (core dumped) | [cyrill@moon kvm]$ Signed-off-by: Cyrill Gorcunov <gorcunov@xxxxxxxxx> Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxx> --- tools/kvm/builtin-run.c | 4 ++++ tools/kvm/kvm.c | 41 +++++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index 95d35a5..466169e 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -997,6 +997,10 @@ static int kvm_cmd_run_init(int argc, const char **argv) } kvm = kvm__init(dev, hugetlbfs_path, ram_size, guest_name); + if (IS_ERR(kvm)) { + r = PTR_ERR(kvm); + goto fail; + } kvm->single_step = single_step; diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c index 74e37ae..9a0bd67 100644 --- a/tools/kvm/kvm.c +++ b/tools/kvm/kvm.c @@ -123,10 +123,12 @@ static int kvm__check_extensions(struct kvm *kvm) static struct kvm *kvm__new(void) { struct kvm *kvm = calloc(1, sizeof(*kvm)); - if (!kvm) return ERR_PTR(-ENOMEM); + kvm->sys_fd = -1; + kvm->vm_fd = -1; + return kvm; } @@ -341,47 +343,42 @@ struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_s } kvm = kvm__new(); - if (IS_ERR_OR_NULL(kvm)) + if (IS_ERR(kvm)) return kvm; kvm->sys_fd = open(kvm_dev, O_RDWR); if (kvm->sys_fd < 0) { - if (errno == ENOENT) { + if (errno == ENOENT) pr_err("'%s' not found. Please make sure your kernel has CONFIG_KVM " - "enabled and that the KVM modules are loaded.", kvm_dev); - ret = -errno; - goto cleanup; - } - if (errno == ENODEV) { - die("'%s' KVM driver not available.\n # (If the KVM " - "module is loaded then 'dmesg' may offer further clues " - "about the failure.)", kvm_dev); - ret = -errno; - goto cleanup; - } + "enabled and that the KVM modules are loaded.", kvm_dev); + else if (errno == ENODEV) + pr_err("'%s' KVM driver not available.\n # (If the KVM " + "module is loaded then 'dmesg' may offer further clues " + "about the failure.)", kvm_dev); + else + pr_err("Could not open %s: ", kvm_dev); - pr_err("Could not open %s: ", kvm_dev); ret = -errno; - goto cleanup; + goto err_free; } ret = ioctl(kvm->sys_fd, KVM_GET_API_VERSION, 0); if (ret != KVM_API_VERSION) { pr_err("KVM_API_VERSION ioctl"); ret = -errno; - goto cleanup; + goto err_sys_fd; } kvm->vm_fd = ioctl(kvm->sys_fd, KVM_CREATE_VM, 0); if (kvm->vm_fd < 0) { ret = kvm->vm_fd; - goto cleanup; + goto err_sys_fd; } kvm->name = strdup(name); if (!kvm->name) { ret = -ENOMEM; - goto cleanup; + goto err; } if (kvm__check_extensions(kvm)) { @@ -393,10 +390,14 @@ struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_s kvm_ipc__start(kvm__create_socket(kvm)); kvm_ipc__register_handler(KVM_IPC_PID, kvm__pid); + return kvm; -cleanup: + +err: close(kvm->vm_fd); +err_sys_fd: close(kvm->sys_fd); +err_free: free(kvm); return ERR_PTR(ret); -- To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html