2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2015, The V3VEE Project <http://www.v3vee.org>
11 * All rights reserved.
13 * Author: Peter Dinda <pdinda@northwestern.edu>
15 * This is free software. You are permitted to use,
16 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
26 #include <palacios/vmm_types.h>
27 #include <palacios/vmm_multiboot.h>
30 enum { ROS_NONE=0, ROS_PAGE_FAULT=1, ROS_SYSCALL=2 } event_type;
31 uint64_t last_ros_event_result; // valid when ROS_NONE
33 struct { // valid when ROS_PAGE_FAULT
36 enum {ROS_READ, ROS_WRITE} action;
38 struct { // valid when ROS_SYSCALL
44 struct v3_ros_signal {
45 // swapped atomically at entry check (xchg)
46 // so only one core does entry
47 // code = 0 => no signal is pending
50 // ROS process context we inject to
51 // if any of these are zero, no injection happens
52 // it must be the case that the ROS is at CPL 3
53 // and in user-mode for injection to occur
61 uint32_t first_hrt_core;
62 uint64_t first_hrt_gpa;
63 struct v3_cfg_file *hrt_file; // image provided via PAL file, if any
64 void *hrt_image; // image provided by ROS, if any
65 uint64_t hrt_image_size; // size of this image
66 uint64_t hrt_entry_addr;
68 enum { HRT_BLOB, HRT_ELF64, HRT_MBOOT2, HRT_MBOOT64 } hrt_type;
70 // The following parallel the content of mb_info_hrt_t in
71 // the extended multiboot header. They reflect how the
72 // HRT has actually been mapped, as opposed to the requested
73 // mapping/flags from the mb_mb64_hrt_t
75 uint64_t max_mem_mapped;
78 uint64_t comm_page_gpa;
79 uint8_t hrt_int_vector;
84 enum {HRT_IDLE=0, HRT_CALL=1, HRT_PARCALL=2, HRT_SYNCSETUP=3, HRT_SYNC=4, HRT_SYNCTEARDOWN=5, HRT_MERGE=6} trans_state;
87 // the ROS event to be handed back
88 struct v3_ros_event ros_event;
90 // user-level interrupt injection state for ROS
91 struct v3_ros_signal ros_signal;
97 uint64_t last_boot_start;
107 int v3_init_hvm_vm(struct v3_vm_info *vm, struct v3_xml *config);
108 int v3_deinit_hvm_vm(struct v3_vm_info *vm);
111 int v3_init_hvm_core(struct guest_info *core);
112 int v3_deinit_hvm_core(struct guest_info *core);
115 uint64_t v3_get_hvm_ros_memsize(struct v3_vm_info *vm);
116 uint64_t v3_get_hvm_hrt_memsize(struct v3_vm_info *vm);
117 int v3_is_hvm_ros_mem_gpa(struct v3_vm_info *vm, addr_t gpa);
118 int v3_is_hvm_hrt_mem_gpa(struct v3_vm_info *vm, addr_t gpa);
120 uint32_t v3_get_hvm_ros_cores(struct v3_vm_info *vm);
121 uint32_t v3_get_hvm_hrt_cores(struct v3_vm_info *vm);
122 int v3_is_hvm_ros_core(struct guest_info *core);
123 int v3_is_hvm_hrt_core(struct guest_info *core);
126 int v3_hvm_should_deliver_ipi(struct guest_info *src, struct guest_info *dest);
127 void v3_hvm_find_apics_seen_by_core(struct guest_info *core, struct v3_vm_info *vm,
128 uint32_t *start_apic, uint32_t *num_apics);
131 int v3_build_hrt_multiboot_tag(struct guest_info *core, mb_info_hrt_t *hrt);
133 int v3_setup_hvm_vm_for_boot(struct v3_vm_info *vm);
134 int v3_setup_hvm_hrt_core_for_boot(struct guest_info *core);
136 // 0 is not a valid code
137 int v3_hvm_signal_ros(struct v3_vm_info *vm, uint64_t code);
139 int v3_handle_hvm_reset(struct guest_info *core);
141 int v3_handle_hvm_entry(struct guest_info *core);
142 int v3_handle_hvm_exit(struct guest_info *core);
145 HVM/HRT interaction is as follows:
147 1. MB_TAG_MB64_HRT tag in the HRT multiboot kernel signifies it
148 is handled by the HVM.
149 2. The flags and other info in the the tag indicate the properties of the HRT
150 to the HVM. (see vmm_multiboot.h), in particular:
151 - position independence
152 - ability to be initially mapped with an offset
153 between virtual and physical addresses, for example
154 to hoist it into the same position that the ROS kernel
155 will occupy in the virtual address space of a ROS
157 - how much physical address space we will intiially map
158 and what kind of page tables are used to map it
159 - what physical page (4KB) should we reserve for use
160 in HVM/HRT communication (particularly upcalls)
161 - the interrupt vector used to upcall from the HVM to the HRT
162 3. The MB_INFO_HRT_TAG within the multiboot info structures the
163 HRT sees on boot indicates that HRT functionality is established and
164 gives details of operation to the HRT, including the following.
165 See vmm_multiboot.c for more info
166 - apics and ioapic ids, and indications of which apics
167 and which entries on ioapics are exclusively for HRT use
168 - physical address range that is exclusively for HRT use
169 - where the the physical address range exclusively for HRT use
170 is mapped into the virtual address space (offset). The
171 ROS part of the physical address space is always identity mapped
173 - the amount of physical memory that has been mapped
174 - the physical address of the page the HVM will use to
175 communicate with the HRT
176 - the interrupt vector the HVM will use to upcall the HRT
177 - flags copied from the HRT's HRT tag (position independence,
178 page table model, offset, etc)
180 hypercall 0xf00d with arguments depending on operation
181 with examples described below. Some requests are only
182 allowed from an HRT core (or ROS core). rax is set to -1
185 (To HRT) interrupt injected by VMM or a magic #PF
186 info via a shared memory page, contents below
187 (To ROS) ROS *app* can set itself up to receive a
188 *user-level* "interrupt" manufactured by the VMM
189 our user library automates this, making it look
190 sort of like a signal handler
194 Type of upcall is determined by the first 64 bits in the commm page
197 0x20 => Invoke function in HRT
198 Next 64 bits contains address of structure
199 describing function call. This is typically the ROS
200 trying to get the HRT to run a function for it.
201 ROS is resposible for assuring that this address
202 (and other addresses) are correct with respect to
203 mappings. That is, for a non-merged address space,
204 the ROS needs to supply physical addresses so that
205 they can be used (with the identity-mapped ROS physical
206 memory.) If it wants to use virtual addresses, it
207 needs to first merge the address spaces.
208 0x21 => Invoke function in HRT in parallel
209 Exactly like previos, but the upcall is happening
210 simultaneously on all HRT cores.
211 0x30 => Merge address space
212 Next 64 bits contains the ROS CR3 that we will use
213 to map the user portion of ROS address space into
214 the HRT address space
215 0x31 => Unmerge address space
216 return the ROS memory mapping to normal (physical/virtual identity)
218 Downcalls from ROS or HRT
220 HVM_HCALL is the general hypercall number used to talk to the HVM
221 The first argument is the request number (below). The other arguments
224 0x0 => Null, just for timing
229 0x8 => Replace HRT image
230 pass in pointer (gva) and length of new image
232 0xf => Get HRT transaction state and current ROS event
233 first argument is pointer to the ROS event state
236 0x10 => ROS event request (HRT->ROS)
237 first argument is pointer where to write the ROS event state
238 0x1f => ROS event completion (ROS->HRT)
239 first argument is the result code
241 0x20 => Invoke function (ROS->HRT)
242 first argument is pointer to structure describing call
243 0x21 => Invoke function in parallel (ROS->HRT)
244 same as above, but simultaneously on all HRT cores
245 0x2f => Function execution complete (HRT->ROS, once per core)
246 0x30 => Merge address space (ROS->HRT)
247 no arguments (CR3 implicit). Merge the current
248 address space in the ROS with the address space on
250 0x31 => Unmerge address apce (ROS->HRT)
251 release any address space merger and restore identity mapping
252 0x3f => Merge request complete (HRT->ROS)
254 0x40 => Install user-mode interrupt/signal handler (ROS)
255 arg1 = handler, arg2 = stack
257 0x41 => Signal ROS handler (HRT->ROS)
258 arg1 = number (must != 0)
262 (Currently all are application/HRT dependent)
268 #endif /* ! __V3VEE__ */