xref: /openbmc/linux/drivers/virt/acrn/vm.c (revision 88f537d5)
19c5137aeSShuo Liu // SPDX-License-Identifier: GPL-2.0
29c5137aeSShuo Liu /*
39c5137aeSShuo Liu  * ACRN_HSM: Virtual Machine management
49c5137aeSShuo Liu  *
59c5137aeSShuo Liu  * Copyright (C) 2020 Intel Corporation. All rights reserved.
69c5137aeSShuo Liu  *
79c5137aeSShuo Liu  * Authors:
89c5137aeSShuo Liu  *	Jason Chen CJ <jason.cj.chen@intel.com>
99c5137aeSShuo Liu  *	Yakui Zhao <yakui.zhao@intel.com>
109c5137aeSShuo Liu  */
119c5137aeSShuo Liu #include <linux/io.h>
129c5137aeSShuo Liu #include <linux/mm.h>
139c5137aeSShuo Liu #include <linux/slab.h>
149c5137aeSShuo Liu 
159c5137aeSShuo Liu #include "acrn_drv.h"
169c5137aeSShuo Liu 
179c5137aeSShuo Liu /* List of VMs */
189c5137aeSShuo Liu static LIST_HEAD(acrn_vm_list);
199c5137aeSShuo Liu /* To protect acrn_vm_list */
209c5137aeSShuo Liu static DEFINE_MUTEX(acrn_vm_list_lock);
219c5137aeSShuo Liu 
229c5137aeSShuo Liu struct acrn_vm *acrn_vm_create(struct acrn_vm *vm,
239c5137aeSShuo Liu 			       struct acrn_vm_creation *vm_param)
249c5137aeSShuo Liu {
259c5137aeSShuo Liu 	int ret;
269c5137aeSShuo Liu 
279c5137aeSShuo Liu 	ret = hcall_create_vm(virt_to_phys(vm_param));
289c5137aeSShuo Liu 	if (ret < 0 || vm_param->vmid == ACRN_INVALID_VMID) {
299c5137aeSShuo Liu 		dev_err(acrn_dev.this_device,
309c5137aeSShuo Liu 			"Failed to create VM! Error: %d\n", ret);
319c5137aeSShuo Liu 		return NULL;
329c5137aeSShuo Liu 	}
339c5137aeSShuo Liu 
34*88f537d5SShuo Liu 	mutex_init(&vm->regions_mapping_lock);
359c5137aeSShuo Liu 	vm->vmid = vm_param->vmid;
369c5137aeSShuo Liu 	vm->vcpu_num = vm_param->vcpu_num;
379c5137aeSShuo Liu 
389c5137aeSShuo Liu 	mutex_lock(&acrn_vm_list_lock);
399c5137aeSShuo Liu 	list_add(&vm->list, &acrn_vm_list);
409c5137aeSShuo Liu 	mutex_unlock(&acrn_vm_list_lock);
419c5137aeSShuo Liu 
429c5137aeSShuo Liu 	dev_dbg(acrn_dev.this_device, "VM %u created.\n", vm->vmid);
439c5137aeSShuo Liu 	return vm;
449c5137aeSShuo Liu }
459c5137aeSShuo Liu 
469c5137aeSShuo Liu int acrn_vm_destroy(struct acrn_vm *vm)
479c5137aeSShuo Liu {
489c5137aeSShuo Liu 	int ret;
499c5137aeSShuo Liu 
509c5137aeSShuo Liu 	if (vm->vmid == ACRN_INVALID_VMID ||
519c5137aeSShuo Liu 	    test_and_set_bit(ACRN_VM_FLAG_DESTROYED, &vm->flags))
529c5137aeSShuo Liu 		return 0;
539c5137aeSShuo Liu 
549c5137aeSShuo Liu 	/* Remove from global VM list */
559c5137aeSShuo Liu 	mutex_lock(&acrn_vm_list_lock);
569c5137aeSShuo Liu 	list_del_init(&vm->list);
579c5137aeSShuo Liu 	mutex_unlock(&acrn_vm_list_lock);
589c5137aeSShuo Liu 
599c5137aeSShuo Liu 	ret = hcall_destroy_vm(vm->vmid);
609c5137aeSShuo Liu 	if (ret < 0) {
619c5137aeSShuo Liu 		dev_err(acrn_dev.this_device,
629c5137aeSShuo Liu 			"Failed to destroy VM %u\n", vm->vmid);
639c5137aeSShuo Liu 		clear_bit(ACRN_VM_FLAG_DESTROYED, &vm->flags);
649c5137aeSShuo Liu 		return ret;
659c5137aeSShuo Liu 	}
66*88f537d5SShuo Liu 
67*88f537d5SShuo Liu 	acrn_vm_all_ram_unmap(vm);
68*88f537d5SShuo Liu 
699c5137aeSShuo Liu 	dev_dbg(acrn_dev.this_device, "VM %u destroyed.\n", vm->vmid);
709c5137aeSShuo Liu 	vm->vmid = ACRN_INVALID_VMID;
719c5137aeSShuo Liu 	return 0;
729c5137aeSShuo Liu }
73