Skip to content

Commit f08e0c9

Browse files
committed
[guest,host,common] brought back in-process driver
(1) had to add helper impl functions for the HyperlightPEB struct to get the host addresses for some memory regions. (2) re-added some logic for the LeakedOutBWrapper and for the InProcessDriver. (3) added an in process test in the sandbox_builder file. (4) renamed hyperlight_common::hyperlight_peb mod to hyperlight_common::peb. Signed-off-by: danbugs <[email protected]>
1 parent 1fe6ac4 commit f08e0c9

File tree

15 files changed

+329
-115
lines changed

15 files changed

+329
-115
lines changed

Diff for: src/hyperlight_common/src/lib.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub const PAGE_SIZE: usize = 0x1_000; // 4KB
2525
extern crate alloc;
2626
extern crate core;
2727

28-
use crate::hyperlight_peb::{HyperlightPEB, RunMode};
28+
use crate::peb::{HyperlightPEB, RunMode};
2929

3030
pub mod flatbuffer_wrappers;
3131
/// cbindgen:ignore
@@ -44,7 +44,7 @@ mod flatbuffers;
4444
/// the two will communicate. For example, in the PEB, you can set the address for the
4545
/// input and output data regions—these regions are imperative for the host and guest to
4646
/// be able to communicate via function calls.
47-
pub mod hyperlight_peb;
47+
pub mod peb;
4848

4949
/// We keep track of the PEB address in a global variable that references a region of
5050
/// shared memory.
@@ -54,6 +54,14 @@ pub static mut PEB: *mut HyperlightPEB = core::ptr::null_mut();
5454
/// state in this global variable.
5555
pub static mut RUNNING_MODE: RunMode = RunMode::None;
5656

57+
/// For in-process mode, we can't call the `outb` instruction directly because it is a privileged
58+
/// instruction. Instead, we use a function pointer to call an `outb_handler` function.
59+
/// For in-process mode, we can't call the `outb` instruction directly because it is a privileged
60+
/// instruction. Instead, we use a function pointer to call an `outb_handler` function.
61+
pub static mut OUTB_HANDLER: Option<extern "C" fn(u16, u8)> = None;
62+
63+
pub static mut OUTB_HANDLER_CTX: Option<extern "C" fn(*mut core::ffi::c_void, u16, u8)> = None;
64+
5765
/// Hyperlight operates with a host-guest execution model.
5866
///
5967
/// The host is who creates the hypervisor partition, and the guest is whatever runs

Diff for: src/hyperlight_common/src/outb.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use core::arch;
22

33
use anyhow::{bail, Result};
44

5-
use crate::hyperlight_peb::RunMode;
6-
use crate::RUNNING_MODE;
5+
use crate::peb::RunMode;
6+
use crate::{OUTB_HANDLER_CTX, PEB, RUNNING_MODE};
77

88
/// Supported actions when issuing an OUTB actions by Hyperlight.
99
/// - Log: for logging,
@@ -44,16 +44,13 @@ pub fn outb(port: u16, value: u8) {
4444
hloutb(port, value);
4545
}
4646
RunMode::InProcessLinux | RunMode::InProcessWindows => {
47-
// TODO(danbugs:297): bring back
48-
// if let Some(outb_func) = OUTB_PTR_WITH_CONTEXT {
49-
// if let Some(peb_ptr) = PEB {
50-
// outb_func((*peb_ptr).pOutbContext, port, value);
51-
// }
52-
// } else if let Some(outb_func) = OUTB_PTR {
53-
// outb_func(port, value);
54-
// } else {
55-
// panic!("Tried to call outb without hypervisor and without outb function ptrs");
56-
// }
47+
if let Some(outb_func) = OUTB_HANDLER_CTX {
48+
outb_func((*PEB).outb_ptr_ctx as *mut core::ffi::c_void, port, value);
49+
} else if let Some(outb_func) = OUTB_PTR {
50+
outb_func(port, value);
51+
} else {
52+
panic!("Tried to call outb without hypervisor and without outb function ptrs");
53+
}
5754
}
5855
_ => {
5956
panic!("Tried to call outb in invalid runmode");

Diff for: src/hyperlight_common/src/hyperlight_peb.rs renamed to src/hyperlight_common/src/peb.rs

+158-23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::PAGE_SIZE;
1+
use crate::{PAGE_SIZE, RUNNING_MODE};
22

33
/// Hyperlight supports 2 primary modes:
44
/// 1. Hypervisor mode
@@ -34,8 +34,12 @@ pub struct HyperlightPEB {
3434
/// Hyperlight, but with no hypervisor isolation. When we
3535
/// run in-process, we can't rely on the usual mechanism for
3636
/// host function calls (i.e., `outb`). Instead, we call a
37-
/// function directly, which is represented by this pointer.
37+
/// function directly, which is represented by these pointers.
3838
pub outb_ptr: u64,
39+
pub outb_ptr_ctx: u64,
40+
41+
/// The host base address for the custom guest memory region.
42+
pub guest_memory_host_base_address: u64,
3943

4044
/// The base address for the guest memory region.
4145
pub guest_memory_base_address: u64,
@@ -52,43 +56,43 @@ pub struct HyperlightPEB {
5256

5357
/// Guest error data can be used to pass guest error information
5458
/// between host and the guest.
55-
pub guest_error_data_ptr: u64,
59+
pub guest_error_data_offset: u64,
5660
pub guest_error_data_size: u64,
5761

5862
/// Host error data can be used to pass host error information
5963
/// between the host and the guest.
60-
pub host_error_data_ptr: u64,
64+
pub host_error_data_offset: u64,
6165
pub host_error_data_size: u64,
6266

6367
/// The input data pointer is used to pass data from
6468
/// the host to the guest.
65-
pub input_data_ptr: u64,
69+
pub input_data_offset: u64,
6670
pub input_data_size: u64,
6771

6872
/// The output data pointer is used to pass data from
6973
/// the guest to the host.
70-
pub output_data_ptr: u64,
74+
pub output_data_offset: u64,
7175
pub output_data_size: u64,
7276

7377
/// The guest panic context pointer can be used to pass
7478
/// panic context data from the guest to the host.
75-
pub guest_panic_context_ptr: u64,
79+
pub guest_panic_context_offset: u64,
7680
pub guest_panic_context_size: u64,
7781

7882
/// The guest heap data pointer points to a region of
7983
/// memory in the guest that is used for heap allocations.
80-
pub guest_heap_data_ptr: u64,
84+
pub guest_heap_data_offset: u64,
8185
pub guest_heap_data_size: u64,
8286

8387
/// The guest stack data pointer points to a region of
8488
/// memory in the guest that is used for stack allocations.
85-
pub guest_stack_data_ptr: u64,
89+
pub guest_stack_data_offset: u64,
8690
pub guest_stack_data_size: u64,
8791

8892
// Host function details may be used in the guest before
8993
// issuing a host function call to validate it before
9094
// ensuing a `VMEXIT`.
91-
pub host_function_details_ptr: u64,
95+
pub host_function_details_offset: u64,
9296
pub host_function_details_size: u64,
9397
}
9498

@@ -97,8 +101,8 @@ impl HyperlightPEB {
97101
// we set the guest stack at the start of the guest memory region to leverage
98102
// the stack guard page before it
99103
self.set_guest_stack_data_region(
100-
self.guest_memory_base_address, // start at base of custom guest memory region,
101-
None, // don't override the stack size
104+
0x0, // start at base of custom guest memory region,
105+
None, // don't override the stack size
102106
);
103107

104108
let guest_stack_size = self.get_guest_stack_data_size();
@@ -143,31 +147,31 @@ impl HyperlightPEB {
143147

144148
// Sets the guest error data region, where the guest can write errors to.
145149
pub fn set_guest_error_data_region(&mut self, ptr: u64, size: u64) {
146-
self.guest_error_data_ptr = self.guest_memory_base_address + ptr;
150+
self.guest_error_data_offset = ptr;
147151
self.guest_error_data_size = size;
148152
}
149153

150154
// Sets the host error data region, where the host can write errors to.
151155
pub fn set_host_error_data_region(&mut self, ptr: u64, size: u64) {
152-
self.host_error_data_ptr = self.guest_memory_base_address + ptr;
156+
self.host_error_data_offset = ptr;
153157
self.host_error_data_size = size;
154158
}
155159

156160
// Sets the input data region, where the host can write things like function calls to.
157161
pub fn set_input_data_region(&mut self, ptr: u64, size: u64) {
158-
self.input_data_ptr = self.guest_memory_base_address + ptr;
162+
self.input_data_offset = ptr;
159163
self.input_data_size = size;
160164
}
161165

162166
// Sets the output data region, where the guest can write things like function return values to.
163167
pub fn set_output_data_region(&mut self, ptr: u64, size: u64) {
164-
self.output_data_ptr = self.guest_memory_base_address + ptr;
168+
self.output_data_offset = ptr;
165169
self.output_data_size = size;
166170
}
167171

168172
// Sets the guest panic context region, where the guest can write panic context data to.
169173
pub fn set_guest_panic_context_region(&mut self, ptr: u64, size: u64) {
170-
self.guest_panic_context_ptr = self.guest_memory_base_address + ptr;
174+
self.guest_panic_context_offset = ptr;
171175
self.guest_panic_context_size = size;
172176
}
173177

@@ -184,7 +188,7 @@ impl HyperlightPEB {
184188

185189
// Sets the guest heap data region.
186190
pub fn set_guest_heap_data_region(&mut self, ptr: u64, size_override: Option<u64>) {
187-
self.guest_heap_data_ptr = self.guest_memory_base_address + ptr;
191+
self.guest_heap_data_offset = ptr;
188192
// the Hyperlight host always sets the heap data size to a default value, the
189193
// guest has the option to override it.
190194
if let Some(size) = size_override {
@@ -211,7 +215,7 @@ impl HyperlightPEB {
211215

212216
// Sets the guest stack data region.
213217
pub fn set_guest_stack_data_region(&mut self, ptr: u64, size_override: Option<u64>) {
214-
self.guest_stack_data_ptr = self.guest_memory_base_address + ptr;
218+
self.guest_stack_data_offset = ptr;
215219

216220
// the Hyperlight host always sets the stack data size to a default value, the
217221
// guest has the option to override it.
@@ -228,17 +232,148 @@ impl HyperlightPEB {
228232

229233
// Sets the host function details region, where the guest can write host function details to.
230234
pub fn set_host_function_details_region(&mut self, ptr: u64, size: u64) {
231-
self.host_function_details_ptr = self.guest_memory_base_address + ptr;
235+
self.host_function_details_offset = ptr;
232236
self.host_function_details_size = size;
233237
}
234238

235-
// Gets the input data region, where the host can write things like function calls to.
239+
// Gets the input data guest region, where the host can write things like function calls to.
240+
pub fn get_input_data_guest_region(&self) -> (u64, u64) {
241+
(
242+
self.input_data_offset + self.guest_memory_base_address,
243+
self.input_data_size,
244+
)
245+
}
246+
247+
// Gets input data host region.
248+
pub fn get_input_data_host_region(&self) -> (u64, u64) {
249+
(
250+
self.input_data_offset + self.guest_memory_host_base_address,
251+
self.input_data_size,
252+
)
253+
}
254+
255+
// Gets input data region.
236256
pub fn get_input_data_region(&self) -> (u64, u64) {
237-
(self.input_data_ptr, self.input_data_size)
257+
unsafe {
258+
match RUNNING_MODE {
259+
RunMode::Hypervisor => self.get_input_data_guest_region(),
260+
RunMode::InProcessWindows | RunMode::InProcessLinux => {
261+
self.get_input_data_host_region()
262+
}
263+
_ => panic!("Invalid running mode"),
264+
}
265+
}
238266
}
239267

240268
// Gets the output data region, where the guest can write things like function return values to.
269+
pub fn get_output_data_guest_region(&self) -> (u64, u64) {
270+
(
271+
self.output_data_offset + self.guest_memory_base_address,
272+
self.output_data_size,
273+
)
274+
}
275+
276+
// Gets output data host region.
277+
pub fn get_output_data_host_region(&self) -> (u64, u64) {
278+
(
279+
self.output_data_offset + self.guest_memory_host_base_address,
280+
self.output_data_size,
281+
)
282+
}
283+
284+
// Gets output data region.
241285
pub fn get_output_data_region(&self) -> (u64, u64) {
242-
(self.output_data_ptr, self.output_data_size)
286+
unsafe {
287+
match RUNNING_MODE {
288+
RunMode::Hypervisor => self.get_output_data_guest_region(),
289+
RunMode::InProcessWindows | RunMode::InProcessLinux => {
290+
self.get_output_data_host_region()
291+
}
292+
_ => panic!("Invalid running mode"),
293+
}
294+
}
295+
}
296+
297+
// Gets the guest heap data address.
298+
pub fn get_heap_data_address(&self) -> u64 {
299+
unsafe {
300+
match RUNNING_MODE {
301+
RunMode::Hypervisor => self.guest_heap_data_offset + self.guest_memory_base_address,
302+
RunMode::InProcessWindows | RunMode::InProcessLinux => {
303+
self.guest_heap_data_offset + self.guest_memory_host_base_address
304+
}
305+
_ => panic!("Invalid running mode"),
306+
}
307+
}
308+
}
309+
310+
// Gets the guest stack data address.
311+
pub fn get_stack_data_address(&self) -> u64 {
312+
unsafe {
313+
match RUNNING_MODE {
314+
RunMode::Hypervisor => {
315+
self.guest_stack_data_offset + self.guest_memory_base_address
316+
}
317+
RunMode::InProcessWindows | RunMode::InProcessLinux => {
318+
self.guest_stack_data_offset + self.guest_memory_host_base_address
319+
}
320+
_ => panic!("Invalid running mode"),
321+
}
322+
}
323+
}
324+
325+
// Gets the guest error data address.
326+
pub fn get_guest_error_data_address(&self) -> u64 {
327+
unsafe {
328+
match RUNNING_MODE {
329+
RunMode::Hypervisor => {
330+
self.guest_error_data_offset + self.guest_memory_base_address
331+
}
332+
RunMode::InProcessWindows | RunMode::InProcessLinux => {
333+
self.guest_error_data_offset + self.guest_memory_host_base_address
334+
}
335+
_ => panic!("Invalid running mode"),
336+
}
337+
}
338+
}
339+
340+
// Gets the guest panic context address.
341+
pub fn get_guest_panic_context_address(&self) -> u64 {
342+
unsafe {
343+
match RUNNING_MODE {
344+
RunMode::Hypervisor => {
345+
self.guest_panic_context_offset + self.guest_memory_base_address
346+
}
347+
RunMode::InProcessWindows | RunMode::InProcessLinux => {
348+
self.guest_panic_context_offset + self.guest_memory_host_base_address
349+
}
350+
_ => panic!("Invalid running mode"),
351+
}
352+
}
353+
}
354+
355+
// Get host error guest offset.
356+
pub fn get_host_error_guest_offset(&self) -> u64 {
357+
self.host_error_data_offset + self.guest_memory_base_address
358+
}
359+
360+
// Get guest error guest offset.
361+
pub fn get_guest_error_guest_offset(&self) -> u64 {
362+
self.guest_error_data_offset + self.guest_memory_base_address
363+
}
364+
365+
// Get guest panic context offset.
366+
pub fn get_guest_panic_context_offset(&self) -> u64 {
367+
self.guest_panic_context_offset + self.guest_memory_base_address
368+
}
369+
370+
// Sets the outb pointer, which is used for in-process execution.
371+
pub fn set_outb_ptr(&mut self, ptr: u64) {
372+
self.outb_ptr = ptr;
373+
}
374+
375+
// Sets the outb pointer context, which is used for in-process execution.
376+
pub fn set_outb_ptr_ctx(&mut self, ptr: u64) {
377+
self.outb_ptr_ctx = ptr;
243378
}
244379
}

Diff for: src/hyperlight_guest/src/chkstk.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ limitations under the License.
1717
use core::arch::global_asm;
1818
use core::mem::size_of;
1919

20-
use hyperlight_common::hyperlight_peb::RunMode;
20+
use hyperlight_common::peb::RunMode;
2121
use hyperlight_common::RUNNING_MODE;
2222

2323
use crate::guest_error::{set_invalid_runmode_error, set_stack_allocate_error};

0 commit comments

Comments
 (0)