Commit 9c5137ae authored by Shuo Liu's avatar Shuo Liu Committed by Greg Kroah-Hartman
Browse files

virt: acrn: Introduce VM management interfaces



The VM management interfaces expose several VM operations to ACRN
userspace via ioctls. For example, creating VM, starting VM, destroying
VM and so on.

The ACRN Hypervisor needs to exchange data with the ACRN userspace
during the VM operations. HSM provides VM operation ioctls to the ACRN
userspace and communicates with the ACRN Hypervisor for VM operations
via hypercalls.

HSM maintains a list of User VM. Each User VM will be bound to an
existing file descriptor of /dev/acrn_hsm. The User VM will be
destroyed when the file descriptor is closed.

Cc: Zhi Wang <zhi.a.wang@intel.com>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
Cc: Yu Wang <yu1.wang@intel.com>
Cc: Reinette Chatre <reinette.chatre@intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: default avatarZhi Wang <zhi.a.wang@intel.com>
Reviewed-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarShuo Liu <shuo.a.liu@intel.com>
Link: https://lore.kernel.org/r/20210207031040.49576-7-shuo.a.liu@intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 666834c4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -320,6 +320,7 @@ Code Seq# Include File Comments
0xA0  all    linux/sdp/sdp.h                                         Industrial Device Project
                                                                     <mailto:kenji@bitgate.com>
0xA1  0      linux/vtpm_proxy.h                                      TPM Emulator Proxy Driver
0xA2  all    uapi/linux/acrn.h                                       ACRN hypervisor
0xA3  80-8F                                                          Port ACL  in development:
                                                                     <mailto:tlewis@mindspring.com>
0xA3  90-9F  linux/dtlk.h
+1 −0
Original line number Diff line number Diff line
@@ -443,6 +443,7 @@ S: Supported
W:	https://projectacrn.org
F:	Documentation/virt/acrn/
F:	drivers/virt/acrn/
F:	include/uapi/linux/acrn.h
AD1889 ALSA SOUND DRIVER
L:	linux-parisc@vger.kernel.org
+1 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_ACRN_HSM)	:= acrn.o
acrn-y := hsm.o
acrn-y := hsm.o vm.o
+20 −1
Original line number Diff line number Diff line
@@ -3,16 +3,35 @@
#ifndef __ACRN_HSM_DRV_H
#define __ACRN_HSM_DRV_H

#include <linux/acrn.h>
#include <linux/dev_printk.h>
#include <linux/miscdevice.h>
#include <linux/types.h>

#include "hypercall.h"

extern struct miscdevice acrn_dev;

#define ACRN_INVALID_VMID (0xffffU)

#define ACRN_VM_FLAG_DESTROYED		0U
/**
 * struct acrn_vm - Properties of ACRN User VM.
 * @list:	Entry within global list of all VMs
 * @vmid:	User VM ID
 * @vcpu_num:	Number of virtual CPUs in the VM
 * @flags:	Flags (ACRN_VM_FLAG_*) of the VM. This is VM flag management
 *		in HSM which is different from the &acrn_vm_creation.vm_flag.
 */
struct acrn_vm {
	struct list_head	list;
	u16			vmid;
	int			vcpu_num;
	unsigned long		flags;
};

struct acrn_vm *acrn_vm_create(struct acrn_vm *vm,
			       struct acrn_vm_creation *vm_param);
int acrn_vm_destroy(struct acrn_vm *vm);

#endif /* __ACRN_HSM_DRV_H */
+74 −2
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
 *	Yakui Zhao <yakui.zhao@intel.com>
 */

#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -38,10 +37,82 @@ static int acrn_dev_open(struct inode *inode, struct file *filp)
	return 0;
}

/*
 * HSM relies on hypercall layer of the ACRN hypervisor to do the
 * sanity check against the input parameters.
 */
static long acrn_dev_ioctl(struct file *filp, unsigned int cmd,
			   unsigned long ioctl_param)
{
	struct acrn_vm *vm = filp->private_data;
	struct acrn_vm_creation *vm_param;
	int ret = 0;

	if (vm->vmid == ACRN_INVALID_VMID && cmd != ACRN_IOCTL_CREATE_VM) {
		dev_dbg(acrn_dev.this_device,
			"ioctl 0x%x: Invalid VM state!\n", cmd);
		return -EINVAL;
	}

	switch (cmd) {
	case ACRN_IOCTL_CREATE_VM:
		vm_param = memdup_user((void __user *)ioctl_param,
				       sizeof(struct acrn_vm_creation));
		if (IS_ERR(vm_param))
			return PTR_ERR(vm_param);

		if ((vm_param->reserved0 | vm_param->reserved1) != 0)
			return -EINVAL;

		vm = acrn_vm_create(vm, vm_param);
		if (!vm) {
			ret = -EINVAL;
			kfree(vm_param);
			break;
		}

		if (copy_to_user((void __user *)ioctl_param, vm_param,
				 sizeof(struct acrn_vm_creation))) {
			acrn_vm_destroy(vm);
			ret = -EFAULT;
		}

		kfree(vm_param);
		break;
	case ACRN_IOCTL_START_VM:
		ret = hcall_start_vm(vm->vmid);
		if (ret < 0)
			dev_dbg(acrn_dev.this_device,
				"Failed to start VM %u!\n", vm->vmid);
		break;
	case ACRN_IOCTL_PAUSE_VM:
		ret = hcall_pause_vm(vm->vmid);
		if (ret < 0)
			dev_dbg(acrn_dev.this_device,
				"Failed to pause VM %u!\n", vm->vmid);
		break;
	case ACRN_IOCTL_RESET_VM:
		ret = hcall_reset_vm(vm->vmid);
		if (ret < 0)
			dev_dbg(acrn_dev.this_device,
				"Failed to restart VM %u!\n", vm->vmid);
		break;
	case ACRN_IOCTL_DESTROY_VM:
		ret = acrn_vm_destroy(vm);
		break;
	default:
		dev_dbg(acrn_dev.this_device, "Unknown IOCTL 0x%x!\n", cmd);
		ret = -ENOTTY;
	}

	return ret;
}

static int acrn_dev_release(struct inode *inode, struct file *filp)
{
	struct acrn_vm *vm = filp->private_data;

	acrn_vm_destroy(vm);
	kfree(vm);
	return 0;
}
@@ -50,9 +121,10 @@ static const struct file_operations acrn_fops = {
	.owner		= THIS_MODULE,
	.open		= acrn_dev_open,
	.release	= acrn_dev_release,
	.unlocked_ioctl = acrn_dev_ioctl,
};

static struct miscdevice acrn_dev = {
struct miscdevice acrn_dev = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name	= "acrn_hsm",
	.fops	= &acrn_fops,
Loading