コード例 #1
0
ファイル: vmci_host.c プロジェクト: avagin/linux
int __init vmci_host_init(void)
{
	int error;

	host_context = vmci_ctx_create(VMCI_HOST_CONTEXT_ID,
					VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS,
					-1, VMCI_VERSION, NULL);
	if (IS_ERR(host_context)) {
		error = PTR_ERR(host_context);
		pr_warn("Failed to initialize VMCIContext (error%d)\n",
			error);
		return error;
	}

	error = misc_register(&vmci_host_miscdev);
	if (error) {
		pr_warn("Module registration error (name=%s, major=%d, minor=%d, err=%d)\n",
			vmci_host_miscdev.name,
			MISC_MAJOR, vmci_host_miscdev.minor,
			error);
		pr_warn("Unable to initialize host personality\n");
		vmci_ctx_destroy(host_context);
		return error;
	}

	pr_info("VMCI host device registered (name=%s, major=%d, minor=%d)\n",
		vmci_host_miscdev.name, MISC_MAJOR, vmci_host_miscdev.minor);

	vmci_host_device_initialized = true;
	return 0;
}
コード例 #2
0
ファイル: vmci_host.c プロジェクト: avagin/linux
void __exit vmci_host_exit(void)
{
	vmci_host_device_initialized = false;

	misc_deregister(&vmci_host_miscdev);
	vmci_ctx_destroy(host_context);
	vmci_qp_broker_exit();

	pr_debug("VMCI host driver module unloaded\n");
}
コード例 #3
0
void __exit vmci_host_exit(void)
{
	int error;

	vmci_host_device_initialized = false;

	error = misc_deregister(&vmci_host_miscdev);
	if (error)
		pr_warn("Error unregistering character device: %d\n", error);

	vmci_ctx_destroy(host_context);
	vmci_qp_broker_exit();

	pr_debug("VMCI host driver module unloaded\n");
}
コード例 #4
0
ファイル: vmci_host.c プロジェクト: avagin/linux
/*
 * Called on close of /dev/vmci, most often when the process
 * exits.
 */
static int vmci_host_close(struct inode *inode, struct file *filp)
{
	struct vmci_host_dev *vmci_host_dev = filp->private_data;

	if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) {
		vmci_ctx_destroy(vmci_host_dev->context);
		vmci_host_dev->context = NULL;

		/*
		 * The number of active contexts is used to track whether any
		 * VMX'en are using the host personality. It is incremented when
		 * a context is created through the IOCTL_VMCI_INIT_CONTEXT
		 * ioctl.
		 */
		atomic_dec(&vmci_host_active_users);
	}
	vmci_host_dev->ct_type = VMCIOBJ_NOT_SET;

	kfree(vmci_host_dev);
	filp->private_data = NULL;
	return 0;
}
コード例 #5
0
ファイル: vmci_host.c プロジェクト: avagin/linux
static int vmci_host_do_init_context(struct vmci_host_dev *vmci_host_dev,
				     const char *ioctl_name,
				     void __user *uptr)
{
	struct vmci_init_blk init_block;
	const struct cred *cred;
	int retval;

	if (copy_from_user(&init_block, uptr, sizeof(init_block))) {
		vmci_ioctl_err("error reading init block\n");
		return -EFAULT;
	}

	mutex_lock(&vmci_host_dev->lock);

	if (vmci_host_dev->ct_type != VMCIOBJ_NOT_SET) {
		vmci_ioctl_err("received VMCI init on initialized handle\n");
		retval = -EINVAL;
		goto out;
	}

	if (init_block.flags & ~VMCI_PRIVILEGE_FLAG_RESTRICTED) {
		vmci_ioctl_err("unsupported VMCI restriction flag\n");
		retval = -EINVAL;
		goto out;
	}

	cred = get_current_cred();
	vmci_host_dev->context = vmci_ctx_create(init_block.cid,
						 init_block.flags, 0,
						 vmci_host_dev->user_version,
						 cred);
	put_cred(cred);
	if (IS_ERR(vmci_host_dev->context)) {
		retval = PTR_ERR(vmci_host_dev->context);
		vmci_ioctl_err("error initializing context\n");
		goto out;
	}

	/*
	 * Copy cid to userlevel, we do this to allow the VMX
	 * to enforce its policy on cid generation.
	 */
	init_block.cid = vmci_ctx_get_id(vmci_host_dev->context);
	if (copy_to_user(uptr, &init_block, sizeof(init_block))) {
		vmci_ctx_destroy(vmci_host_dev->context);
		vmci_host_dev->context = NULL;
		vmci_ioctl_err("error writing init block\n");
		retval = -EFAULT;
		goto out;
	}

	vmci_host_dev->ct_type = VMCIOBJ_CONTEXT;
	atomic_inc(&vmci_host_active_users);

	retval = 0;

out:
	mutex_unlock(&vmci_host_dev->lock);
	return retval;
}