vmm: Moves gpci into guest_thread
[akaros.git] / user / vmm / include / vmm / vmm.h
1 /* Copyright (c) 2015 Google Inc.
2  * Ron Minnich <rminnich@google.com>
3  * See LICENSE for details.
4  *
5  * VMM.h */
6
7 #pragma once
8
9 #include <ros/vmm.h>
10 #include <vmm/sched.h>
11 #include <vmm/linux_bootparam.h>
12 #include <parlib/stdio.h>
13 #include <libelf.h>
14
15 // We need to reserve an area of the low 4G for thinks like tables, APIC, and
16 // so on. So far, 256 MiB has been more than enough, so ...
17 #define MiB 0x100000ull
18 #define MinMemory (16*MiB)
19 #define GiB (0x40000000ULL)
20 #define _4GiB (0x100000000ULL)
21 // BIOS conventions from 1978 make it smart to reserve the low 64k
22 #define LOW64K 65536
23 // The RESERVED area is for all the random junk like devices, ACPI, etc.
24 // We just give it the top 1 GiB of the 32-bit address space, which
25 // nicely translates to one GiB PTE.
26 #define RESERVED 0xC0000000ULL
27 #define RESERVEDSIZE (_4GiB - RESERVED)
28 // Start the VM at 16 MiB, a standard number for 64 bit kernels on amd64
29 #define KERNSTART 0x1000000
30
31 #define VM_PAGE_FAULT                   14
32
33 // APIC Guest Physical Address, a well known constant.
34 #define APIC_GPA                        0xfee00000ULL
35
36 /* The listing of VIRTIO MMIO devices. We currently only expect to have 2,
37  * console and network. Only the console is fully implemented right now.*/
38 enum {
39         VIRTIO_MMIO_CONSOLE_DEV,
40         VIRTIO_MMIO_NETWORK_DEV,
41         VIRTIO_MMIO_BLOCK_DEV,
42
43         /* This should always be the last entry. */
44         VIRTIO_MMIO_MAX_NUM_DEV,
45 };
46
47 /* Structure to encapsulate all of the bookkeeping for a VM. */
48 struct virtual_machine {
49         struct guest_thread                     **gths;
50         unsigned int                            nr_gpcs;
51         /* up_gpcs should not need synchronization. only the BSP should be making
52          * startup vmcalls. For security's sake we might still want to lock in the
53          * future. TODO(ganshun)
54          * up_gpcs refers to the number of guest pcores that have
55          * been started so far. */
56         unsigned int                            up_gpcs;
57         bool                                            vminit;
58
59         /* TODO: put these in appropriate structures.  e.g., virtio things in
60          * something related to virtio.  low4k in something related to the guest's
61          * memory. */
62         uint8_t                                         *low4k;
63         struct virtio_mmio_dev          *virtio_mmio_devices[VIRTIO_MMIO_MAX_NUM_DEV];
64
65         /* minimum and maximum physical memory addresses. When we set up the initial
66          * default page tables we use this range. Note that even if the "physical"
67          * memory has holes, we'll create PTEs for it. This seems enough for now but
68          * we shall see. */
69         uintptr_t                                       minphys;
70         uintptr_t                                       maxphys;
71
72         /* Default root pointer to use if one is not set in a
73          * guest thread. We expect this to be the common case,
74          * where all guests share a page table. It's not required
75          * however. setup_paging now updates this to point to the initial set of
76          * page tables for the guest. */
77         void                                            *root;
78         /* lock to control access to root */
79         uth_mutex_t                                     root_mtx;
80
81         /* Default value for whether guest threads halt on an exit. */
82         bool                                            halt_exit;
83 };
84
85 struct elf_aux {
86         unsigned long v[2];
87 };
88
89 char *regname(uint8_t reg);
90 int decode(struct guest_thread *vm_thread, uint64_t *gpa, uint8_t *destreg,
91            uint64_t **regp, int *store, int *size, int *advance);
92 int io(struct guest_thread *vm_thread);
93 void showstatus(FILE *f, struct guest_thread *vm_thread);
94 int gvatogpa(struct guest_thread *vm_thread, uint64_t va, uint64_t *pa);
95 int rippa(struct guest_thread *vm_thread, uint64_t *pa);
96 int msrio(struct guest_thread *vm_thread, struct vmm_gpcore_init *gpci,
97           uint32_t opcode);
98 int do_ioapic(struct guest_thread *vm_thread, uint64_t gpa,
99               int destreg, uint64_t *regp, int store);
100 bool handle_vmexit(struct guest_thread *gth);
101 int __apic_access(struct guest_thread *vm_thread, uint64_t gpa, int destreg,
102                   uint64_t *regp, int store);
103 int vmm_interrupt_guest(struct virtual_machine *vm, unsigned int gpcoreid,
104                         unsigned int vector);
105 uintptr_t load_elf(char *filename, uint64_t offset, uint64_t *highest,
106                    Elf64_Ehdr *ehdr_out);
107 ssize_t setup_initrd(char *filename, void *membase, size_t memsize);
108
109 /* Lookup helpers */
110
111 static struct virtual_machine *gth_to_vm(struct guest_thread *gth)
112 {
113         return ((struct vmm_thread*)gth)->vm;
114 }
115
116 static struct vm_trapframe *gth_to_vmtf(struct guest_thread *gth)
117 {
118         return &gth->uthread.u_ctx.tf.vm_tf;
119 }
120
121 static struct vmm_gpcore_init *gth_to_gpci(struct guest_thread *gth)
122 {
123         return &gth->gpci;
124 }
125
126 static struct guest_thread *gpcid_to_gth(struct virtual_machine *vm,
127                                          unsigned int gpc_id)
128 {
129         return vm->gths[gpc_id];
130 }
131
132 static struct virtual_machine *get_my_vm(void)
133 {
134         return ((struct vmm_thread*)current_uthread)->vm;
135 }
136
137 /* memory helpers */
138 void *init_e820map(struct virtual_machine *vm, struct boot_params *bp);
139 void checkmemaligned(uintptr_t memstart, size_t memsize);
140 void mmap_memory(struct virtual_machine *vm, uintptr_t memstart,
141                  size_t memsize);
142 bool mmap_file(const char *path, uintptr_t memstart, uintptr_t memsize,
143                uint64_t protections, uint64_t offset);
144 void add_pte_entries(struct virtual_machine *vm, uintptr_t start,
145                      uintptr_t end);
146 void setup_paging(struct virtual_machine *vm);
147 void *setup_biostables(struct virtual_machine *vm,
148                        void *a, void *smbiostable);
149 void *populate_stack(uintptr_t *stack, int argc, char *argv[],
150                          int envc, char *envp[],
151                          int auxc, struct elf_aux auxv[]);