| /* |
| * Copyright 2017, 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 GNU General Public License version 2. Note that NO WARRANTY is provided. |
| * See "LICENSE_GPLv2.txt" for details. |
| * |
| * @TAG(DATA61_GPL) |
| */ |
| |
| /*This file contains structure definitions and function prototype related with VMM.*/ |
| |
| #pragma once |
| |
| #include <sel4/sel4.h> |
| |
| #include <vka/vka.h> |
| #include <simple/simple.h> |
| #include <vspace/vspace.h> |
| #include <allocman/allocman.h> |
| |
| typedef struct vmm vmm_t; |
| typedef struct vmm_vcpu vmm_vcpu_t; |
| |
| #include "vmm/platform/vmexit.h" |
| #include "vmm/driver/pci.h" |
| #include "vmm/io.h" |
| #include "vmm/platform/guest_memory.h" |
| #include "vmm/guest_state.h" |
| #include "vmm/vmexit.h" |
| #include "vmm/mmio.h" |
| #include "vmm/processor/lapic.h" |
| #include "vmm/vmcall.h" |
| #include "vmm/vmm_manager.h" |
| |
| /* ID of the boot vcpu in a vmm */ |
| #define BOOT_VCPU 0 |
| |
| /* System callbacks passed from the user to the library. These need to |
| * be passed in as their definitions are invisible to this library */ |
| typedef struct platform_callbacks { |
| int (*get_interrupt)(); |
| int (*has_interrupt)(); |
| int (*do_async)(seL4_Word badge); |
| seL4_CPtr (*get_async_event_notification)(); |
| } platform_callbacks_t; |
| |
| /* Stores informatoin about the guest image we are loading. This information probably stops |
| * being relevant / useful after we start running. Most of this assumes |
| * we are loading a guest kernel elf image and that we are acting as some kind of bootloader */ |
| typedef struct guest_image { |
| /* Alignment we used when loading the kernel image */ |
| size_t alignment; |
| /* Entry point when the VM starts */ |
| uintptr_t entry; |
| /* Base address (in guest physical) where the image was loaded */ |
| uintptr_t load_paddr; |
| /* Base physical address the image was linked for */ |
| uintptr_t link_paddr; |
| uintptr_t link_vaddr; |
| /* If we are loading a guest elf then we may not have been able to put it where it |
| * requested. This is the relocation offset */ |
| int relocation_offset; |
| /* Guest physical address of where we built its page directory */ |
| uintptr_t pd; |
| /* Guest physical address of where we stashed the kernel cmd line */ |
| uintptr_t cmd_line; |
| size_t cmd_line_len; |
| /* Guest physical address of where we created the boot information */ |
| uintptr_t boot_info; |
| /* Boot module information */ |
| uintptr_t boot_module_paddr; |
| size_t boot_module_size; |
| } guest_image_t; |
| |
| /* Represents a libsel4vmm vcpu */ |
| typedef struct vmm_vcpu { |
| /* kernel objects */ |
| seL4_CPtr guest_vcpu; |
| |
| /* context */ |
| guest_state_t guest_state; |
| |
| /* parent vmm */ |
| vmm_t *vmm; |
| |
| vmm_lapic_t *lapic; |
| int vcpu_id; |
| |
| /* is the vcpu online */ |
| int online; |
| } vmm_vcpu_t; |
| |
| /* Represents a vmm instance that runs a single guest with one or more vcpus */ |
| typedef struct vmm { |
| /* Debugging state for sanity */ |
| int done_host_init; |
| int done_guest_init; |
| /* Allocators, vspaces, and other things for resource management */ |
| vka_t vka; |
| simple_t host_simple; |
| vspace_t host_vspace; |
| /* due ot limitation of the vka interface we still need an explicit allocman */ |
| allocman_t *allocman; |
| |
| /* TCB of the VMM thread |
| * TODO: Should eventually have one vmm thread per vcpu */ |
| seL4_CPtr tcb; |
| seL4_CPtr sc; |
| seL4_CPtr sched_ctrl; |
| |
| /* platform callback functions */ |
| platform_callbacks_t plat_callbacks; |
| |
| /* Default page size to use */ |
| int page_size; |
| |
| /* Memory related */ |
| guest_image_t guest_image; |
| seL4_CPtr guest_pd; |
| guest_memory_t guest_mem; |
| |
| /* Exit handling table */ |
| vmexit_handler_ptr vmexit_handlers[VMM_EXIT_REASON_NUM]; |
| /* PCI emulation state */ |
| vmm_pci_space_t pci; |
| |
| /* IO port management */ |
| vmm_io_port_list_t io_port; |
| |
| /* MMIO management. Should probably be per-vcpu, e.g. we can't handle the |
| * guest trying to remap a local APIC */ |
| vmm_mmio_list_t mmio_list; |
| |
| unsigned int num_vcpus; |
| vmm_vcpu_t *vcpus; |
| |
| vmcall_handler_t *vmcall_handlers; |
| unsigned int vmcall_num_handlers; |
| |
| /*TODO add |
| map of vcpu affinities |
| */ |
| } vmm_t; |
| |
| /* Finalize the VM before running it */ |
| int vmm_finalize(vmm_t *vmm); |
| |
| /*running vmm moudle*/ |
| void vmm_run(vmm_t *vmm); |
| |
| /* TODO htf did these get here? lets refactor everything */ |
| void vmm_sync_guest_state(vmm_vcpu_t *vcpu); |
| void vmm_sync_guest_context(vmm_vcpu_t *vcpu); |
| void vmm_reply_vm_exit(vmm_vcpu_t *vcpu); |
| |
| /* mint a badged copy of the vmm's async event notification cap */ |
| seL4_CPtr vmm_create_async_event_notification_cap(vmm_t *vmm, seL4_Word badge); |
| |