static int ne_enclave_release()

in drivers/virt/nitro_enclaves/ne_misc_dev.c [1559:1630]


static int ne_enclave_release(struct inode *inode, struct file *file)
{
	struct ne_pci_dev_cmd_reply cmd_reply = {};
	struct enclave_stop_req enclave_stop_request = {};
	struct ne_enclave *ne_enclave = file->private_data;
	struct ne_pci_dev *ne_pci_dev = ne_devs.ne_pci_dev;
	struct pci_dev *pdev = ne_pci_dev->pdev;
	int rc = -EINVAL;
	struct slot_free_req slot_free_req = {};

	if (!ne_enclave)
		return 0;

	/*
	 * Early exit in case there is an error in the enclave creation logic
	 * and fput() is called on the cleanup path.
	 */
	if (!ne_enclave->slot_uid)
		return 0;

	/*
	 * Acquire the enclave list mutex before the enclave mutex
	 * in order to avoid deadlocks with @ref ne_event_work_handler.
	 */
	mutex_lock(&ne_pci_dev->enclaves_list_mutex);
	mutex_lock(&ne_enclave->enclave_info_mutex);

	if (ne_enclave->state != NE_STATE_INIT && ne_enclave->state != NE_STATE_STOPPED) {
		enclave_stop_request.slot_uid = ne_enclave->slot_uid;

		rc = ne_do_request(pdev, ENCLAVE_STOP,
				   &enclave_stop_request, sizeof(enclave_stop_request),
				   &cmd_reply, sizeof(cmd_reply));
		if (rc < 0) {
			dev_err_ratelimited(ne_misc_dev.this_device,
					    "Error in enclave stop [rc=%d]\n", rc);

			goto unlock_mutex;
		}

		memset(&cmd_reply, 0, sizeof(cmd_reply));
	}

	slot_free_req.slot_uid = ne_enclave->slot_uid;

	rc = ne_do_request(pdev, SLOT_FREE,
			   &slot_free_req, sizeof(slot_free_req),
			   &cmd_reply, sizeof(cmd_reply));
	if (rc < 0) {
		dev_err_ratelimited(ne_misc_dev.this_device,
				    "Error in slot free [rc=%d]\n", rc);

		goto unlock_mutex;
	}

	ne_pci_dev_remove_enclave_entry(ne_enclave, ne_pci_dev);
	ne_enclave_remove_all_mem_region_entries(ne_enclave);
	ne_enclave_remove_all_vcpu_id_entries(ne_enclave);

	mutex_unlock(&ne_enclave->enclave_info_mutex);
	mutex_unlock(&ne_pci_dev->enclaves_list_mutex);

	kfree(ne_enclave);

	return 0;

unlock_mutex:
	mutex_unlock(&ne_enclave->enclave_info_mutex);
	mutex_unlock(&ne_pci_dev->enclaves_list_mutex);

	return rc;
}