[PATCH RFC POC 36/50] nitro_enclaves: install the enclave descriptor when the ioctl returns
From: Christian Brauner
Date: Tue Sep 15 2026 - 08:13:27 EST
Rely on the fd exit path machinery.
Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
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