blob: bf6e2f13eb7acb1d14737d66e44acebf24c60e75 [file] [log] [blame] [edit]
/*
* 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)
*/
#pragma once
#include <sel4/sel4.h>
#include <vka/vka.h>
#include <simple/simple.h>
#include <vspace/vspace.h>
#include <platsupport/io.h>
#include <sel4vm/arch/guest_vm_arch.h>
#include <sel4vm/guest_memory.h>
typedef struct vm vm_t;
typedef struct vm_vcpu vm_vcpu_t;
typedef struct vm_mem vm_mem_t;
typedef struct vm_ram_region vm_ram_region_t;
typedef struct vm_run vm_run_t;
typedef struct vm_arch vm_arch_t;
/***
* @module guest_vm.h
* The guest vm interface is central to libsel4vm, providing definitions of the guest vm datastructure and
* primitives to run the VM instance and start its vcpus.
*/
/**
* Type signature of unhandled memory fault function, invoked when a memory fault is unable to be handled
* @param {vm_t *} vm A handle to the VM
* @param {vm_vcpu_t *} vcpu A handle to the fault vcpu
* @param {uintptr_t} paddr Faulting guest physical address
* @param {size_t} len Length of faulted access
* @param {void *} cookie User cookie to pass onto callback
* @return Fault handling status code: HANDLED, UNHANDLED, RESTART, ERROR
*/
typedef memory_fault_result_t (*unhandled_mem_fault_callback_fn)(vm_t *vm, vm_vcpu_t *vcpu, uintptr_t paddr,
size_t len, void *cookie);
/**
* Type signature of unhandled notification callback, invoked when a notification is recieved and cannot be processed
* by the vm runtime
* @param {vm_t *} vm A handle to the VM
* @param {seL4_Word} badge Badge of inbound event
* @param {seL4_MessageInfo_t} tag seL4 Message Info tag of inbound event (if IPC related)
* @param {void *} cookie User cookie to pass onto callback
* @return -1 on failure otherwise 0 for success
*/
typedef int (*notification_callback_fn)(vm_t *vm, seL4_Word badge, seL4_MessageInfo_t tag,
void *cookie);
/***
* @struct vm_ram_region
* Structure representing individual RAM region. A VM can have multiple regions to represent its total RAM
* @param {uintptr_t} start Guest physical start address of region
* @param {size_t} size Size of region in bytes
* @param {int} allocated Whether or not this region has been 'allocated'
*/
struct vm_ram_region {
uintptr_t start;
size_t size;
int allocated;
};
/***
* @struct vm_mem
* Structure representing VM memory managment
* @param {vspace_t} vm_vspace Guest VM's vspace
* @param {vka_object_t} vm_vspace_root VKA allocated guest VM root vspace
* @param {vspace_t} vmm_vspace Hosts/VMMs vspace
* @param {int} num_ram_regions Total number of registered `vm_ram_regions`
* @param {struct vm_ram_region *} Set of registered `vm_ram_regions`
* @param {vm_memory_reservation_cookie_t *} Initialised instance of vm memory interface
* @param {unhandled_mem_fault_callback_fn} unhandled_mem_fault_handler Registered callback for unhandled memory faults
* @param {void *} unhandled_mem_fault_cookie User data passed onto unhandled mem fault callback
*/
struct vm_mem {
/* Guest vm vspace management */
vspace_t vm_vspace;
/* Guest vm root vspace */
vka_object_t vm_vspace_root;
/* vmm vspace */
vspace_t vmm_vspace;
/* Guest vm ram regions */
/* We maintain all pieces of ram as a sorted list of regions.
* This is memory that we will specifically give the guest as actual RAM */
int num_ram_regions;
struct vm_ram_region *ram_regions;
/* Memory reservations */
vm_memory_reservation_cookie_t *reservation_cookie;
unhandled_mem_fault_callback_fn unhandled_mem_fault_handler;
void *unhandled_mem_fault_cookie;
};
/***
* @struct vm_tcb
* Structure used for TCB management within a VCPU
* @param {vka_object_t} tcb VKA allocated TCB object
* @param {vka_object_t} sc VKA allocated scheduling context
* @param {int} priority VCPU scheduling priority
*/
struct vm_tcb {
/* Guest vm tcb management objects */
vka_object_t tcb;
vka_object_t sc;
vka_object_t sched_ctrl;
/* vcpu scheduling priority */
int priority;
};
/***
* @struct vm_vcpu
* Structure used to represent a VCPU
* @param {struct vm *} vm Parent VM
* @param {vka_object_t} vcpu VKA allocated vcpu object
* @param {struct vm_tcb} tcb VCPUs TCB management structure
* @param {unsigned int} vcpu_id VCPU Identifier
* @param {int} target_cpu The target core the vcpu is assigned to
* @param {bool} vcpu_online Flag representing if the vcpu has been started
* @param {struct vm_vcpu_arch} vcpu_arch Architecture specific vcpu properties
*/
struct vm_vcpu {
/* Parent vm */
struct vm *vm;
/* Kernel vcpu object */
vka_object_t vcpu;
/* vm tcb */
struct vm_tcb tcb;
/* Id of vcpu */
unsigned int vcpu_id;
/* The target core the vcpu is assigned to */
int target_cpu;
/* is the vcpu online */
bool vcpu_online;
/* Architecture specfic vcpu */
struct vm_vcpu_arch vcpu_arch;
};
/***
* @struct vm_run
* VM Runtime management structure
* @param {int} exit_reason Records last vm exit reason
* @param {notification_callback_fn} notification_callback Callback for processing unhandled notifications
* @param {void *} notification_callback_cookie A cookie to supply to the notification callback
*/
struct vm_run {
int exit_reason;
notification_callback_fn notification_callback;
void *notification_callback_cookie;
};
/***
* @struct vm_cspace
* VM cspace management structure
* @param {vka_object_t} cspace_obj VKA allocated cspace object
* @param {seL4_Word} cspace_root_data cspace root data capability
*/
struct vm_cspace {
vka_object_t cspace_obj;
seL4_Word cspace_root_data;
};
/***
* @struct vm
* Structure representing a VM instance
* @param {struct vm_arch} arch Architecture specfic vm structure
* @param {unsigned int} num_vcpus Number of vcpus created for the VM
* @param {struct vm_vcpu*} vcpus vcpu's belonging to the VM
* @param {struct vm_mem} mem Memory management structure
* @param {struct vm_run} run VM Runtime management structure
* @param {struct vm_cspace} cspace VM CSpace management structure
* @param {seL4_CPtr} host_endpoint Host/VMM endpoint. `vm_run` waits on this enpoint
* @param {vka_t *} vka Handle to virtual kernel allocator for seL4 kernel object allocation
* @param {ps_io_ops_t *} io_ops Handle to platforms io ops
* @param {simple_t *} simple Handle to hosts simple environment
* @param {char *} vm_name String used to describe VM. Useful for debugging
* @param {unsigned int} vm_id Identifier for VM. Useful for debugging
* @param {bool} vm_initialised Boolean flagging whether VM is intialised or not
*/
struct vm {
/* Architecture specfic vm structure */
struct vm_arch arch;
/* vm vcpus */
unsigned int num_vcpus;
struct vm_vcpu *vcpus[CONFIG_MAX_NUM_NODES];
/* vm memory management */
struct vm_mem mem;
/* vm runtime management */
struct vm_run run;
/* Guest vm cspace */
struct vm_cspace cspace;
/* Host endoint (i.e. vmm) to wait for VM faults and host events */
seL4_CPtr host_endpoint;
/* Support & Resource Managements */
vka_t *vka;
ps_io_ops_t *io_ops;
simple_t *simple;
/* Debugging & Identification */
char *vm_name;
unsigned int vm_id;
bool vm_initialised;
};
/***
* @function vm_run(vm_t *vm)
* Enter the VM event runtime loop.
* This funtion is a blocking call, returning on the event of an unhandled VM exit or error
* @param {vm_t *} vm A handle to the VM to run
* @return 0 on success, -1 on error
*/
int vm_run(vm_t *vm);
/***
* @function vcpu_start(vcpu)
* Start an initialised vcpu thread
* @param {vm_vcpu_t *} vcpu A handle to vcpu to start
* @return 0 on success, -1 on error
*/
int vcpu_start(vm_vcpu_t *vcpu);
/* Unhandled fault callback registration functions */
/***
* @function vm_register_unhandled_mem_fault_callback(vm, fault_handler, cookie)
* Register a callback for processing unhandled memory faults (memory regions not previously registered or reserved)
* @param {vm_t *} vm A handle to the VM
* @param {unhandled_mem_fault_callback_fn} fault_handler A user supplied callback to process unhandled memory faults
* @param {void *} cookie A cookie to supply to the memory fault handler
* @return 0 on success, -1 on error
*/
int vm_register_unhandled_mem_fault_callback(vm_t *vm, unhandled_mem_fault_callback_fn fault_handler,
void *cookie);
/***
* @function vm_register_notification_callback(vm, notification_callback, cookie)
* Register a callback for processing unhandled notifications (events unknown to libsel4vm)
* @param {vm_t *} vm A handle to the VM
* @param {notification_callback_fn} notification_callback A user supplied callback to process unhandled notifications
* @param {void *} cookie A cookie to supply to the callback
* @return 0 on success, -1 on error
*/
int vm_register_notification_callback(vm_t *vm, notification_callback_fn notification_callback,
void *cookie);