1/* 2 * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <autoconf.h> 8 9#include <string.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <utils/util.h> 13 14#include <sel4vm/guest_vm.h> 15#include <sel4vm/boot.h> 16#include <sel4vm/guest_vm_exits.h> 17#include <sel4vm/guest_vm_util.h> 18 19#include "vm_boot.h" 20 21static int curr_vcpu_index = 0; 22 23int vm_init(vm_t *vm, vka_t *vka, simple_t *host_simple, vspace_t host_vspace, 24 ps_io_ops_t *io_ops, seL4_CPtr host_endpoint, const char *name) 25{ 26 int err; 27 bzero(vm, sizeof(vm_t)); 28 /* Initialise vm fields */ 29 vm->vka = vka; 30 vm->simple = host_simple; 31 vm->io_ops = io_ops; 32 vm->mem.vmm_vspace = host_vspace; 33 vm->host_endpoint = host_endpoint; 34 vm->vm_name = strndup(name, strlen(name)); 35 vm->run.exit_reason = VM_GUEST_UNKNOWN_EXIT; 36 /* Initialise ram region */ 37 vm->mem.num_ram_regions = 0; 38 vm->mem.ram_regions = malloc(0); 39 assert(vm->vcpus); 40 /* Initialise vm memory management interface */ 41 err = vm_memory_init(vm); 42 if (err) { 43 ZF_LOGE("Failed to initialise VM memory manager"); 44 return err; 45 } 46 47 /* Initialise vm architecture support */ 48 err = vm_init_arch(vm); 49 if (err) { 50 ZF_LOGE("Failed to initialise VM architecture support"); 51 return err; 52 } 53 54 /* Flag that the vm has been initialised */ 55 vm->vm_initialised = true; 56 return 0; 57} 58 59vm_vcpu_t *vm_create_vcpu(vm_t *vm, int priority) 60{ 61 int err; 62 if (vm->num_vcpus >= CONFIG_MAX_NUM_NODES) { 63 ZF_LOGE("Failed to create vcpu, reached maximum number of support vcpus"); 64 return NULL; 65 } 66 vm_vcpu_t *vcpu_new = calloc(1, sizeof(vm_vcpu_t)); 67 assert(vcpu_new); 68 /* Create VCPU */ 69 err = vka_alloc_vcpu(vm->vka, &vcpu_new->vcpu); 70 assert(!err); 71 /* Initialise vcpu fields */ 72 vcpu_new->vm = vm; 73 vcpu_new->vcpu_id = curr_vcpu_index++; 74 vcpu_new->tcb.priority = priority; 75 vcpu_new->vcpu_online = false; 76 vcpu_new->target_cpu = -1; 77 err = vm_create_vcpu_arch(vm, vcpu_new); 78 assert(!err); 79 vm->vcpus[vm->num_vcpus] = vcpu_new; 80 vm->num_vcpus++; 81 return vcpu_new; 82} 83 84int vm_assign_vcpu_target(vm_vcpu_t *vcpu, int target_cpu) 85{ 86 if (vcpu == NULL) { 87 ZF_LOGE("Failed to assign target cpu - Invalid vcpu"); 88 return -1; 89 } 90 vm_vcpu_t *target_vcpu = vm_vcpu_for_target_cpu(vcpu->vm, target_cpu); 91 if (target_vcpu) { 92 ZF_LOGE("Failed to assign target cpu - A VCPU is already assigned to core %d", target_cpu); 93 return -1; 94 } 95 vcpu->target_cpu = target_cpu; 96 return 0; 97} 98