Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


HVM Enhancements + Bug Fixes
[palacios.git] / palacios / include / palacios / vmm_hvm.h
1 /*
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.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2015, The V3VEE Project <http://www.v3vee.org> 
11  * All rights reserved.
12  *
13  * Author: Peter Dinda <pdinda@northwestern.edu>
14  *
15  * This is free software.  You are permitted to use,
16  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
17  */
18
19
20 #ifndef __VMM_HVM_H
21 #define __VMM_HVM_H
22
23
24 #ifdef __V3VEE__ 
25
26 #include <palacios/vmm_types.h>
27 #include <palacios/vmm_multiboot.h>
28
29 struct v3_ros_event {
30     enum { ROS_NONE=0, ROS_PAGE_FAULT=1, ROS_SYSCALL=2, HRT_EXCEPTION=3, HRT_THREAD_EXIT=4, ROS_DONE=5} event_type;
31     uint64_t       last_ros_event_result; // valid when ROS_NONE
32     union {
33         struct {   // valid when ROS_PAGE_FAULT
34             uint64_t rip;
35             uint64_t cr2;
36             enum {ROS_READ, ROS_WRITE} action;
37         } page_fault;
38         struct { // valid when ROS_SYSCALL
39             uint64_t args[8];
40         } syscall;
41         struct { // valid when HRT_EXCEPTION
42             uint64_t rip;
43             uint64_t vector;
44         } excp;
45         struct { // valid when HRT_THREAD_EXIT
46             uint64_t nktid;
47         } thread_exit;
48     };
49 };
50
51 struct v3_ros_signal { 
52     // swapped atomically at entry check (xchg)
53     // so only one core does entry
54     // code = 0 => no signal is pending
55     uint64_t code;
56
57     // ROS process context we inject to
58     // if any of these are zero, no injection happens
59     // it must be the case that the ROS is at CPL 3
60     // and in user-mode for injection to occur
61     uint64_t cr3;
62     uint64_t handler;
63     uint64_t stack;
64 };
65
66 struct v3_vm_hvm {
67     // used to serialize hypercalls across cores (hopefully temporary)
68     v3_lock_t hypercall_lock; 
69
70     uint8_t   is_hvm;
71     uint32_t  first_hrt_core;
72     uint64_t  first_hrt_gpa;
73     struct v3_cfg_file *hrt_file;  // image provided via PAL file, if any
74     void      *hrt_image;          // image provided by ROS, if any
75     uint64_t  hrt_image_size;      //   size of this image
76     uint64_t  hrt_entry_addr;
77
78     enum { HRT_BLOB, HRT_ELF64, HRT_MBOOT2, HRT_MBOOT64 } hrt_type;
79
80     // The following parallel the content of mb_info_hrt_t in
81     // the extended multiboot header.   They reflect how the 
82     // HRT has actually been mapped, as opposed to the requested
83     // mapping/flags from the mb_mb64_hrt_t
84     uint64_t  hrt_flags; 
85     uint64_t  max_mem_mapped;
86     uint64_t  gva_offset;
87     uint64_t  gva_entry;
88     uint64_t  comm_page_gpa;
89     uint8_t   hrt_int_vector;
90
91     void     *comm_page_hpa;
92     void     *comm_page_hva;
93
94     enum {HRT_IDLE=0, HRT_CALL=1, HRT_PARCALL=2, HRT_SYNCSETUP=3, HRT_SYNC=4, HRT_SYNCTEARDOWN=5, HRT_MERGE=6, HRT_GDTSYNC=7} trans_state;
95     uint64_t  trans_count;
96
97     // the ROS event to be handed back
98     struct v3_ros_event ros_event;
99
100     // user-level interrupt injection state for ROS
101     struct v3_ros_signal ros_signal;
102
103     uint64_t hrt_gdt_gva;
104     uint64_t ros_fsbase;
105 };
106
107 struct v3_core_hvm {
108     uint8_t   is_hrt;
109     uint64_t  last_boot_start;
110 };
111
112
113
114 struct v3_xml;
115
116 int v3_init_hvm();
117 int v3_deinit_hvm();
118
119 int v3_init_hvm_vm(struct v3_vm_info *vm, struct v3_xml *config);
120 int v3_deinit_hvm_vm(struct v3_vm_info *vm);
121
122
123 int v3_init_hvm_core(struct guest_info *core);
124 int v3_deinit_hvm_core(struct guest_info *core);
125
126
127 uint64_t v3_get_hvm_ros_memsize(struct v3_vm_info *vm);
128 uint64_t v3_get_hvm_hrt_memsize(struct v3_vm_info *vm);
129 int      v3_is_hvm_ros_mem_gpa(struct v3_vm_info *vm, addr_t gpa);
130 int      v3_is_hvm_hrt_mem_gpa(struct v3_vm_info *vm, addr_t gpa);
131
132 uint32_t v3_get_hvm_ros_cores(struct v3_vm_info *vm);
133 uint32_t v3_get_hvm_hrt_cores(struct v3_vm_info *vm);
134 int      v3_is_hvm_ros_core(struct guest_info *core);
135 int      v3_is_hvm_hrt_core(struct guest_info *core);
136
137
138 int      v3_hvm_should_deliver_ipi(struct guest_info *src, struct guest_info *dest);
139 void     v3_hvm_find_apics_seen_by_core(struct guest_info *core, struct v3_vm_info *vm, 
140                                         uint32_t *start_apic, uint32_t *num_apics);
141
142
143 int v3_build_hrt_multiboot_tag(struct guest_info *core, mb_info_hrt_t *hrt);
144
145 int v3_setup_hvm_vm_for_boot(struct v3_vm_info *vm);
146 int v3_setup_hvm_hrt_core_for_boot(struct guest_info *core);
147
148 // 0 is not a valid code
149 int v3_hvm_signal_ros(struct v3_vm_info *vm, uint64_t code);
150
151 int v3_handle_hvm_reset(struct guest_info *core);
152
153 int v3_handle_hvm_entry(struct guest_info *core);
154 int v3_handle_hvm_exit(struct guest_info *core);
155
156 /*
157   HVM/HRT interaction is as follows:
158
159   1. MB_TAG_MB64_HRT tag in the HRT multiboot kernel signifies it
160      is handled by the HVM.
161   2. The flags and other info in the the tag indicate the properties of the HRT
162      to the HVM.  (see vmm_multiboot.h), in particular:
163          - position independence
164          - ability to be initially mapped with an offset
165            between virtual and physical addresses, for example  
166            to hoist it into the same position that the ROS kernel
167            will occupy in the virtual address space of a ROS
168            process
169          - how much physical address space we will intiially map
170            and what kind of page tables are used to map it
171          - what physical page (4KB) should we reserve for use
172            in HVM/HRT communication (particularly upcalls)
173          - the interrupt vector used to upcall from the HVM to the HRT
174   3. The MB_INFO_HRT_TAG within the multiboot info structures the
175      HRT sees on boot indicates that HRT functionality is established and
176      gives details of operation to the HRT, including the following.
177      See vmm_multiboot.c for more info
178          - apics and ioapic ids, and indications of which apics
179            and which entries on ioapics are exclusively for HRT use
180          - physical address range that is exclusively for HRT use
181          - where the the physical address range exclusively for HRT use 
182            is mapped into the virtual address space (offset).  The
183            ROS part of the physical address space is always identity mapped 
184            initially.
185          - the amount of physical memory that has been mapped
186          - the physical address of the page the HVM will use to 
187            communicate with the HRT
188          - the interrupt vector the HVM will use to upcall the HRT
189          - flags copied from the HRT's HRT tag (position independence, 
190            page table model, offset, etc)
191   4. Downcalls:
192          hypercall 0xf00d with arguments depending on operation
193          with examples described below.  Some requests are only
194          allowed from an HRT core (or ROS core).   rax is set to -1
195          on error.
196   5. Upcalls
197          (To HRT) interrupt injected by VMM or a magic #PF
198                   info via a shared memory page, contents below
199          (To ROS) ROS *app* can set itself up to receive a 
200                   *user-level* "interrupt" manufactured by the VMM
201                   our user library automates this, making it look
202                   sort of like a signal handler
203
204   Upcalls to HRT
205
206    Type of upcall is determined by the first 64 bits in the commm page
207
208    0x0  =>  Null (test)
209    0x20 =>  Invoke function in HRT 
210             Next 64 bits contains address of structure
211             describing function call.   This is typically the ROS
212             trying to get the HRT to run a function for it. 
213             ROS is resposible for assuring that this address
214             (and other addresses) are correct with respect to
215             mappings.   That is, for a non-merged address space,
216             the ROS needs to supply physical addresses so that
217             they can be used (with the identity-mapped ROS physical
218             memory.)  If it wants to use virtual addresses, it
219             needs to first merge the address spaces. 
220    0x21 =>  Invoke function in HRT in parallel
221             Exactly like previos, but the upcall is happening 
222             simultaneously on all HRT cores. 
223    0x30 =>  Merge address space
224             Next 64 bits contains the ROS CR3 that we will use
225             to map the user portion of ROS address space into
226             the HRT address space
227    0x31 =>  Unmerge address space
228             return the ROS memory mapping to normal (physical/virtual identity)
229
230   Downcalls from ROS or HRT
231
232    HVM_HCALL is the general hypercall number used to talk to the HVM
233      The first argument is the request number (below).   The other arguments
234      depend on the first.
235
236    0x0  =>  Null, just for timing
237    0x1  =>  Reboot ROS
238    0x2  =>  Reboot HRT
239    0x3  =>  Reboot Both
240
241    0x8  =>  Replace HRT image
242             pass in pointer (gva) and length of new image
243
244    0xf  =>  Get HRT transaction state and current ROS event
245             first argument is pointer to the ROS event state 
246             to be filled out
247
248    0x10 =>  ROS event request (HRT->ROS)
249             first argument is pointer where to write the ROS event state
250
251    0x1e =>  HRT event ack (HRT->ROS) 
252             the HRT has read the result of the previous event
253
254    0x1f =>  ROS event completion (ROS->HRT)
255             first argument is the result code
256
257    0x20 =>  Invoke function (ROS->HRT)
258             first argument is pointer to structure describing call
259    0x21 =>  Invoke function in parallel (ROS->HRT)
260             same as above, but simultaneously on all HRT cores
261
262    0x28 =>  Set up for synchronous operation (ROS->HRT)
263    0x29 =>  Tear down synchronous operation (ROS->HRT)
264
265    0x2f =>  Function execution complete (HRT->ROS, once per core)
266
267    0x30 =>  Merge address space (ROS->HRT)
268             no arguments (CR3 implicit).   Merge the current
269             address space in the ROS with the address space on 
270             the HRT
271    0x31 =>  Unmerge address apce (ROS->HRT)
272             release any address space merger and restore identity mapping
273    0x3f =>  Merge request complete (HRT->ROS)
274
275    0x40 =>  Install user-mode interrupt/signal handler (ROS)
276             arg1 = handler, arg2 = stack
277
278    0x41 =>  Signal ROS handler (HRT->ROS)
279             arg1 = number (must != 0)
280
281    0x51 =>  Synchronize GDT (ROS->HRT)
282             ROS updates HRT's GDT area with its own 
283             and then informs HRT
284    
285    0x52 =>  Register HRT GDT area to support GDT synchronization (HRT only)
286   
287    0x53 =>  Restore GDT (ROS->HRT)
288
289    0x5f =>  GDT Synchronization done (HRT->ROS)
290
291    Upcalls to ROS
292    
293    (Currently all are application/HRT dependent)
294
295 */     
296      
297
298
299 #endif /* ! __V3VEE__ */
300
301
302 #endif