Rely on the fd exit path machinery. Signed-off-by: Christian Brauner (Amutable) --- drivers/virt/nitro_enclaves/ne_misc_dev.c | 33 ++++++++++++------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/virt/nitro_enclaves/ne_misc_dev.c b/drivers/virt/nitro_enclaves/ne_misc_dev.c index c91300a73f50..93c3f00f5443 100644 --- a/drivers/virt/nitro_enclaves/ne_misc_dev.c +++ b/drivers/virt/nitro_enclaves/ne_misc_dev.c @@ -1589,7 +1589,7 @@ static const struct file_operations ne_enclave_fops = { static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_uid) { struct ne_pci_dev_cmd_reply cmd_reply = {}; - int enclave_fd = -1; + const struct fd_slot *enclave_fd = NULL; struct file *enclave_file = NULL; unsigned int i = 0; struct ne_enclave *ne_enclave = NULL; @@ -1647,9 +1647,9 @@ static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_ui goto free_cpumask; } - enclave_fd = get_unused_fd_flags(O_CLOEXEC); - if (enclave_fd < 0) { - rc = enclave_fd; + enclave_fd = fd_prepare(O_CLOEXEC); + if (IS_ERR(enclave_fd)) { + rc = PTR_ERR(enclave_fd); dev_err_ratelimited(ne_misc_dev.this_device, "Error in getting unused fd [rc=%d]\n", rc); @@ -1664,7 +1664,7 @@ static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_ui dev_err_ratelimited(ne_misc_dev.this_device, "Error in anon inode get file [rc=%d]\n", rc); - goto put_fd; + goto free_cpumask; } rc = ne_do_request(pdev, SLOT_ALLOC, @@ -1688,27 +1688,20 @@ static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_ui list_add(&ne_enclave->enclave_list_entry, &ne_pci_dev->enclaves_list); - if (copy_to_user(slot_uid, &ne_enclave->slot_uid, sizeof(ne_enclave->slot_uid))) { - /* - * As we're holding the only reference to 'enclave_file', fput() - * will call ne_enclave_release() which will do a proper cleanup - * of all so far allocated resources, leaving only the unused fd - * for us to free. - */ - fput(enclave_file); - put_unused_fd(enclave_fd); + fd_stage(enclave_fd, enclave_file); + /* + * The failed ioctl drops the descriptor and with it the only reference + * to 'enclave_file', so ne_enclave_release() does a proper cleanup of + * all so far allocated resources. + */ + if (copy_to_user(slot_uid, &ne_enclave->slot_uid, sizeof(ne_enclave->slot_uid))) return -EFAULT; - } - - fd_install(enclave_fd, enclave_file); - return enclave_fd; + return fd_prepare_fd(enclave_fd); put_file: fput(enclave_file); -put_fd: - put_unused_fd(enclave_fd); free_cpumask: free_cpumask_var(ne_enclave->vcpu_ids); for (i = 0; i < ne_enclave->nr_parent_vm_cores; i++) -- 2.53.0