Skip to content

Commit

Permalink
wip vmm_context_t
Browse files Browse the repository at this point in the history
  • Loading branch information
Axel Heider committed Mar 31, 2023
1 parent 2e373d2 commit 23dd2b8
Showing 1 changed file with 113 additions and 60 deletions.
173 changes: 113 additions & 60 deletions components/VM_Arm/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,30 @@ int NUM_VCPUS = 1;
#define seL4_DebugHalt() do{ printf("Halting...\n"); while(1); } while(0)
#endif

vka_t _vka;
simple_t _simple;
vspace_t _vspace;
sel4utils_alloc_data_t _alloc_data;
allocman_t *allocman;
seL4_CPtr _fault_endpoint;
irq_server_t *_irq_server;
typedef struct _vmm_context_t vmm_context_t;

typedef struct {
vmm_context_t *vmm;
vm_config_t const *config;
vm_t *vm;
} vm_context_t;

struct _vmm_context_t {
vka_t vka;
simple_t simple;
vspace_t vspace;
sel4utils_alloc_data_t alloc_data;
allocman_t *allocman;
seL4_CPtr fault_endpoint;
irq_server_t *irq_server;

struct ps_io_ops io_ops;
vm_t vm;

vm_context_t vm_context;
};

vmm_context_t my_vmm_context;

vmm_pci_space_t *pci;
vmm_io_port_list_t *io_ports;
Expand All @@ -104,8 +121,6 @@ reboot_hooks_list_t reboot_hooks_list;
static char gen_dtb_buf[DTB_BUFFER_SIZE];
static char gen_dtb_base_buf[DTB_BUFFER_SIZE];

struct ps_io_ops _io_ops;

static jmp_buf restart_jmp_buf;

void camkes_make_simple(simple_t *simple);
Expand All @@ -131,15 +146,16 @@ int get_crossvm_irq_num(void)

static int _dma_morecore(size_t min_size, int cached, struct dma_mem_descriptor *dma_desc)
{
vmm_context_t *vmm_context = &my_vmm_context;

static uint32_t _vaddr = DMA_VSTART;
struct seL4_ARM_Page_GetAddress getaddr_ret;
seL4_CPtr frame;
seL4_CPtr pd;
vka_t *vka;
vka_t *vka = &(vmm_context->vka);
int err;

pd = simple_get_pd(&_simple);
vka = &_vka;
pd = simple_get_pd(&vmm_context->simple);

/* Create a frame */
frame = vka_alloc_frame_leaky(vka, seL4_PageBits);
Expand Down Expand Up @@ -342,8 +358,10 @@ static int vm_new_io_mapper(simple_t simple, vspace_t vspace, vka_t vka, ps_io_m

static seL4_Error vm_simple_get_irq(void *data, int irq, seL4_CNode cnode, seL4_Word index, uint8_t depth)
{
vmm_context_t *vmm_context = &my_vmm_context;

seL4_Error res;
res = original_simple_get_irq_fn(_simple.data, irq, cnode, index, depth);
res = original_simple_get_irq_fn(vmm_context->simple.data, irq, cnode, index, depth);
if (res == seL4_NoError) {
return res;
}
Expand All @@ -362,11 +380,14 @@ static vka_utspace_alloc_at_fn utspace_alloc_at_copy;
static int camkes_vm_utspace_alloc_maybe_device_fn(void *data, const cspacepath_t *dest, seL4_Word type,
seL4_Word size_bits, bool can_use_dev, seL4_Word *res)
{
vmm_context_t *vmm_context = &my_vmm_context;
vka_t *vka = &(vmm_context->vka);

if (type == seL4_TCBObject) {
seL4_CPtr cap = camkes_alloc(type, 0, 0);
if (cap != seL4_CapNull) {
cspacepath_t src;
vka_cspace_make_path(&_vka, cap, &src);
vka_cspace_make_path(vka, cap, &src);
return vka_cnode_copy(dest, &src, seL4_AllRights);
}
}
Expand All @@ -376,13 +397,16 @@ static int camkes_vm_utspace_alloc_maybe_device_fn(void *data, const cspacepath_
static int camkes_vm_utspace_alloc_at(void *data, const cspacepath_t *dest, seL4_Word type,
seL4_Word size_bits, uintptr_t paddr, seL4_Word *res)
{
vmm_context_t *vmm_context = &my_vmm_context;
vka_t *vka = &(vmm_context->vka);

if (type == seL4_ARM_SmallPageObject) {
for (dataport_frame_t *frame = __start__dataport_frames;
frame < __stop__dataport_frames; frame++) {
if (frame->paddr == paddr) {
if (frame->size == BIT(size_bits)) {
cspacepath_t src;
vka_cspace_make_path(&_vka, frame->cap, &src);
vka_cspace_make_path(vka, frame->cap, &src);
return vka_cnode_copy(dest, &src, seL4_AllRights);
} else {
ZF_LOGF("ERROR: found mapping for %p, wrong size %zu, expected %zu", (void *) paddr, frame->size, BIT(size_bits));
Expand All @@ -395,18 +419,21 @@ static int camkes_vm_utspace_alloc_at(void *data, const cspacepath_t *dest, seL4

}

static int vmm_init(const vm_config_t *vm_config)
static int vmm_init(vmm_context_t *vmm_context)
{
vka_object_t fault_ep_obj;
vka_t *vka;
simple_t *simple;
vspace_t *vspace;
int err;
allocman_t *allocman;
irq_server_t *irq_server;

vm_context_t *vm_context = &(vmm_context->vm_context);
vm_config_t const *vm_config = vm_context->config;

vka = &_vka;
vspace = &_vspace;
simple = &_simple;
fault_ep_obj.cptr = 0;
vka_t *vka = &(vmm_context->vka);
simple_t *simple = &(vmm_context->simple);

vka_object_t fault_ep_obj = {
.cptr = 0,
};

/* Camkes adds nothing to our address space, so this array is empty */
void *existing_frames[] = {
Expand All @@ -428,6 +455,7 @@ static int vmm_init(const vm_config_t *vm_config)
get_allocator_mempool_size(), get_allocator_mempool()
);
assert(allocman);
vmm_context->allocman = allocman;

allocman_make_vka(vka, allocman);

Expand Down Expand Up @@ -471,38 +499,41 @@ static int vmm_init(const vm_config_t *vm_config)
}
}
/* Initialize the vspace */
err = sel4utils_bootstrap_vspace(vspace, &_alloc_data,
simple_get_init_cap(simple, seL4_CapInitThreadPD), vka, NULL, NULL, existing_frames);
err = sel4utils_bootstrap_vspace(&(vmm_context->vspace),
&(vmm_context->alloc_data),
simple_get_init_cap(simple, seL4_CapInitThreadPD),
vka, NULL, NULL, existing_frames);
assert(!err);

/* Initialise device support */
err = vm_new_io_mapper(*simple, *vspace, *vka,
&_io_ops.io_mapper);
err = vm_new_io_mapper(*simple, vmm_context->vspace, *vka,
&(vmm_context->io_ops.io_mapper));
assert(!err);

/* Initialise MUX subsystem for platforms that need it */
#ifdef CONFIG_PLAT_EXYNOS5410
err = mux_sys_init(&_io_ops, NULL, &_io_ops.mux_sys);
err = mux_sys_init(&(vmm_context->io_ops), NULL, &(vmm_context->io_ops.mux_sys));
assert(!err);
#endif

/* Initialise DMA */
err = dma_dmaman_init(&_dma_morecore, NULL, &_io_ops.dma_manager);
err = dma_dmaman_init(&_dma_morecore, NULL, &(vmm_context->io_ops.dma_manager));
assert(!err);

/* Allocate an endpoint for listening to events */
err = vka_alloc_endpoint(vka, &fault_ep_obj);
assert(!err);
_fault_endpoint = fault_ep_obj.cptr;
vmm_context->fault_endpoint = fault_ep_obj.cptr;

err = sel4platsupport_new_malloc_ops(&_io_ops.malloc_ops);
err = sel4platsupport_new_malloc_ops(&vmm_context->io_ops.malloc_ops);
assert(!err);

/* Create an IRQ server */
_irq_server = irq_server_new(vspace, vka, IRQSERVER_PRIO,
simple, simple_get_cnode(simple), fault_ep_obj.cptr,
IRQ_MESSAGE_LABEL, 256, &_io_ops.malloc_ops);
assert(_irq_server);
irq_server = irq_server_new(&(vmm_context->vspace), vka, IRQSERVER_PRIO,
simple, simple_get_cnode(simple), fault_ep_obj.cptr,
IRQ_MESSAGE_LABEL, 256, &vmm_context->io_ops.malloc_ops);
assert(irq_server);
vmm_context->irq_server = irq_server;

int num_pt_irqs = ARRAY_SIZE(linux_pt_irqs);

Expand All @@ -517,7 +548,7 @@ static int vmm_init(const vm_config_t *vm_config)

for (int i = 0; i < num_irq_threads; i++) {
/* Create new IRQ server threads and have them allocate notifications for us */
thread_id_t t_id = irq_server_thread_new(_irq_server, seL4_CapNull,
thread_id_t t_id = irq_server_thread_new(irq_server, seL4_CapNull,
0, -1);
assert(t_id >= 0);
}
Expand Down Expand Up @@ -627,10 +658,12 @@ static USED SECTION("_vmm_module") struct {} dummy_module;
extern vmm_module_t __start__vmm_module[];
extern vmm_module_t __stop__vmm_module[];

static int install_vm_devices(vm_t *vm)
static int install_vm_devices(vm_context_t *vm_context)
{
int err;

vm_t *vm = vm_context->vm;

/* Install virtual devices */
if (config_set(CONFIG_VM_PCI_SUPPORT)) {
err = vm_install_vpci(vm, io_ports, pci);
Expand Down Expand Up @@ -824,16 +857,19 @@ static int load_generated_dtb(vm_t *vm, uintptr_t paddr, void *addr, size_t size
return 0;
}

static int load_vm(vm_t *vm, const vm_config_t *vm_config)
static int load_vm(vm_context_t *vm_context)
{
vm_t *vm = vm_context->vm;
vm_config_t const *vm_config = vm_context->config;

seL4_Word entry;
seL4_Word dtb;
int err;

vm->mem.map_one_to_one = vm_config->map_one_to_one; /* Map memory 1:1 if configured to do so */

/* Install devices */
err = install_vm_devices(vm);
err = install_vm_devices(vm_context);
if (err) {
printf("Error: Failed to install VM devices\n");
return -1;
Expand Down Expand Up @@ -894,8 +930,10 @@ static int load_vm(vm_t *vm, const vm_config_t *vm_config)
}
fdt_ori = (void *)gen_dtb_base_buf;
} else {
camkes_io_fdt(&(_io_ops.io_fdt));
fdt_ori = (void *)ps_io_fdt_get(&_io_ops.io_fdt);
vmm_context_t *vmm_context = vm_context->vmm;
ps_io_fdt_t *io_fdt = &(vmm_context->io_ops.io_fdt);
camkes_io_fdt(io_fdt);
fdt_ori = (void *)io_fdt;
}

err = generate_fdt(vm, vm_config, fdt_ori, gen_fdt, size_gen,
Expand Down Expand Up @@ -965,10 +1003,13 @@ int register_async_event_handler(seL4_Word badge, async_event_handler_fn_t callb

static int handle_async_event(vm_t *vm, seL4_Word badge, seL4_MessageInfo_t tag, void *cookie)
{
vm_context_t *vm_context = (vm_context_t *)cookie;

seL4_Word label = seL4_MessageInfo_get_label(tag);
if (badge == 0) {
if (label == IRQ_MESSAGE_LABEL) {
irq_server_handle_irq_ipc(_irq_server, tag);

irq_server_handle_irq_ipc(vm_context->vmm->irq_server, tag);
} else {
ZF_LOGE("Unknown label (%"SEL4_PRId_word")", label);
}
Expand Down Expand Up @@ -1089,14 +1130,18 @@ memory_fault_result_t unhandled_mem_fault_callback(vm_t *vm, vm_vcpu_t *vcpu,
return FAULT_ERROR;
}

static int main_continued(void)
static int main_continued(vmm_context_t *vmm_context)
{
vm_t vm;
int err;

vm_context_t *vm_context = &(vmm_context->vm_context);
vm_context->config = &vm_config;
vm_context->vm = &(vmm_context->vm);
vm_t *vm = vm_context->vm;

/* setup for restart with a setjmp */
while (setjmp(restart_jmp_buf) != 0) {
err = vmm_process_reboot_callbacks(&vm, &reboot_hooks_list);
err = vmm_process_reboot_callbacks(vm, &reboot_hooks_list);
if (err) {
ZF_LOGF("vm_process_reboot_callbacks failed: %d", err);
}
Expand All @@ -1123,26 +1168,32 @@ static int main_continued(void)
return err;
}

err = vmm_init(&vm_config);
err = vmm_init(vmm_context);
assert(!err);

/* Create the VM */
err = vm_init(&vm, &_vka, &_simple, _vspace, &_io_ops, _fault_endpoint, get_instance_name());
err = vm_init(vm,
&(vmm_context->vka),
&(vmm_context->simple),
vmm_context->vspace,
&(vmm_context->io_ops),
vmm_context->fault_endpoint,
get_instance_name());
assert(!err);
err = vm_register_unhandled_mem_fault_callback(&vm, unhandled_mem_fault_callback, NULL);
err = vm_register_unhandled_mem_fault_callback(vm, unhandled_mem_fault_callback, NULL);
assert(!err);
err = vm_register_notification_callback(&vm, handle_async_event, NULL);
err = vm_register_notification_callback(vm, handle_async_event, vm_context);
assert(!err);
#ifdef CONFIG_TK1_SMMU
/* install any iospaces */
int iospace_caps;
err = simple_get_iospace_cap_count(&_simple, &iospace_caps);
err = simple_get_iospace_cap_count(&(vmm_context->simple), &iospace_caps);
if (err) {
ZF_LOGF("Failed to get iospace count");
}
for (int i = 0; i < iospace_caps; i++) {
seL4_CPtr iospace = simple_get_nth_iospace_cap(&_simple, i);
err = vm_guest_add_iospace(&vm, &_vspace, iospace);
err = vm_guest_add_iospace(vm, &(vmm_context->vspace), iospace);
if (err) {
ZF_LOGF("Failed to add iospace");
}
Expand All @@ -1155,35 +1206,35 @@ static int main_continued(void)
seL4_CPtr sid_cap = camkes_get_smmu_sid_cap();

ZF_LOGD("Assigning vspace to context bank");
err = seL4_ARM_CB_AssignVspace(cb_cap, vspace_get_root(&vm.mem.vm_vspace));
err = seL4_ARM_CB_AssignVspace(cb_cap, vspace_get_root(&vm->mem.vm_vspace));
ZF_LOGF_IF(err, "Failed to assign vspace to CB");

ZF_LOGD("Binding stream id to context bank");
err = seL4_ARM_SID_BindCB(sid_cap, cb_cap);
ZF_LOGF_IF(err, "Failed to bind CB to SID");
#endif /* CONFIG_ARM_SMMU */

err = vm_create_default_irq_controller(&vm);
err = vm_create_default_irq_controller(vm);
assert(!err);

for (int i = 0; i < NUM_VCPUS; i++) {
vm_vcpu_t *new_vcpu = create_vmm_plat_vcpu(&vm, VM_PRIO - 1);
vm_vcpu_t *new_vcpu = create_vmm_plat_vcpu(vm, VM_PRIO - 1);
assert(new_vcpu);
}
vm_vcpu_t *vm_vcpu = vm.vcpus[BOOT_VCPU];
vm_vcpu_t *vm_vcpu = vm->vcpus[BOOT_VCPU];
err = vm_assign_vcpu_target(vm_vcpu, 0);
if (err) {
return -1;
}

/* Route IRQs */
err = route_irqs(vm_vcpu, _irq_server);
err = route_irqs(vm_vcpu, vmm_context->irq_server);
if (err) {
return -1;
}

/* Load system images */
err = load_vm(&vm, &vm_config);
err = load_vm(vm_context);
if (err) {
printf("Failed to load VM image\n");
seL4_DebugHalt();
Expand All @@ -1197,7 +1248,7 @@ static int main_continued(void)
}

while (1) {
err = vm_run(&vm);
err = vm_run(vm);
if (err) {
ZF_LOGE("Failed to run VM");
seL4_DebugHalt();
Expand Down Expand Up @@ -1231,5 +1282,7 @@ int run(void)
}
}

return main_continued();
vmm_context_t *vmm_context = &my_vmm_context;

return main_continued(vmm_context);
}

0 comments on commit 23dd2b8

Please sign in to comment.