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