blob: 84648348e9138070eecee957de72b3079070c064 [file] [log] [blame]
/*
* Copyright 2019, Data61
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
* ABN 41 687 119 230.
*
* This software may be distributed and modified according to the terms of
* the BSD 2-Clause license. Note that NO WARRANTY is provided.
* See "LICENSE_BSD2.txt" for details.
*
* @TAG(DATA61_BSD)
*/
#include <autoconf.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <utils/util.h>
#include <sel4vm/guest_vm.h>
#include <sel4vm/boot.h>
#include <sel4vm/guest_vm_exits.h>
#include <sel4vm/guest_vm_util.h>
#include "vm_boot.h"
static int curr_vcpu_index = 0;
int vm_init(vm_t *vm, vka_t *vka, simple_t *host_simple, vspace_t host_vspace,
ps_io_ops_t *io_ops, seL4_CPtr host_endpoint, const char *name)
{
int err;
bzero(vm, sizeof(vm_t));
/* Initialise vm fields */
vm->vka = vka;
vm->simple = host_simple;
vm->io_ops = io_ops;
vm->mem.vmm_vspace = host_vspace;
vm->host_endpoint = host_endpoint;
vm->vm_name = strndup(name, strlen(name));
vm->run.exit_reason = VM_GUEST_UNKNOWN_EXIT;
/* Initialise ram region */
vm->mem.num_ram_regions = 0;
vm->mem.ram_regions = malloc(0);
assert(vm->vcpus);
/* Initialise vm memory management interface */
err = vm_memory_init(vm);
if (err) {
ZF_LOGE("Failed to initialise VM memory manager");
return err;
}
/* Initialise vm architecture support */
err = vm_init_arch(vm);
if (err) {
ZF_LOGE("Failed to initialise VM architecture support");
return err;
}
/* Flag that the vm has been initialised */
vm->vm_initialised = true;
return 0;
}
vm_vcpu_t *vm_create_vcpu(vm_t *vm, int priority)
{
int err;
if (vm->num_vcpus >= CONFIG_MAX_NUM_NODES) {
ZF_LOGE("Failed to create vcpu, reached maximum number of support vcpus");
return NULL;
}
vm_vcpu_t *vcpu_new = calloc(1, sizeof(vm_vcpu_t));
assert(vcpu_new);
/* Create VCPU */
err = vka_alloc_vcpu(vm->vka, &vcpu_new->vcpu);
assert(!err);
/* Initialise vcpu fields */
vcpu_new->vm = vm;
vcpu_new->vcpu_id = curr_vcpu_index++;
vcpu_new->tcb.priority = priority;
vcpu_new->vcpu_online = false;
vcpu_new->target_cpu = -1;
err = vm_create_vcpu_arch(vm, vcpu_new);
assert(!err);
vm->vcpus[vm->num_vcpus] = vcpu_new;
vm->num_vcpus++;
return vcpu_new;
}
int vm_assign_vcpu_target(vm_vcpu_t *vcpu, int target_cpu)
{
if (vcpu == NULL) {
ZF_LOGE("Failed to assign target cpu - Invalid vcpu");
return -1;
}
vm_vcpu_t *target_vcpu = vm_vcpu_for_target_cpu(vcpu->vm, target_cpu);
if (target_vcpu) {
ZF_LOGE("Failed to assign target cpu - A VCPU is already assigned to core %d", target_cpu);
return -1;
}
vcpu->target_cpu = target_cpu;
return 0;
}