xref: /openbmc/linux/drivers/virt/acrn/vm.c (revision 9c5137ae)
1*9c5137aeSShuo Liu // SPDX-License-Identifier: GPL-2.0
2*9c5137aeSShuo Liu /*
3*9c5137aeSShuo Liu  * ACRN_HSM: Virtual Machine management
4*9c5137aeSShuo Liu  *
5*9c5137aeSShuo Liu  * Copyright (C) 2020 Intel Corporation. All rights reserved.
6*9c5137aeSShuo Liu  *
7*9c5137aeSShuo Liu  * Authors:
8*9c5137aeSShuo Liu  *	Jason Chen CJ <jason.cj.chen@intel.com>
9*9c5137aeSShuo Liu  *	Yakui Zhao <yakui.zhao@intel.com>
10*9c5137aeSShuo Liu  */
11*9c5137aeSShuo Liu #include <linux/io.h>
12*9c5137aeSShuo Liu #include <linux/mm.h>
13*9c5137aeSShuo Liu #include <linux/slab.h>
14*9c5137aeSShuo Liu 
15*9c5137aeSShuo Liu #include "acrn_drv.h"
16*9c5137aeSShuo Liu 
17*9c5137aeSShuo Liu /* List of VMs */
18*9c5137aeSShuo Liu static LIST_HEAD(acrn_vm_list);
19*9c5137aeSShuo Liu /* To protect acrn_vm_list */
20*9c5137aeSShuo Liu static DEFINE_MUTEX(acrn_vm_list_lock);
21*9c5137aeSShuo Liu 
22*9c5137aeSShuo Liu struct acrn_vm *acrn_vm_create(struct acrn_vm *vm,
23*9c5137aeSShuo Liu 			       struct acrn_vm_creation *vm_param)
24*9c5137aeSShuo Liu {
25*9c5137aeSShuo Liu 	int ret;
26*9c5137aeSShuo Liu 
27*9c5137aeSShuo Liu 	ret = hcall_create_vm(virt_to_phys(vm_param));
28*9c5137aeSShuo Liu 	if (ret < 0 || vm_param->vmid == ACRN_INVALID_VMID) {
29*9c5137aeSShuo Liu 		dev_err(acrn_dev.this_device,
30*9c5137aeSShuo Liu 			"Failed to create VM! Error: %d\n", ret);
31*9c5137aeSShuo Liu 		return NULL;
32*9c5137aeSShuo Liu 	}
33*9c5137aeSShuo Liu 
34*9c5137aeSShuo Liu 	vm->vmid = vm_param->vmid;
35*9c5137aeSShuo Liu 	vm->vcpu_num = vm_param->vcpu_num;
36*9c5137aeSShuo Liu 
37*9c5137aeSShuo Liu 	mutex_lock(&acrn_vm_list_lock);
38*9c5137aeSShuo Liu 	list_add(&vm->list, &acrn_vm_list);
39*9c5137aeSShuo Liu 	mutex_unlock(&acrn_vm_list_lock);
40*9c5137aeSShuo Liu 
41*9c5137aeSShuo Liu 	dev_dbg(acrn_dev.this_device, "VM %u created.\n", vm->vmid);
42*9c5137aeSShuo Liu 	return vm;
43*9c5137aeSShuo Liu }
44*9c5137aeSShuo Liu 
45*9c5137aeSShuo Liu int acrn_vm_destroy(struct acrn_vm *vm)
46*9c5137aeSShuo Liu {
47*9c5137aeSShuo Liu 	int ret;
48*9c5137aeSShuo Liu 
49*9c5137aeSShuo Liu 	if (vm->vmid == ACRN_INVALID_VMID ||
50*9c5137aeSShuo Liu 	    test_and_set_bit(ACRN_VM_FLAG_DESTROYED, &vm->flags))
51*9c5137aeSShuo Liu 		return 0;
52*9c5137aeSShuo Liu 
53*9c5137aeSShuo Liu 	/* Remove from global VM list */
54*9c5137aeSShuo Liu 	mutex_lock(&acrn_vm_list_lock);
55*9c5137aeSShuo Liu 	list_del_init(&vm->list);
56*9c5137aeSShuo Liu 	mutex_unlock(&acrn_vm_list_lock);
57*9c5137aeSShuo Liu 
58*9c5137aeSShuo Liu 	ret = hcall_destroy_vm(vm->vmid);
59*9c5137aeSShuo Liu 	if (ret < 0) {
60*9c5137aeSShuo Liu 		dev_err(acrn_dev.this_device,
61*9c5137aeSShuo Liu 			"Failed to destroy VM %u\n", vm->vmid);
62*9c5137aeSShuo Liu 		clear_bit(ACRN_VM_FLAG_DESTROYED, &vm->flags);
63*9c5137aeSShuo Liu 		return ret;
64*9c5137aeSShuo Liu 	}
65*9c5137aeSShuo Liu 	dev_dbg(acrn_dev.this_device, "VM %u destroyed.\n", vm->vmid);
66*9c5137aeSShuo Liu 	vm->vmid = ACRN_INVALID_VMID;
67*9c5137aeSShuo Liu 	return 0;
68*9c5137aeSShuo Liu }
69